Mysql主从半同步复制
这里也是一系列的配置,结合原理才能了解主从半同步复制到底做了一件什么事。
1、mysql复制原理图
2、主从半同步复制有2种
- after_sync
- after_commit
after_commit 是mysql老版本的半同步方式,但是这种方式有缺陷,这种方式是在提交到引擎后才会执行,也就是说已经写入了日志后才半同步,如果遇到主从复制失败的情况即从服务器失败,严格上来说主应该回滚,但是此时主已经写入日志了,最终结果会导致master写入成功而slave同步失败的情况,即主从数据不一致了。所以这种方式已经被淘汰。
after_sync也叫增强版半同步,它是在主master写入日志之前进行半同步复制,所以一旦发生从slave同步失败的情况,主master也不会继续执行,从而保证了主从数据一致。
二者的区别就是等待的点point不同。
3、mysql 实现半同步
若mysql要实现半同步复制,必须要安装插件。
1)主库
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
2) 从库
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看是否安装成功
mysql> show plugins;
注意:一个server可以既是主库也可以是从库,所以,以上插件可以在一个库上执行。
安装完之后,先查看下这个半同步的状态信息
mysql> show global status like "%sync%";
参数介绍
(1)Rpl_semi_sync_master_clients 支持和注册半同步复制的已连Slave数
(2)Rpl_semi_sync_master_no_times master关闭半同步复制的次数
(3)Rpl_semi_sync_master_no_tx master没有收到slave的回复而提交的次数,可以理解为master等待超时的次数,即半同步模式不成功提交数量
(4)Rpl_semi_sync_master_status ON是活动状态(半同步),OFF是非活动状态(异步),用于表示主服务器使用的是异步复制模式,还是半同步复制模式
(5)Rpl_semi_sync_master_tx_avg_wait_time master花在每个事务上的平均等待时间
(6)Rpl_semi_sync_master_tx_waits master等待成功的次数,即master没有等待超时的次数,也就是成功提交的次数
(7)Rpl_semi_sync_master_yes_tx master成功接收到slave的回复的次数,即半同步模式成功提交数量。
从图中可以看到这2个半同步插件的状态都是OFF的,那么下面开始开启半同步:
从库:set global rpl_semi_sync_slave_enabled = 1; # 1启用,0禁止
主库:set global rpl_semi_sync_master_enabled = 1; # 1启用,0禁止
还可以设置主库等待从库复制反馈的时间
set global rpl_semi_sync_master_timeout = 10000; 单位ms
再次查看下半同步插件的状态:show global status like "%sync%";
注意:主库 的Rpl_semi_sync_slave_status 可以是关闭的,根据这个库起到的作用而定。从库的这2个状态可以都是OFF的。因为从库是被动接受方(可以实验一下)。
另一个查看的指令
mysql> show global variables like '%sync%';
结果参数介绍
(1)rpl_semi_sync_master_wait_for_slave_count: 指主等待几个slave返回同步复制的ack信号后进行提交.
(2)rpl_semi_sync_master_enabled (主库)是否启动半同步
(3)rpl_semi_sync_master_timeout 等待多时毫秒后变成异步复制,默认是10000ms
(4)rpl_semi_sync_master_wait_point 5.7默认AFTER_SYNC(增强版半同步复制,无损复制模式),
在得到slave的应答后再commit,可选值AFTER_COMMIT,在master提交后同步数据给slave,然后master等待slave应答,应答成功返回客户端。
这个参数可以手动设置:
mysql> set global rpl_semi_sync_master_wait_for_slave_count = 2;
4、验证以上2种方式的半同步过程
实际操作,先略。
风险
1、风险:endbled写入配置文件的话,会使实例启动后立即进入半同步模式,如果发生长时间断连的实例重新运行启动,有可能导致主库被拖垮。
2、建议:长时间断开的从库,重新连接后,要等待追完全部事务后,手动开启半同步模式,而不是启动后直接切换,防止冲击主库。
3、配置文件中关于半同步的配置(要跟从实际去取舍)
master的my.cnf配置
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 单位是ms
slave的my.cnf配置
[mysqld]
rpl_semi_sync_slave_enabled=1
从库重启io_thread
stop slave io_thread;
start slave io_thread;
缺点
1、after_commit缺点
缺点1: 幻读
当用户发起一个事务,该事务已经写入redo日志和binlog日志,但该事务还没写入从库,此时处在waiting slave dump处,此时另一个用户可以读取到这条数据,而他自己却不能;
缺点2:数据丢失
一个事务在waiting slave dump处crash后,主库将比从库多一条数据。
(mysql官网配置信息详解 https://dev.mysql.com/doc/refman/5.6/en/replication-options-reference.html)
两种模式的对比
- AFTER SYNC
after sync 是mysql5.7官方新加的用以解决5.6半同步缺陷的选项,也是官方推荐的方式。
实际上,客户端发出commit请求后,在主库上写入binlog并推送给slave, slave接收到binlog并写入relaylog,发送ACK确认已经接收binlog后,master在
引擎层commit, 客户端接收commit完成,此时其他绘画才可以看见已提交的数据。
故障分析:
假设master在接收ACK确认时宕机,因此在引擎层并没有提交,HA切换到从库,因为binlog已经写入从库的relaylog,因此不会造成数据丢失,个人认为是目前比较完美的
解决方式。
- AFTER COMMIT
after commit 是MYSQL5.6半同步参数,区别于after sync,after sync是在接收ack确认以后主库在引擎层做提交,而after commit是现在引擎层做提交后等待ack确认。因此,在写入数据
后并且从库确认之前,其他的客户端可以看到这一事务。
故障分析:
1. binlog 未发送到从库
事务B获取到事务A提交的内容,此时宕机故障切换到slave, 事务B获取到的内容却丢失来。事务A commt没有收到反馈信息(则需要业务判断了)。
2. binlog 已经发送给从库
事务B获取到事务A提交的内容,故障切换到slave,B仍然获取到A提交的内容,没毛病。事务A commit没有收到反馈信息,若重新执行该事务,则相当于执行两次A事务(则需要业务判断了)。
小结
主从半同步复制不是很重要的点,但是如果遇到了,要知道去哪里查阅资料解决。还是那句话,理解原理很重要。