MySQL两阶段提交实现redo log,binlog日志一致

发布时间 2023-12-07 09:16:07作者: rockdow

MySQL的执行器使用两阶段提交主要解决 binlog 和 redo log 的数据一致性的问题。

假设只使用一阶段提交的话,整个commit流程图如下:
image
首先,redo log 和 binlog 写入系统缓存,接着 redo log 先刷盘,然后在 binlog 即将刷盘时系统发生故障,导致 binlog 刷盘失败。假设执行的事务是update name=“张三” where id = 1(id为1的记录name字段原先的值为“王五”),那么在系统恢复时,主机根据 redo log 日志中内容,会重新执行该条语句,将id=1记录的name字段更新为张三,而从机同步过来的 binlog 中,却没有记录该条语句,id=1记录的name字段仍为王五,这就会导致主机和从机的数据不一致。

但是采用两阶段提交的话,整个commit流程图如下:
image
与上面相比,将 redo log 的写入拆成了两个步骤 preparecommit,这就是两阶段提交。假设在步骤4 binlog 刷盘发生故障,那么主机根据redo log 日志恢复数据时,发现 redo log 还处于 prepare 阶段,并且没有对应 binlog 日志,就不会重新执行update语句。假设步骤5或步骤6发生故障导致 redo log 的 commit 状态未能成功写入,也不会造成问题,虽然 redo log 是处于 prepare 阶段,但是能通过事务id找到对应的 binlog 日志,所以MySQL认为是完整的,就会提交事务恢复数据。