InnoDB: Topic: 2PC for Redo Log and Binlog

 31st August 2020 at 10:27pm

这篇文档描述 MySQL 在处理一条修改数据的请求时,写入 redo log 及 binlog 的时序,以及如何达成 crash-safe。

分布式领域有 two-phase commit(2PC,二阶段提交),是一种为了保持多节点一致性的算法。MySQL 在它的内部实现中也大量借鉴了这种想法。以 InnoDB 为例,在 MySQL 收到一条 COMMIT 请求后,会有下列的过程发生:

  1. MySQL 要求存储引擎准备好(prepare)

    InnoDB 调用 innobase_xa_prepare,此时会将该事务写入 redo log 并保证它刷入了磁盘。此时这批 redo 会被标记为 prepared。

    如果此时 MySQL crash 了,即写 redo log 的过程中断了,此时 MySQL 重启后并不会继续提交,而是回到未提交前的状态。

  2. 存储引擎准备好后,MySQL 写 binlog

    写 binlog 过程如果 crash 了,则 MySQL 重启时再从 redo log 中拿出相应的纪录再重新应用,重启写 binlog 即可。

  3. 写完 binlog 后,MySQL 要求存储引擎也提交相应的改动

    如果写完 binlog 后就 crash 了,MySQL 仍然能从 binlog 中知道存储引擎应该提交哪些纪录。

    InnoDB 在此时会将相应的数据落盘,并将相应的 redo log 标记为 committed。

References