Bootstrap

谈一下MySQL的两阶段提交机制

为什么需要两阶段提交?

为了保证事务的持久性和一致性,MySQL需要确保redo log和binlog的同步持久化。MySQL通过“两阶段提交”的机制来实现在事务提交时,这两个日志必须保持一致,以避免出现数据不一致的问题。

为什么会出现日志不一样的这种情况?

因为事务提交后,redo log 和 binlog 都要持久化到磁盘,但是这两个是独立的逻辑,可能出现半成功的状态。
即,有可能redo持久化了,但是binlog没持久化;或者是redo没有持久化成功,而binlog持久化成功了。这样就会导致它们两个日志的不一致性。
而我们通过“两阶段提交”的机制来保证日志一致的问题。

两阶段提交流程?

  1. 准备阶段(Prepare)
        在事务执行过程中,所有的数据更改都会先记录到InnoDB存储引擎的redo log中,此时事务处于prepare阶段。此阶段确保了即使发生崩溃,更改也能通过redo log进行恢复。
        在准备阶段结束时,InnoDB会生成一个唯一的事务ID(XID)。InnoDB会将一个包含此XID和事务状态的特殊标记记录写入redo log,并将redo log标记为prepare状态。
  2. 写入binlog
        事务的所有更改都会记录到binlog中,然后记录一个包含XID的COMMIT事件。
  3. 写binlog到磁盘
        MySQL会将binlog的内容从内存缓冲区通过write操作写入文件缓冲区,随后根据配置(例如,sync_binlog=1)可能会立即刷盘到磁盘,以确保binlog的持久性。
  4. 提交阶段(Commit)
        在binlog成功写入磁盘后,事务会进入提交阶段。此时,InnoDB会使用前面生成的XID标记为已提交(Committed),并将这个提交操作记录到redo log中。
        最后,InnoDB会根据需要将redo log的更改刷盘到磁盘上,完成事务的持久化。此时,事务正式提交完成。
    在这里插入

图片来源:小林coding

两阶段提交缺点?

  磁盘 I/O 次数高:对于“双1”配置,每个事务提交都会进行两次 fsync(刷盘),一次是 redo log 刷盘,另一次是 binlog 刷盘。

  锁竞争激烈:两阶段提交虽然能够保证「单事务」两个日志的内容一致,但在「多事务」的情况下,却不能保证两者的提交顺序一致,因此,在两阶段提交的流程基础上,还需要加一个锁来保证提交的原子性,从而保证多事务的情况下,两个日志的提交顺序一致。

最后

如果小伙伴们觉得我写的文章不错的话,那么请给我点点关注,我们下次见!
      在这里插入图片描述

;