Mysql半同步复制与增强半同步复制

Mysql的三种复制策略:

1、异步复制(默认)
2、半同步复制
3、增强半同步复制

名词解释

异步复制:
主库写入binlog就直接返回客户端更新成功。

半同步复制(after_commit):
Mysql5.5开始推出半同步复制,相比异步复制,半同步复制提高了数据完整性,在master的dump线程通知slave后,增加了一个ack(消息确认)这一个步骤。即binlog先在引擎层提交,然后再等待slave反馈收到relay log,只有收到ack后master才将commit ok结果反馈给客户端。

会出现的问题:幻读
当引擎层已经commit的时候他还需要等待slave的ACK确认,才在客户端返回commit ok,但是在写入数据后并且从库确认之前,主库的其他客户端是可以看到这一条记录的,这就造成了幻读。

增强半同步复制(after_sync):
master将每个事务写入binlog,传递给slave刷新到磁盘(relay log)。master等待slave反馈接收到relay log的ack之后,再在引擎层提交事务并返回commit ok结果返回给客户端。即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中,即确保已经在relay log中了。

半同步复制通俗的讲就是主库确认从库接受到binlog后再返回事务提交的信息,早期的半同步复制实现的方式是在engine commit(对应二阶段提交中给redo打commit标记)后去等待从库的确认信息,在innodb引擎中,engine commit后事务做的修改其他会话就能读到了,这时如果其他会话读到了这个修改的事务,但是从库没有收到事务对应的binlog,主库突然crash掉发生了主备切换,再去做读操作的时候就会发现刚刚读到的这条数据读不到了,产生了幻读。因此后面修改了半同步复制的实现方式,主库在binlog写入之后,engine commit之前去进行从库接受日志的确认,若未收到确认信息,存储引擎层就不会将事务提交,这样就避免了早期半同步复制幻读的问题,这种半同步复制的实现方式就是增强半同步。

下面笔者团队领导给我们出的一个问题,大家可以看一下:

1.现有一套MySQL增强半同步的架构,A为主库,B为从库。某天,A库因为掉电挂掉了,B库接管了服务成为了新的主库,之后运维人员重新启动了A服务器,想将A库作为B库的从库加入集群,却发现A库存在一些比B库多出的事务,为什么?

答:
需要结合二阶段提交,增强半同步是在从库接收到之后,返回ACK之后,主库才在引擎层提交,其他事务才能看到,如果在binlog写完的情况下,就是二阶段提交的第4步(可以看下图),此时发生crash,binlog在原主库已经写入完成,但是在引擎层还没有提交,也就不会发送给从库,原主库在recovery过程中,虽然这个事务在engine层没有提交,但是binlog已经记录,所以崩溃恢复流程中会根据redo log,再加上完整的binlog,去把主库的事务提交。

Mysql半同步复制与增强半同步复制_第1张图片

你可能感兴趣的:(mysql,mysql,数据库)