MySQL半同步中几个参数设置的原理
最近遇到一个mysql主备跨机房半同步设置导致主库插入性能慢的问题,由于一主一备跨机房设置了半同步复制,sql插入的执行时间在40ms,业务对数据落库性能又比较敏感,所以就导致了应用系统的性能问题。最后改成主备异步复制,关闭了rpl_semi_sync_slave_enabled参数,sql插入的执行时间降到了2ms,应用系统也就没有出现性能问题。因此如果是一主一备跨机房的架构在对性能有要求的情况下,建议不要开启半同步复制,避免跨机房网络延时带来的性能问题。这次问题的处理也引发了我对MySQL半同步复制的几个问题的思考,加深了对半同步复制原理的理解。
1.rpl_semi_sync_master_wait_point参数原理
这个参数默认值在5.7.2版本由原来的after_commit改为了after_sync,官方文档上描述的其实不太好理解。对于after_commit,当前客户端只有在服务器向存储引擎提交数据并收到SLAVE返回的确认后,才会收到事务的返回结果。但是在事务提交之后收到SLAVE返回确认信息之前,此刻其他客户端可以看到当前客户端提交的事务信息,因此如果因为网络或备库故障或者主从切换造成事务回滚,那就会出现幻读现象。 对于after_sync,当事务被SLAVE确认后MASTER在存储引擎层面进行提交事务后,所有客户端才能看到事务造成的数据更改。因此,所有客户端在MASTER上同一时刻看到是相同的数据。因此,after_sync的出现其实就是为了解决after_commit的幻读问题,确保主从切换后所有客户端看到的数据是一致的。这个其实就是我们所说的增强半同步,也叫无损半同步。
2.备库relaylog的刷盘机制
在其他数据库的主备复制中,关于备库什么时候返回ack给主库,一般会有几个级别,比如备库收到主库日志就返回ack、备库日志刷盘再返回ack、备库事务提交再返回ack。而在MySQL中,其实只有一种机制,那就是备库把relaylog写入到内存中就返回ack,不会等relaylog刷盘。而relaylog的刷盘机制由sync_relay_log参数控制,默认为10000,表示每10000个事务刷一次盘。当sync_relay_log设置为0时,则relaylog的刷盘机制不再由sync_relay_log参数控制,而仅依赖于操作系统的刷盘机制。