Mysql主从集群——二阶段提交机制

之前的文章写了Mysql中的几种日志和作用,MySQL中经常说的WAL技术,WAL的全称是Write- Ahead Logging,它的关键点就是先写日志,再写磁盘。即当有一条记录需要更新时,InnoDB引擎就会先把记录写到redo log里,并更新内存,这个时候更新就完成了。因为如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程IO成本、查找成本都很高。

例如在执行一条update语句时候,处理流程为:首先把数据写入内存,写入redo log,状态为prepare——>写binlog——>redo log状态修改为commit

从流程可以看到所说的 二阶段提交,redo日志写入时首先是prepare状态,在写入binlog后再被commit。把redo和binlog分别看成是两个分支事务,从分布式事物的角度或许更好理解,所以MySQL的两阶段提交主要是为了解决 binlog 和 InnoDB redolog 的数据一致性的问题。binlog默认是不开启的,只有使用主从分离集群是才需要我们使用binlog实现主从库的数据同步,所以我的理解是非主从集群模式下的mysql是用不到mysql二阶段提交的。

第一阶段:InnoDB写入redolog,将回滚段(undo)设置为Prepared状态,binlog不做任何操作。

第二阶段:将事务写入Binlog中,成功写入后在把redolog commit完成最终事务的提交。

需要注意的是: 在二阶段提交中,MySQL以binlog是否成功写入作为事务是否成功的标记,redolog commit标记并不是这个事务成功与否的标记。即 在mysql服务宕机恢复时,mysql会扫描最后一个Binlog文件,提取其中所有的xid。InnoDB维持了状态为Prepare的事务链表,将这些事务的xid与刚刚提取的xid做比较,若存在,则提交prepare的事务,若不存在,回滚。

基于二阶段提交机制,在发生到宕机恢复时mysql可以准确地恢复数据并保持binlog 和 InnoDB redolog 的数据一致。在做Crash recovery时分为以下3种情况:

  1. binlog有记录,redolog状态commit:正常完成的事务,不需要恢复;
  2. binlog有记录,redolog状态prepare:在binlog写完提交事务之前的crash,恢复操作:提交事务。(因为之前没有提交)
  3. binlog无记录,redolog状态prepare:在binlog写完之前的crash,恢复操作:回滚事务(因为crash时并没有成功写入数据库)

猜你喜欢

转载自blog.csdn.net/qq_29569183/article/details/112472715
今日推荐