InnoDB多版本并发控制MVCC

前言

InnoDB维护旧版本数据来支持事务并发和回滚。旧版本信息会存储在系统表空间或者undo表空间里,以回滚段(rollback segment)的数据结构存储。当事务需要回滚的时候就会使用到这些回滚段来回滚,同时一致性读的时候也会用到这些回滚段。

注:
1、系统表空间:system tablespace,是InnoDB存储数据的空间,存储了doublewrite buffer、change buffer、undo logs,同时可能会存储表数据和索引数据。我们常见的ibdata1这种文件就存储在这个空间。
2、undo表空间:undo tablespaces,这个空间里存储了undo logs,能够节约其他表空间如system tablespace的使用,同时针对SSD存储该空间有做IO优化。


InnoDB架构图

实现原理

1、InnoDB向表里的每行增加三个字段

  • DB_TRX_ID,记录了上一次插入或者更新该行的事务id,删除操作也被视为更新操作
  • DB_ROLL_PTR,回滚指针,指向回滚段,如果一行被更新,那么更新之前undo log会记录这一行的信息。
  • DB_ROW_ID,如果是自增主键,这个值则包含自增主键,如果不是,那么该ID会给每个新增的行存储一个单调递增的ID。

2、Undo logs在回滚段里被划分为insert undo logs和update undo logs,前者事务提交之后就可以清除了;后者主要记录更新的版本数据,并且可以用于一致性读。

3、聚簇索引数据在原位置更新,且这些行的隐藏列会指向undo logs;辅助索引数据的更新则是先删除再插入,同时没有隐藏列,如果涉及事务一致性读或者回滚等操作则会找到该索引对应的聚簇索引,取出DB_TRX_ID,从undo log里取出正确版本信息。

InnoDB是如何利用一致性读(快照读)的

0、快照读和当前读

a、快照读简单理解为是事务里的select。快照读利用mvcc实现。
b、当前读简单理解为是事务里的update、delete。当前读加锁实现。

1、Repeatable Read可重复读隔离级别下

  • 同一事务里的所有快照读都读的是第一次读时创建的快照

If the transaction isolation level is REPEATABLE READ (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction.

  • 此隔离级别下通过快照读和next-key lock(当前读)解决了幻读问题

a、快照读解决幻读就不解释了
b、当前读的时候会给读取到的行加上next-key lock,如果是范围读就给范围加锁,如果是读一些行就给行和行前的间隙加锁。这样当前读的时候就不会有新的数据插入或者被删除

  • 考虑RR级别下一致性读的原理
begin
# first read
select * from table where id = 21
.....
# second read
select * from table where id = 21
commit

a、第一次读的时候会创建快照,此时select读取的行里有隐藏了DB_TRX_ID,同时DB_ROLL_PTR指向undo logs里的回滚段。

b、假设此时innodb里有多个活跃的事务887、889、890,和已经提交的事务885、886,则创建快照过程如下:

首先,如果DB_TRX_ID小于当前活跃的最小事务min_active_trx_id,那么说明该行数据是被已提交的事务修改的,直接返回该快照
否则,如果DB_TRX_ID大于等于当前最大事务id max_trx_id,则说明其他新事务修改了这行数据,此时需要从undo log里取已提交的数据创建快照并返回
如果,DB_TRX_ID 大于等于当前活跃的最小事务ID,并且小于当前最大事务ID。
情况1、DB_TRX_ID 是非活跃事务ID,说明修改这行数据的事务已经提交了,直接返回该快照
情况2、如果DB_TRX_ID是活跃事务ID,则说明修改这行数据的事务当时还没提交,这时候就要判断create_trx_id是不是等于DB_TRX_ID,如果是,说明当前事务之前操作了这行数据,则直接返回快照。否则,说明数据是其它活跃事务修改的,那么数据不可见,需要从undo log 里获取已提交的数据创建快照并返回。

d、第二次读的时候直接读取相同快照即可

2、Read Commited 读已提交隔离级别下

  • 同一事务里的所有快照读都自己创建快照,并读取这个快照
  • 可以看出此隔离级别下快照读无法解决幻读问题,因为每次读都创建快照,不保证多个读操作的一致性
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容