mysql版本:5.7
主从形式
一主一从、主主复制、一主多从、多主一丛、联机复制
简单原理
主库将数据增删改的事件记录在binlog中。
从库启动后创建一个I/O线程连接到主库并要求主库发送记录在其binlog中的更新。
主库为每个连接的从库启动一个dump线程,从库I/O线程读取dump线程发送的更新,并将其记录到本地的中继日志relay-log中。
从库启动SQL线程读取relay-log中的事件,在本地重放,从而达到本地与主库节点的数据一致。
复制过程中从库启动的2个线程:
I/O线程:向主库获取binlog,并将binlog写入从库本地的relay-log中。
SQL线程:读取本地relay-log文件中的日志,解析成sql语句逐个执行。
业务场景
1、数据的备份
2、数据库高可用性,读写分离
3、多库存储、提高单机IO性能
安装配置
一主一从配置为例
1、基础准备
系统:centos7
mysql:5.7
两台虚拟机:node1(主),node2(从)
2、安装mysql数据库
3、两台机器分别创建测试数据库
create databse replication_test;
4、主节点配置
#修改配置文件
vi /etc/my.cnf
#在【mysqld】模块中添加如下配置信息
log-bin=master-bin #二进制文件名称
binlog-format=ROW #二进制日志格式,有row、statement、mixed三种格式,row指的是把改变的内容复制过去,而不是把命令在从服务器上执行一遍,statement指的是在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。mixed指的是默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
server-id=1 #要求各个服务器的id必须不一样
binlog-do-db=replication_test #同步的数据库名称
#从节点账号授权
grant replication slave on *.* to 'root'@'%' identified by '123456';
--刷新权限
flush privileges;
5、从节点配置
#修改配置文件
vi /etc/my.cnf
#在mysqld模块中添加如下配置信息
log-bin=master-bin #二进制文件的名称
binlog-format=ROW #二进制文件的格式
server-id=2 #服务器的id
6、重启主节点mysql
#重启mysql服务
systemctl restart mysqld
#登录mysql数据库
mysql -uroot -p
#查看master的状态(重要)
show master status;
【记下关键2个参数】
File:日志文件名
Position:表示当前需处理同步日志开始的坐标
7、重启配置从节点
#重启mysql服务
systemctl restart mysqld
#登录mysql
mysql -uroot -p
#连接主服务器
change master to master_host='主节点ip',master_user='root',master_password='123456',master_port=3306,master_log_file='上一步2个参数中的file',master_log_pos=上一步2个参数中的Position;
#启动slave
start slave
#查看slave的状态
show slave status\G
至此mysql一主一从配置完成。
主节点不会去同步从节点的数据,所以增删改需在主节点操作。
可在主insert从select、或者从insert主select查看对应的测试效果。
问题
主从同步延时分析
1、一次主从复制操作需要3个单线程去执行,dump、IOThread、SQLThread,当主库的更新事件较多时,SQLThread可能出现事件的积压,当主库产生的事件数量远大于SQLThread的处理速度时,延迟发生。
2、大多数业务场景主从复制和读写分离是一并使用的,在从库充当的读库的角色时,如果读的需求过大,必定也会影响同步的效率
3、主库写binlog的操作是顺序写,从库的SQLThread进行事件重放的操作是随机的,在I/O性能上也有一定的差别。
4、网络传输的原因
解决方案
5.6版本之前:
平行扩展mysql服务,分散压力。
在业务与数据库之间增加缓存,减小mysql读压力。
使用更高配置的机器。
优化网络,主从放在同一个机房等等。
文中使用的5.7版本,mysql通过MTS并行复制技术来解决延时的问题
并行复制就是在流程中添加了一个分发的环节,相当于原来的sql_thread变成了一个中间人角色,负责读取日志信息以及分发事务,真正的日志执行的是在worker线程上,由多个线程并行的去执行。
简单配置
5.7实现并行复制
开启worker线程数
set global slave_parallel_workers = 4;
设置属性值
set global slave_parallel_type='logical_check';
mysql5.6开始支持的并行复制,在之后的版本有一些升级或者说优化等等,还是需要进一步去研究一下。