注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭研后台技术中心的博客

 
 
 
 
 

日志

 
 

MySQL XA 事务的一些问题  

来自江羽   2013-06-07 09:41:20|  分类: 默认分类 |举报 |字号 订阅

  下载LOFTER 我的照片书  |

MySQL官方对XA的事务支持一直都存在些问题:

  1. prepare后的xa事务在客户端退出时被回滚
  2. prepare后的xa事务,如果server crash后重启,commit后会造成master-slave数据不一致
  3. prepare后的xa事务,如果server crash后重启,select-xa commit-select造成第二个select命中query cache的问题

下面具体分析上上述几个问题产生的主要原因:

1. prepare后的xa事务在客户端退出时被回滚

MySQL在master-slave的replication运用中,xa事务对于slave来讲就是一个普通的事务,master只有在xa commit的时候才把操作写入binlog,对于master整个commit之前的操作,slave并不感知,如果master上有事务在xa prepare后退出,如果不回滚该xa事务,造成其他客户端在操作xa事务中操作的表示,会被block住,所以MySQL在处理xa事务上,在客户端退出时把该客户端所有做了xa prepare的事务都进行了回滚。

2. prepare后的xa事务,如果server crash后重启,commit后会造成master-slave数据不一致

对于这个问题,MySQL手册上有一段描述:

" If an XA transaction has reached the PREPARED state and the MySQL server is killed (for example, with kill -9 on Unix) or shuts down abnormally, the transaction can be continued after the server restarts. However, if the client reconnects and commits the transaction, the transaction will be absent from the binary log even though it has been committed. This means the data and the binary log have gone out of synchrony. An implication is that XA cannot be used safely together with replication. "

从上面的描述中,我们可以知道:xa事务在replication环境下是不安全的,可能会造成主从不一致

那么我们来分析下,为什么会出现这种情况。

MySQL在进行xa事务的时候,所有操作的binlog保存在binlog的cache中,当xa事务进行commit后,才把cache中的信息刷到binlog文件中,而在prepare后server crash,重启后binlog cache中的信息被丢失,而xa事务是在InnoDB层的,InnoDB在启动的时候会把prepare的事务恢复到事务列表,也就是说,在MySQL重启后,xa事务在InnoDB层会被恢复,而binlog层被丢失了,所以在进行commit后,事务被提交了,而binlog没有被记录,造成主从上的数据不一致。

3. prepare后的xa事务,如果server crash后重启,select-xa commit-select造成第二个select命中query cache的问题

该问题是MySQL-5.5.x版本中的问题,在MySQL5.6中已经被修复

该问题重现如下:

xa start '111';

insert into t values(1);

xa end '111';

xa prepare '111';

kill -9 pid

restart the server

select * from t;

xa commit '111';

select * from t;

上面操作的两个select * from t,在第二个select操作时,会命中第二个select的query cache,即使在xa commit ‘111’中对表t进行了插入,这是MySQL的一个bug。

这里由于在执行xa commit的时候没有产生undo日志(undo产生都在server crash之前),所以query cache没有失效,第二次select就直接命中了query cache,造成查询的结果是错误的。这种情况在非xa事务下不会出现。

通过上面的介绍,我们看到MySQL对XA事务的支持没有完全符合XA事务标准,在XA Prepare的时候没有产生binlog,这个主要由于MySQL binlog本身的特点决定,或许以后通过GTID(全局事务ID)可以解决该问题

  评论这张
 
阅读(1545)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017