💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、豆包、星火、月之暗面及文生图、文生视频 广告
源码剖析: ~~~ sql/binlog.cc ordered_commit ~~~ 配置分析 当sync\_binlog为0的时候,binlog sync磁盘由操作系统负责。当不为0的时候,其数值为定期sync磁盘的binlog commit group数。当sync\_binlog值大于1的时候,sync binlog操作可能并没有使binlog落盘。如果没有落盘,事务在提交前,Master掉电,然后恢复,那么这个时候该事务被回滚。但是Slave上可能已经收到了该事务的events并且执行,这个时候就会出现Slave事务比Master多的情况,主备同步会失败。所以如果要保持主备一致,需要设置sync\_binlog为1。 根据上面源码,流程如下图所示。Master依次执行flush binlog, update binlog position, sync binlog。如果Master在update binlog position后,sync binlog前掉电,Master再次启动后原事务就会被回滚。但可能出现Slave获取到Events,这也会导致Slave数据比Master多,主备同步失败。 ![MySQL 半同步复制数据一致性分析](http://p9.pstatp.com/large/1dca000142ccc6d8b3a1) 由于上面的原因,sync\_binlog设置为1的时候,MySQL会update binlog end pos after sync。流程如下图所示。这时候,对于每一个事务都需要sync binlog,同时sync binlog和网络发送events会是一个串行的过程,性能下降明显。 ![MySQL 半同步复制数据一致性分析](http://p1.pstatp.com/large/1dc30005e60b316725ac) sync\_relay\_log的配置 源码剖析 ~~~ sql/rpl_slave.cc handle_slave_io ~~~ 配置分析 在Slave的IO线程中get\_sync\_period获得的是sync\_relay\_log的值,与sync\_binlog对sync控制一样。当sync\_relay\_log不是1的时候,semisync返回给Master的position可能没有sync到磁盘。在gtid\_mode下,在保证前面两个配置正确的情况下,sync\_relay\_log不是1的时候,仅发生Master或Slave的一次Crash并不会发生数据丢失或者主备同步失败情况。如果发生Slave没有sync relay log,Master端事务提交,客户端观察到事务提交,然后Slave端Crash。这样Slave端就会丢失掉已经回复Master ACK的事务events。 ![MySQL 半同步复制数据一致性分析](http://p9.pstatp.com/large/1dc70004affee8169108) 但当Slave再次启动,如果没有来得及从Master端同步丢失的事务Events,Master就Crash。这个时候,用户访问Slave就会发现数据丢失。 ![MySQL 半同步复制数据一致性分析](http://p3.pstatp.com/large/1dc70004affff3f357e2) 通过上面这个Case,MySQL semisync如果要保证任意时刻发生一台机器宕机都不丢失数据,需要同时设置sync\_relay\_log为1。对relay log的sync操作是在queue\_event中,对每个event都要sync,所以sync\_relay\_log设置为1的时候,事务响应时间会受到影响,对于涉及数据比较多的事务延迟会增加很多。