MySQL多版本并发控制(MVCC)

MySQL在大多数事务型存储引擎实现的都不是简单的行级锁。为了提升性能他们一般都同时实现了多版本并发控制(MVCC)。不仅是MySQL,包括Oracle,PostgreSQL等也都实现了MVCC,但各自实现的机制不同,因为MVCC没有一个统一的实现标准。

MVCC定义

MVCC全称Mutli Version Concurreny Control,多版本并发控制,也可称之为一致性非锁定读;它通过行的多版本控制方式来读取当前执行时间数据库中的行数据。实质上使用的是快照数据,这样就可以实现不加锁读。MVCC 主要应用于 Read Commited 和 Repeatable read 两个事务隔离级别。

1. innoDB 的逻辑存储结构

innoDB 的数据保存在表空间中,表空间又包含各种段,其中有数据段,索引段,回滚段。InnoDB中数据以B+Tree的数据结构存储的,非叶子节点也就是索引,叶子节点也就是数据行,回滚段用于存储undoLog,undoLog中记录的就是多版本数据,用于快照读和事务失败后的数据回滚,MySQL在合适的时机会清理undoLog。

2. MVVC的实现

MVCC的实现依赖于 每行的隐藏字段,DB_TRX_ID,DB_ROLL_PTR,删除标记位,还有read_view。

3. 三个隐藏字段

  • ```DB_TRX_ID``` 事务id 占6 字节,表示这一行数据最后插入或修改的事务id。此外删除在内部也被当作一次更新,在行的特殊位置添加一个删除标记(记录头信息有一个字节存储是否删除的标记)。

  • ```DB_ROLL_PTR``` 回滚指针 占7字节,回滚指针指向被写在 ```Rollback segment```中的undoLog记录,在该行数据被更新的时候,undoLog 会记录该行修改前内容到undoLog。

  • ```DB_ROW_ID``` 行ID 占7字节,他就项自增主键一样随着插入新数据自增。如果表中不存主键 或者 唯一索引,那么数据库 就会采用 ```DB_ROW_ID ```生成聚簇索引。否则```DB_ROW_ID ```不会出现在索引中.

4. undo log

  • undo log是为回滚而用,具体内容就是copy事务前的数据库内容(行)到undo buffer,在适合的时间把undo buffer中的内容刷新到磁盘。undo buffer与redo buffer一样,也是环形缓冲,但当缓冲满的时候,undo buffer中的内容会也会被刷新到磁盘;与redo log不同的是,磁盘上不存在单独的undo log文件,所有的undo log均存放在主ibd数据文件中(表空间),即使客户端设置了每表一个数据文件也是如此。

  • undo log 在 ```Rollback segment```中又被细分为 insert 和 update undo log , insert 类型的undo log 仅仅用于事务回滚,当事务一旦提交,insert undo log 就会被丢弃。update的undo log 被用于 一致性的读和事务回滚,update undo log 的清理 是在 没有事务 需要对这部分数据快照进行一致性读的时候 进行清理。

  • undo log 的创建 每次对数据进行更新操作时,都会copy 当前数据,保存到undo log 中。并修改 当前行的 回滚指针指向 undo log 中的 旧数据行。

5. read_view 判断数据行可见性 在innodb中,创建一个新事务的时候,innodb会将当前系统中的活跃事务列表创建一个副本(read view),副本中保存的是系统当前不应该被本事务看到的其他事务id列表。当用户在这个事务中要读取该行记录的时候,innodb会将该行当前的版本号与该read view进行比较。 6. (提交读)Read Commited ,(可重复读)Repeatable read 数据可见性判断 Read Commited 和 Repeatable read 采用相同的数据可见性判断逻辑。 那么怎么在相同的判断逻辑下 分别 实现 RC 和 RR 级别的?

  • Read Commited
在每次语句执行的过程中,都关闭read_view, 重新创建当前的一份新的read_view。 这样就可以根据当前的全局事务链表创建read_view的事务区间,实现read committed隔离级别。
  • Repeatable read
在repeatable read的隔离级别下,创建事务trx结构的时候,就生成了当前的global read view。 使用trx_assign_read_view函数创建,一直维持到事务结束,这样就实现了repeatable read隔离级别。

参考文档

zhaohao

大家好,欢迎来到赵豪博客!赵豪,94年生人,PHP程序员一枚,因为对PHP开发有着相对比较浓厚的兴趣,所以现在从事着PHP程序员的工作。 今天再次开通这个博客,这里将记录我的职业生涯的点点滴滴,感谢来访与关注!如果我的博客能给您带来一些帮助那真是一件非常荣幸的事情~

相关推荐

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

微信扫一扫

微信扫一扫

微信扫一扫,分享到朋友圈

MySQL多版本并发控制(MVCC)
返回顶部

显示

忘记密码?

显示

显示

获取验证码

Close