ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MVCC

2022-07-18 02:01:57  阅读:180  来源: 互联网

标签:事务 Read DB MVCC ID View


什么是MVCC?

在InnoDB存储引擎中,MVCC 多版本并发控制(multi versioning), 是对一致性非锁定读的实现,MVCC 是一种用来解决读-写冲突的无锁并发控制,为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只能读到生成Read View之前已经完成的事务。在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能 同时还可以解决 脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

MVCC的实现原理

MVCC的实现依赖于3个隐藏字段,read view,undo log。在内部实现中innodb会把数据行中的隐藏字段DB_TRX_ID事务id与read view中的数据进行比较,判断数据的可见性,如果不可见则会通过数据行的DB_ROLL_PTR回滚指针,找到undo log中的历史版本。每个事务能看到的数据库版本可能是不一样的,用户只能读取到生成Read View之前已经提交的事务和该事务本身做的修改。

隐式字段

每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段
● DB_ROW_ID 6byte, 隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
● DB_TRX_ID 6byte, 最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID
● DB_ROLL_PTR 7byte, 回滚指针,指向这条记录的上一个版本(存储于rollback segment里)
● DELETED_BIT 1byte, 记录被更新或删除并不代表真的删除,而是删除flag变了

Read View (读视图)

Read View就是事务进行快照读操作的时候生产的读视图(Read View) 用于判断数据的可见性。里面保存了对当前事务不可见的其他事务。Read View里面主要包含了重要参数

  1. trx_list 生成read view时,还在活跃的事务id
  2. up_limit_id // trx_list当中的最小事务id
  3. low_limit_id // 生成read view时,数据库还未分配的下一个事务id

具体的比较算法时,把要读取的数据的DB_trx_id宇up_limit_id进行比较,

  1. 如果DB_Trx_id<up_limit_id,那么久证明,该数据的最新事务,时在生成read view事务前,因此对当前事务课件
  2. 如果DB_trx_id >= low_limit_id , 证明该数据时生成read view之后产生的,因此不可以见
  3. 如果DB_trx_id 在trx_list内,也是不可见的。表示生成read view时,该数据的事务还没有提交

快照读和锁定读

快照读

读取的是数据的一个快照,不一定是最新版本的一个数据

锁定读

读取的是数据的最新,锁定读会对读取到的记录进行加锁

  1. select ... lock in share mode
  2. select ... for update;
  3. insert 、update、delete操作

Undo log

为了回滚而记录的操作日志叫做undo log。比如:

  1. insert undo log :指在 insert 操作中产生的 undo log。因为 insert 操作的记录只对事务本身可见,对其他事务不可见,故该 undo log 可以在事务提交后直接删除。不需要进行 purge 操作
    ● update 的时候会把数据的旧值记录下来
  2. update undo log :update 或 delete 操作中产生的 undo log。该 undo log可能需要提供 MVCC 机制,因此不能在事务提交时就进行删除。提交时放入 undo log 链表,等待 purge线程 进行最后的删除

判断数据的可见性

在 InnoDB 存储引擎中,创建一个新事务后,执行每个 select 语句前,都会创建一个快照(Read View),快照中保存了当前数据库系统中正处于活跃(没有 commit)的事务的 ID 号。其实简单的说保存的是系统中当前不应该被本事务看到的其他事务 ID 列表(即 m_ids)。当用户在这个事务中要读取某个记录行的时候,InnoDB 会将该记录行的 DB_TRX_ID 与 Read View 中的一些变量及当前事务 ID 进行比较,判断是否满足可见性条件

RC 和 RR 隔离级别下 MVCC 的差异

在事务隔离级别 RC 和 RR (InnoDB 存储引擎的默认事务隔离级别)下,InnoDB 存储引擎使用 MVCC(非锁定一致性读),但它们生成 Read View 的时机却不同
● 在 RC 隔离级别下的 每次select 查询前都生成一个Read View (m_ids 列表)
● 在 RR 隔离级别下只在事务开始后 第一次select 数据前生成一个Read View(m_ids 列表)

MVCC 解决不可重复读问题

RR隔离级别下,第一次select 的时候生成Read View

MVCC➕Next-key-Lock 防止幻读

InnoDB存储引擎在 RR 级别下通过 MVCC和 Next-key Lock 来解决幻读问题:
1、执行普通 select,此时会以 MVCC 快照读的方式读取数据
在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读”
2、执行 select...for update/lock in share mode、insert、update、delete 等当前读
在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lockopen in new window 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读

标签:事务,Read,DB,MVCC,ID,View
来源: https://www.cnblogs.com/amberbar/p/16489042.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有