MySQL XA事务

2PC事务

2pc事务即通常所说的两阶段提交事务,全称Two Phase Commitment Protocol,主要为了解决在分布式部署的情况下,所有节点间数据一致性问题。在分布式部署的情况下,事务的提交会变得相对比较复杂,因为多个节点的存在,可能存在部分节点提交失败的情况,这个时候需要保证数据一致性的话,需要回滚那些能够提交的节点上的事务,总而言之,在分布式提交时,只要发生一个节点提交失败,则所有的节点都不能提交,只有当所有节点都能提交时,整个2pc事务才允许被提交。那么,怎样来保证所有的分布式节点都可以提交?其实,2pc事务的提交被分成两个阶段:第一阶段:prepare,第二阶段:commit/rollback。第一阶段的prepare只是用来询问每个节点事务是否能提交,只有当得到所有节点的“许可”的情况下,第二阶段的commit才能进行,否则就rollback。

继续阅读

MySQL基本概念——DoubleWrite

【背景】

前几天跟人聊起基于共享存储的MySQL,要保证Slave也能读数据,在主出现故障时能快速切换。由于MySQL上的数据刷盘是异步的,Slave读数据可能读取到的页是正在变更中的,这个能否有解决方法?第一个反应想到的是类似于DoubleWrite的结构,先开辟一块空间,把整个提交事务的数据先写到这块空间上,然后再拷贝到存储上,这种方式的确能实现类似需求,但是有几个问题:

  1. 事务不能过大,不然开辟的空间大小不好确定
  2. 主上提交的事务可能需要过段时间才能被从上读取,延迟过高。

其实这个需求有个很好的参考点,ORACLE的RAC基本就是这个套路,排除共享存储的实现,MySQL端需要做的,估计就只有实现Redo的复制和在Slave内存中的重放,当然也要禁掉Slave的刷盘行为。Redo复制,这个大厂基本都已经搞了,aliSQL在Percona大会上就讲过他们的物理复制,Aurora的关键点技术也是基于底层Redo的复制,现在就等MySQL官方版本什么时候放出来了。

继续阅读

MySQL MVCC实现

数据多版本(MVCC)是MySQL实现高性能的一个主要的一个主要方式,通过对普通的SELECT不加锁,直接利用MVCC读取指版本的值,避免了对数据重复加锁的过程,今天我们就用最简单的方式,来分析下MVCC具体的原理,先解释几个概念:

隐藏列

在分析MVCC原理之前,先看下InnoDB中数据行的结构:

row

在InnoDB中,每一行都有2个隐藏列DATA_TRX_ID和DATA_ROLL_PTR(如果没有定义主键,则还有个隐藏主键列):

  1. DATA_TRX_ID表示最近修改该行数据的事务ID
  2. DATA_ROLL_PTR则表示指向该行回滚段的指针,该行上所有旧的版本,在undo中都通过链表的形式组织,而该值,正式指向undo中该行的历史记录链表

整个MVCC的关键就是通过DATA_TRX_ID和DATA_ROLL_PTR这两个隐藏列来实现的。

继续阅读

MySQL异常锁冲突一例

背景

MySQL版本:5.7, 隔离级别:RR

测试表结构:

CREATE TABLE `sbtest1` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`k` int(11) NOT NULL DEFAULT ‘0’,

`c` char(120) NOT NULL DEFAULT ”,

`pad` char(60) NOT NULL DEFAULT ”,

PRIMARY KEY (`id`),

) ENGINE=InnoDB

标准的sysbench测试表,由于二级索引跟本次分析无关,所以没有创建。

整个表大概有50w行记录,表中的数据记录如下:

id k c pad
100 250731 xxx xxx
101 251240 xxx xxx
150 249472 xxx xxx
151 251323 xxx xxx

继续阅读