zoukankan      html  css  js  c++  java
  • 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 找对应的事务。

  • 相关阅读:
    基于Python的人脸动漫转换
    let 与 var的区别
    【LeetCode】汇总
    【HDU】4632 Palindrome subsequence(回文子串的个数)
    【算法】均匀的生成圆内的随机点
    【LeetCode】725. Split Linked List in Parts
    【LeetCode】445. Add Two Numbers II
    【LeetCode】437. Path Sum III
    【LeetCode】222. Count Complete Tree Nodes
    【LeetCode】124. Binary Tree Maximum Path Sum
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/13215980.html
Copyright © 2011-2022 走看看