MySQL Semisync

默认情况下,MySQL的复制功能是异步的。master把binlog发送给slave时,这个复制动作就已经完成,master不会验证slave是否接收完毕(类似于Oracle DataGuard Maximum Performance)。异步复制同时意味着在把数据从一个mysqld实例拷贝到另一个mysqld时有一个延时,即master当前提交的事务不会在同一时刻拷贝到slave。这也带来了一定的风险,当master或slave发生故障时,slave有可能会没有接收到master发送过来的binlog,这样就会造成了master/slave的数据不一直,甚至在恢复时也会造成数据的损失。
为了解决这个问题,MySQL 在5.5以后引入了一种半同步模式,slave在接收binlog并写入relay log后会给服务器发送一个反馈,告诉master接收完成,当出现超时情况时,master会暂时切换到异步复制模式,和Oracle DataGuard Maximum Available的处理方式比较相似。半同步复制模式必须在master和slave端同时启用,否则master会使用默认的异步模式。

1. 开启半同步

我的环境是RHEL 6.5 x86_64, Percona-Server-server-56(RPM),已经配置了异步的同步模式。
检查动态加载选项和插件列表。

默认并没有加载半同步插件,rpm发行版的插件.so文件的位置
/usr/lib64/mysql/plugin/semisync_master.so
/usr/lib64/mysql/plugin/semisync_slave.so
然后在M/S上都加载插件并启用同步。初次加载插件后,MySQL会将该插件记录到系统表mysql.plugin中,下次mysqld启动时会自动加载,无需INSTALL PLUGIN

要将rpl_semi_sync_master_enabled和rpl_semi_sync_slave_enabled参数写入配置文件my.cnf

日志文件会显示:

2. 半同步的参数说明

在master上有4个相关参数,slave中有2个.

3. 半同步与异步的切换

执行完上面的步骤后,我们在M/S上检查半同步的状态,发现rpl_semi_sync_slave_status都是关闭的。这说明虽然启用了半同步的功能,但slave不会自动从异步模式转换到半同步模式。

通过上面的参数也说明了开启半同步会导致一部分额外的开销:
(1). 完成单条事务增加了额外的等待延迟,延迟的大小取决于网络的好坏。
(2). Semi-sync不是分布式事务,主库会在自己完成事务后,等待备库接收事务日志。
接下来重新启动slave。

再次检查slave的状态:

一般情况下,当slave的io线程将binlog接受完毕后,要给master发送一个确认。如果超过rpl_semi_sync_master_timeout=10000(10秒)内未收到该确认信号,那么就自动转换为异步复制模式。这种情况下要排查错误并重启slave来恢复半同步模式。

参考:

http://dev.mysql.com/doc/refman/5.5/en/replication-semisync.html

http://www.orczhou.com/index.php/2011/06/mysql-5-5-semi-sync-replication-setup-config/

Posted in Database, MySQL.