一、MySQL主从复制
复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做) , 从而使得从库和主库的数据保持同步。 MySQL支持一台主库同时向多台从库进行复制 ,从库同时也可以作为其他从服务器的主库,实现链状复制。
1、MySQL主从复制的概念
MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表。
MySQL主从复制可以用来实现读写分离、数据库实时备份、高可用HA以及架构扩展等场景。
2、MySQL主从复制的几种形式
- 一主一从

- 一主多从

一主一从和一主多从是最常见的主从架构,实施起来简单并且有效,不仅可以实现HA,而且还能读写分离,进而提升集群的并发能力。
- 多主一从

多主一从可以将多个mysql数据库备份到一台存储性能比较好的服务器上。
- 双主复制

双主复制,也就是互做主从复制,每个master既是master,又是另外一台服务器的slave。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
- 级联复制

级联复制模式下,部分slave的数据同步不连接主节点,而是连接从节点。因为如果主节点有太多的从节点,就会损耗一部分性能用于replication,那么我们可以让3~5个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。
3、MySQL中主从复制原理

MySQL的主从复制主要分为三步:
- master会在事务提交后将数据变化记录到二进制日志文件binlog中。这些记录过程叫做二进制日志事件,binary log events,这一过程主要由主节点的
log dump
线程执行 - 当savle结点上执行
start savle
执行之后,slave会创建一个I/O线程连接主节点,请求主库中的二进制日志文件,并拷贝数据到本地的中继日志文件(Relay log)中。 - salve结点的SQL线程读取中继日志中记录的事件,并把改变记录到自己的数据库中。MySQL的复制显然是异步并且是串行化的。

二、配置MySQL主从复制
接下来,我们基于docker搭建一下MySQL的主从复制。由于docker已经是现在运维比较常用的容器化技术了,并且docker的操作也不难,所以我们就用docker来搭建一下MySQL主从复制。
1、启动mysql容器
执行如下命令,并将容器内的配置文件和数据文件挂载到宿主机上
docker run --name mysql-3307 -p 3307:3306 -v /docker/mysql/data:/var/lib/mysql -v /docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
如果在启动容器的时候出现mysqld: Can't read dir of '/etc/mysql/conf.d/' (Errcode: 13 - Permission denied)
错误,那是因为Centos7安全Selinux禁止了一些安全权限,导致mysql和mariadb在进行挂载/var/lib/mysql的时候会提示如下信息
此时我们在命令中加上--privileged=true
给容器特定的权限
docker run --privileged=true --name mysql-3307 -p 3307:3306 -v /docker/mysql/data:/var/lib/mysql -v /docker/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
启动之后我们看看容器是否运行了

我们把mysql-3307
作为主节点,把mysql-3308
作为从结点,接下来首先配置Mater结点:
在宿主机上挂载的目录/docker/mysql/conf下,执行vim my.cnf
新建并添加如下配置:
[mysqld]
## 同一局域网内注意要唯一
server-id=100
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
配置完成之后,需要重启mysql服务使配置生效。重启之后下一步在Master数据库创建数据同步用户,授予用户 slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
进入master数据库命令行模式,执行如下命令:
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
2、配置savle结点容器
执行命令vim /docker/mysql/conf2/my.cnf
新建并配置如下信息:
[mysqld]
## 设置server_id,注意要唯一
server-id=101
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
配置完成后也需要重启mysql服务和docker容器,操作和配置Master(主)一致。
3、连接主节点和从结点
配置完成会后,我们首先在主节点服务器的mysql命令行模式下执行show master status
查看主节点的状态
File和Position字段的值后面将会用到,在后面的操作完成之前,需要保证Master库不能做任何操作,否则将会引起状态变化,File和Position字段的值变化。
首先我们查看一下主节点的IP:
docker inspect --format='{{.NetworkSettings.IPAddress}}' mysql-3307
之后在Slave 的 mysql命令行模式下,执行如下命令
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 617, master_connect_retry=30;
命令参数说明:
- master_host:主节点IP,咋docker中可以使用上面给的命令直接查看
- master_user:用于数据同步的用户
- master_password:用于同步的用户的密码
- master_port:Master的端口号,指的是容器的端口号,并不是容器在主机上映射的端口号
- master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
- master_log_pos:从日志文件的哪里开始读,即上文中提到的 Position 字段的值
- master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
之后我们还是在slave的mysql命令行模式下执行start slave;
启动主从复制过程,然后再次查询主从同步状态show slave status \G;
。
#启动主从复制
start salve;
#查看从结点状态
show slave status\G;
判断主从复制有没有启动成功的关键即使看SlaveIORunning 和 SlaveSQLRunning 都是Yes,那就说明主从复制已经开启。此时可以测试数据同步是否成功。
4、测试主从复制
测试主从复制的方法就比较多了,最简单的方法就是在主库创建一个表,一顿操作之后看从库是否有和主库一样的数据即可。这里不在重复了,比较简单,即使简单的SQL操作。最后贴上最终测试的结果:
主库
从库
总结
MySQL主从复制无论是原理还是实际操作还是比较好配置的,主要就是依靠主节点的二进制日志(在MySQL中日志比数据更重要,有了日志就有了一切!!!,实际上MySQL除了本文用到的二进制日志,还提供了很多的日志,有兴趣的小伙伴可以点击我的另一篇博客了解一下MySQL日志分类及简介)将主库的所有操作记录下来,然后从库读取主库的二进制日志文件,并在自己本地重做文件中的操作就完成了复制。