多事务操作同一行数据的明白时候,就会出现各种并发问题,多版mysql通过四种隔离级别来解决这些问题,本控
读提交和可重复读隔离级别都是本控依赖于MVCC多版本控制机制实现,今天我们就来讨论mysql中的MVCC多版本控制机制。
MVCC机制是通过read-view机制与undo log版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据。
事务在开启的时候首先会申请一个事务id:ransaction id。
事务对某行数据做修改操作的时候,Mysql会保留修改前的数据undo回滚日志,并且把事务id:ransaction id赋值给版本记录中的字段trx_id。
把这些undo log日志串联起来形成一个历史记录版本链,如图:
注意这里的版本记录不是真实物理存在的,真实物理存在只有最新的一条记录,其他历史记录都是通过回滚日志推导出来的。
可重复读隔离级别和读提交隔离级别是通过生成一个一致性视图来实现,这个一致性视图就是read-view。
一个事务启动的时候,innodb会为这个事务构造一个数组,用来保存这个事务的启动瞬间正在活跃的所有事务id。“活跃”指的是启动了,但是没提交。
数组里面id最小的值即为低水位,最大的值+1记为高水位,这便是一致性视图。
每个事务在做查询的时候会根据一致性视图的可见性规则去undo log版本链中推导对应的数据。
a. 如果当前事务id落在绿色部分,表示这个版本是已提交的事务或者是当前事务自己生成的,这个数据是可见的;
b. 如果当前事务id落在红色部分,表示这个版本是由将来启动的事务生成的,是肯定不可见的;
c. 如果当前事务id落在黄色部分,那就包括两种情况:
图中事务A查询的i是什么?我们先来分析一下。
按照从上到下事务开启的顺序,每个事务对应的一致性视图如下:
事务A在查询的那个时刻,undo log版本链是:
{ trx_id=11,id=1,i=10,roll_pointer=0}>>>{ trx_id=13,id=1,i=11,roll_pointer=1}>>>{ trx_id=12,id=1,i=12,roll_pointer=2}“{ }” 代表的是版本记录“>>>” 代表的是回滚日志undo log
事务A在查询的时候,事务B和事务C属于未来事务,对事务A是不可见的。因此事务A查询的数据是通过最新的数据记录根据undo log不断向前回滚才得到的数据:i=10。
再看一个案例:
事务A查询1结果是什么?
事务A查询2结果是什么?
由一致性视图可见性规则分析,对事务A来说,事务B是未来事务,对事务A是不可见的,因此查询结果i=10。
查询2的结果i=12,为什么呢?先来看看两个概念:
下面两种查询方式也是当前读:
select k from t where id=1 lock in share mode;select k from t where id=1 for update;
以上便是MVCC机制,按照其规则,这种机制只有在可重复读隔离级别和读提交隔离级别下才会有。
责任编辑:赵宁宁 来源: 码农本农 mysqlMVCC(责任编辑:热点)
基石科技控股(08391.HK)完成配发6962.5万股 每股0.40港元
斯达半导(603290.SH)拟推2021年股票期权激励计划 行权价格为每股134.67元
三维工程(002469.SZ)宣布消息:拟使用不超8亿元自有闲置资金进行投资理财
兴达国际(01899.HK)发布公告:预期2020年纯利同比减少50%