写点什么

解决事务隔离产生问题的 MVCC

  • 2023-04-12
    湖南
  • 本文字数:1593 字

    阅读完需:约 5 分钟

什么是 MVCC ?

MVCC 称为:多版本并发控制,数据多版本并发控制,Multi Version Concurrency Control,也可以称为 MCC,反正我最先知道他就是被称为 MCC,因为当时我了解他的时候是这样的 MultiVersion Concurrency Control。

MVCC 应用在那些数据库的领域?

MYISAM,非聚集索引不存在事务这个概念,更不用说 MVCC 了,只支持表锁。


MVCC 只能用于 INNODB 聚集索引表下的,Reapeable read 和 Read committed 机制。

MVCC 有什么作用?

避免了直接使用锁,大家都知道,使用锁固然是一种很好的方法,保证机制的安全性,但是使用锁的同时大大减低了程序运行的效率,MVCC 就是一种,不加任何锁,却达到了锁的目的的一种良好的机制,同时保证了业务安全与效率的平衡性。MVCC:通过一定机制生成一个数据请求点的一致性数据快照(Snapshot) ,通过 这个快照提供一定级别的一致性读取,类似于多个版本并发执行

MVCC 的工作原理?

特点:只适用于处理“读写”和“写读”的并发事件

MVCC 的组成?

隐藏列:

DB_ID -> 系统 ID(不可重复,在 Oracle 中称为伪列)DB_TRX_ID -> 事务 ID(可以为空)DB_ROLL_PT -> 回滚指针


开启事务不会产生事务 ID(事务编号),只有在修改数据时会出现事务 ID,查询的事务 ID 与修改的事务 ID 不同,查询的事务 ID 大得多,一遍情况下回产生两个事务 ID,一个是查询,一个是修改的修改数据:添加 insert,删除 delect,更新 update

日志:

undo_log -> 回滚数据 :分为两种:insert_undo_logupdate_undo_log

redo_log-->恢复数据“日志先行”(Write-Ahead Logging),在事务开启后,在事务提交之前,会将数据先写入存储引擎的日志缓存中。事务提交之后,会把数据刷新到磁盘持久化。但是在数据库崩了的时候,就可以很有效的使用 redo log 进行数据恢复了。

事务链(版本链):

  1. 修改和删除产生事务链

  2. 添加不写入事务链

  3. 一条数据产生一个事务链

  4. 删除和修改在同一张表上

  5. 除了查询不计其他都计入

  6. select 请求是不会产生版本链的增加的,只有 insert update delete 有

  7. 还未提交的数据事务 ID 在数组内,不加入版本链中

ReadView:

组成活动事务 ID 数组最小事务 ID 下次事务 ID

算法

规则 READ COMMITTED -> 每次事务查询都会产生最新 ReadViewREPEATABLE READ -> 在事务结束之前只保留第一次查询时产生的 ReadView

提交读在 MVCC 中的工作模式:READ COMMITTED

每次事务查询都会产生一个新的 ReadView

可重复读在 MVCC 中的工作模式:REAPETABLE READ

事务结束之前只保留了一次查询是产生的 ReadView


解释不可重复读


	事务A 								   事务B   1:begin;								BEGIN;   2:insert INTO tab(tname,tmoney) VALUES('recently祝祝',80000);(查看事务ID)-- 9322         3:commit;							   4:begin;								BEGIN;   5:update tab SET tname='a' WHERE id=8;(查看事务ID)-- 9327 	   6:									    SELECT id,tname,tmoney  FROM tab WHERE id=8;-- 83960   7:									    SELECT tname,tmoney  FROM tab;-- 83960 -- 查不到   8:COMMIT;								   9:										SELECT id,tname,tmoney  FROM tab WHERE id=8;-- 查不到   10:										commit;
复制代码


解释幻读:


-- REAPETABLE READ -- MySQL中默认的隔离级别-- 幻读的原因	事务A 									事务B   1:begin;								BEGIN;   2:insert INTO tab(tname,tmoney) VALUES('shimmer',8000);(查看事务ID)-- 9337      3:										SELECT id,tname,tmoney  FROM tab WHERE id=9;-- 查不到   4:commit;   5: 										SELECT id,tname,tmoney  FROM tab WHERE id=9;-- 查不到数据   6: 										UPDATE tab SET tname='a' WHERE id=9;(查看事务ID)-- 9338     6:										SELECT id,tname,tmoney  FROM tab WHERE id=9; -- 查到数据   7:										COMMIT;								
复制代码




查看事务 ID:

USE information_schema;SELECT * FROM innodb_trx;
复制代码

作者:Recently 祝祝

链接:https://juejin.cn/post/7220643710659854393

来源:稀土掘金

用户头像

还未添加个人签名 2021-07-28 加入

公众号:该用户快成仙了

评论

发布
暂无评论
解决事务隔离产生问题的MVCC_做梦都在改BUG_InfoQ写作社区