MySQL Transaction--两阶段提交事务

分布式事务两阶段提交数据库

在分布式事务中,须要协调全部分布式原子事务参与者,并决定提交或回滚分布式事务,所以采用两阶段提交协议:app

第一阶段为请求阶段或表决阶段,事务协调者通知事务参与者准备提交或取消事务,而后进入表决过程,事务参与者将表决结果告知协调者是否赞成提交事务;分布式

第二阶段是提交阶段,协调者收集到全部参与者的表决结果,当且仅当全部表决者都赞成提交事务,事务协调者才通知全部参与者提交事务,不然通知参与者回滚事务。

分布式事务首选须要确保各个参与者上面的事务都能进行提交,才能在全部参与者上提交,所以须要两个阶段提交。函数

 

MySQL事务两阶段提交spa

在MySQL事务中,因为事务涉及到存储引擎层和MySQL服务层以及binlog的写入,所以MySQL采用两阶段提交协议来处理事务。日志

先在事务涉及到的全部存储引擎上进行prepare成功后,调用方法将相关数据写到binlog,而后再调用存储引擎的commit完成事务提交。code

Binlog在2PC中充当事务协调者的角色,因为Binlog来通知InnoDB引擎来执行Prepare,Commit或者Rollback操做。orm

 

在大部分关系性数据库中,为保证事务ACID特性,经过会要求事务在提交前,先将事务日志写入到磁盘固化即采用WAL预先写日志机制,但在MySQL Innodb事务引擎中,并无遵循WAL预先写日志机制,所以可能存在数据不一致问题。
在MySQL Innodb处理事务的函数lock_trx_release_locks中,有如下注释:blog

/* The following assignment makes the transaction committed in memory and makes its changes to data visible to other transactions. NOTE that there is a small discrepancy from the strict formal visibility rules here: a human user of the database can see modifications made by another transaction T even before the necessary log segment has been flushed to the disk. If the database happens to crash before the flush, the user has seen modifications from T which will never be a committed transaction. However, any transaction T2 which sees the modifications of the committing transaction T, and which also itself makes modifications to the database, will get an lsn larger than the committing transaction T. In the case where the log flush fails, and T never gets committed, also T2 will never get committed. */

事务T1先在内存中进行提交,此时事务日志还没有刷新到事务日志文件中,但事务所在修改对其余事务T2可见,因为T2访问T1数据,所以T2的LSN确定大于T1的LSN,若是在T1的事务日志被刷新到日志文件以前发生宕机,在系统恢复时,因为事务T1由于没有预写日志而被回滚,当T2由于LSN大于T1且T1发生回滚,所以T1的事务也会发生回滚。
在刷新日志到日志文件时,T2的LSN大于T1的LSN,若是T1的事务日志未刷新到磁盘,那么T2的事务日志确定不会被刷新到磁盘。事务

相关文章
相关标签/搜索