本篇文章主要介绍了"mysql之分布式事务",主要涉及到方面的内容,对于MySql感兴趣的同学可以参考一下:
分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题...
分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题。在分布式事务环境下,事务的提交会变得相对比较复杂,因为多个节点的存在,可能存在部分节点提交失败的情况,即事务的ACID特性需要在各个数据库实例中保证。总而言之,在分布式提交时,只要发生一个节点提交失败,则所有的节点都不能提交,只有当所有节点都能提交时,整个分布式事务才允许被提交。
分布式事务通过2PC协议将提交分成两个阶段
- prepare;
- commit/rollback
第一阶段的prepare只是用来询问每个节点事务是否能提交,只有当得到所有节点的“许可”的情况下,第二阶段的commit才能进行,否则就rollback。需要注意的是:prepare成功的事务,则必须全部提交。
MySQL分布式事务
一直以来,MySQL数据库是支持分布式事务的,但是只能说是有限的支持,具体表现在:
- 已经prepare的事务,在客户端退出或者服务宕机的时候,2PC的事务会被回滚
- 在服务器故障重启提交后,相应的Binlog被丢失
上述问题存在于MySQL数据库长达数十年的时间,直到MySQL-5.7.7版本,官方才修复了该问题。虽然InnoSQL早已在5.5版本修复,但是对比官方的修复方案,我们真的做的没有那么的优雅。下面将会详细介绍下该问题的具体表现和官方修复方法,这里分别采用官方MySQL-5.6.27版本(未修复)和MySQL-5.7.9版本(已修复)进行验证。
先来看下存在的问题,我们先创建一个表如下:
1 2 3 4 | create table t(
id
int auto_increment primary key ,
a
int
)engine=innodb;
|
对于上述表,通过如下操作进行数据插入:
1 2 3 4 | mysql>
XA START 'mysql56' ;
mysql>
INSERT INTO t VALUES (1,1);
mysql>
XA END 'mysql56' ;
mysql>
XA PREPARE 'mysql56'
|
通过上面的操作,用户创建了一个分布式事务,并且prepare没有返回错误,说明该分布式事务可以被提交。通过命令XA RECOVER查看显示如下结果: