InnoDB事务的二阶段提交

Posted wsw_seu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 找对应的事务。

以上是关于InnoDB事务的二阶段提交的主要内容,如果未能解决你的问题,请参考以下文章

Mysql事务—内部XA的两阶段提交(2pc)

Mysql事务—内部XA的两阶段提交(2pc)

MySQL两阶段提交

分布式事务业界主流方案

InnoDB事务锁-update search阶段加锁

mysql行锁+可重复读+读提交