• InnoDB事务的二阶段提交


     

    问题:

    1. 什么是二阶段提交
    2. 为什么需要二阶段提交
    3. 二阶段提交流程

    什么是二阶段提交?

    ### 假设原来id 为10 的记录age 为5
    begin;
    update student set age = 10 where id = 10;
    commit;
    复制代码

    一般情况下,事务提交涉及redo log 和 binlog。
    当commit 命令执行时,

    • 先进入commit prepare 阶段,这个阶段事务中新生成的redo log 会被刷到磁盘,并将回滚段置为prepared状态。
    • commit阶段:innodb释放锁,释放回滚段,设置redo log提交状态,binlog持久化到磁盘,然后存储引擎层提交。

    为什么需要二阶段提交?

    由于存在redo log 和 binlog ,而他们两是相互独立的。而事务提交必须确保两者同时有效。不然会出现不一致的情形。
    假如: redo log 有效,binlog 无对应记录
    在上述例子中如果服务器从事务中回复,由于redo log 有效所以id为10的记录age仍然会是10,但是由于binlog日志没有记录,所以如果通过binlog 做主从,或者主备那么就会导致主从,主备不一致。
    假如: redo log 失效,而binlog 有对应记录,
    上述例子中,服务器中对应的id为10的日志age就会是修改前的5,而binlog中的日志会被传到其他从服务器,也会导致主从,主备不一致。

    二阶段提交流程

    时间点1
    prepare 阶段
    时间点2
    commit 阶段
    时间点3
    时间点1出现问题

    这个时候redo log 和 binlog都在内存中,所以本次事务的相关操作都会消失,相对于事务回滚了,不影响数据的一致性。

    时间点2出现问题

    这个时候redo log已经到磁盘了。binlog没有刷到磁盘所以会消失。服务器从故障中恢复时,读取磁盘中的redo log ,但是由于对应的redo log项还是prepare状态,就要判断binlog 是否完整,如果binlog完整则提交事务,如果binlog不完整则回滚事务。

    时间点3出现问题。

    这个时候redo log 和 binlog都已经存磁盘,服务器从redo log恢复就好了。

    binlog怎么判断完整性:

    • statement 格式的 binlog,最后会有 COMMIT;
    • row 格式的 binlog,最后会有一个 XID event

    redolog 和binlog怎么联系起来:

    它们有一个共同的数据字段,叫 XID。
    崩溃恢复的时候,会按顺序扫描 redo log:如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。

  • 相关阅读:
    Java实现 LeetCode 365 水壶问题
    Java实现 LeetCode 363 矩形区域不超过 K 的最大数值和
    Java实现 LeetCode 363 矩形区域不超过 K 的最大数值和
    Java实现 LeetCode 363 矩形区域不超过 K 的最大数值和
    Java实现 LeetCode 357 计算各个位数不同的数字个数
    Java实现 LeetCode 357 计算各个位数不同的数字个数
    Java实现 LeetCode 357 计算各个位数不同的数字个数
    Java实现 LeetCode 355 设计推特
    利用linux信号机制调试段错误(Segment fault)
    LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/13215980.html
Copyright © 2020-2023  润新知