MySQL半同步复制

  • Post author:
  • Post category:mysql


对于传统的异步复制来说,主库上产生的binlog events交给dump thread之后,就会去处理下一个事务,对于master产生的binlog events是否发送给slave并无法保证。因此,对于传统的复制来说是无法保证主从数据的一致性。MySQL为了解决这个问题,5.6引入了半同步复制,5.7引入了增强半同步复制。

半同步复制原理

相较于异步复制,半同步引入了一个ACK响应。slave在接收到master上产生的binlog events并将其写入到relay log之后,会给master发一个ACK响应表示已经接受到了相应的binlog,master收到slave发送回来的ACK后会给客户端一个响应,然后master才会继续处理接下来的任务。既然半同步复制比异步复制多了一个ACK响应机制,那么master在什么阶段等待slave的ACK响应就是半同步和增强半同步的区别了:

  • rpl_semi_sync_master_wait_point=AFTER_COMMIT   MySQL5.6的半同步复制如下图所示:

  • rpl_semi_sync_master_wait_point=AFTER_SYNC   MySQL5.7的增强半同步复制如下图所示:

从上面两图可以看出来,after_commit是master在存储引擎提交之后,等待slave的ACK响应。而after_sync是master在写完binlog之后,等待slave的ACK响应。那么,after_commit就会存在很明显的问题,当master上存储引擎已经commit,处于等待ACK响应的时候master宕机了,如果slave没有收到相应的binlog events,master在重启之后会将该事务commit,而slave上就会缺少该事务,造成主从不一致。如下图所示:

当用户1插入一条记录3,当它在等待ACK响应的同时(其实该事务已经commit,此时其他连接的用户可以读到最新的数据),此时另一个用户2在masster上读取最新的数据时,是可以读到用户1插入的记录3。但是此时由于master宕机了,用户1插入3这条记录对应的binlog events并没有发送到slave端,用户2此时在slave上读到的最新数据就读不到用户1插入的记录3,那么主从读到的最新数据就会不一致。

为了解决after_commit造成的master上提交的事务slave上没有收到相应的binlog events而造成主从不一致的情况,MySQL5.7引入了after_sync,master在写完binlog之后,存储引擎提交之前,去等待slave上的ACK响应,那么这样就可以保证master上提交的事务,slave上一定可以收到。


半同步复制的配置

半同步复制是MySQL内部自带的一个插件来管理,所以要想使用半同步复制,主从两端都必须安装此插件,下面是安装方式:   install PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;

MASTER端:

rpl_semi_sync_master_wait_point=AFTER_SYNC

rpl_semi_sync_master_timeout=10000(默认10s)

rpl_semi_sync_master_wait_for_slave_count=N

rpl_semi_sync_master_wait_no_slave=OFF

SLAVE端:

rpl_semi_sync_slave_enabled=ON

stop sql_thread;start sql_thread;


半同步复制注意事项

1,由于半同步复制需要主从之间的ACK响应,所以最好选择主机之间的距离较近并且网络状况良好的情况配置。

2,,当master等待从库的ACK响应时间超过设置的rpl_semi_sync_master_timeout后,会自动关闭半同步复制,降为异步复制

3,当收到ACK的响应个数小于rpl_semi_sync_master_wait_for_slave_count时,也会自动关闭半同步复制,降为异步复制



版权声明:本文为qq_42583030原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。