1、引擎层提交了,但BINLOG没写入,备库丢事务

2、引擎层没有PREPARE,但BINLOG写入,主库丢事务

即使我们将参数设置成innodb_flush_log_at_trx_commit =1 和 sync_binlog = 1,也还会面临这样一种情况:主库crash时还有binlog没传递到备库,如果我们直接提升备库为主库,同样会导致主备不一致,老主库必须根据新主库重做,才能恢复到一致的状态。针对这种场景,我们可以通过开启semisync的方式来解决,一种可行的方案描述如下:

  1. 设置双1强持久化配置;

  2. 我们将semisync的超时时间设到极大值,同时使用semisync AFTER_SYNC模式,即用户线程在写入binlog后,引擎层提交前等待备库ACK;

  3. 基于步骤1的配置,我们可以保证在主库crash时,所有老主库比备库多出来的事务都处于prepare状态;

  4. 备库完全apply日志后,记下其执行到的relay log对应的位点,然后将备库提升为新主库;

  5. 将老主库的最后一个binlog进行截断,截断的位点即为步骤3记录的位点;

  6. 启动老主库,那些已经传递到备库的事务都会提交掉,未传递到备库的binlog都会回滚掉。