MySQL:从update语句执行过程分析InnoDB的两阶段提交

先分析update语句执行过程:

例如:update TableAu set num=num+1 where id=1
update过程:

  • 取出id=1这行数据
    这行数据在内存中,直接返回数据行/不在,将数据从磁盘读入内存,返回数据行

  • 对这行数据的num+1,写入新行,更新内存

  • 写redo log,处于prepare

  • 写bin log,提交事务,commit

上述涉及的redo log 与bin log

  • redo log:
    WAL 先写日志,再写磁盘
    redo log是InnodB特有的
    是物理日志,记录在每个数据页做什么操作
    是循环写的,空间固定会用完,所以会覆盖
  • bin log
    Server 层的log
    逻辑日志,记录语句的原始逻辑。statement模式:SQL语句/row模式:记录行更新前、后的内容
    追加写,空间用完切换下一个,不会覆盖

两阶段提交

  • 第一阶段,事务处于prepare,持有prepare_commit_mutex,写入redo log,undo 设置为prepared
  • 第二阶段,事务写入 bin log,将redo log对应的事务打上commit,释放prepare_commit_mutex。这里的commit才是事务真正的commit。
    两阶段提交可以保证两个日志在逻辑上的一致性

崩溃时的恢复:

  • 如果redo log里的事务是完整的prepare+commit,则进行提交
  • 如果redo log里的事务是不完整的,获取redo 的prepare事务列表和最后的一个bin log的Xid列表进行结合
    if binlog事务完整,则进行提交
    if bin log事务不完整,则进行回滚
    binlog 与redo log通过checksum与xid进行完整性判断
    redo log 与 bin log通过事务Xid进行关联
上一篇:Android 学习记录 - MediaPlayer 详解


下一篇:ACM-ICPC 2018 徐州赛区网络预赛 A.Hard to prepare 【规律递推】