栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MVCC原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MVCC原理

文章目录
  • 什么是mvcc
    • 当前读
    • 快照读
  • mvcc的原理
    • 隐式字段
    • undo log
    • Read View
  • 当为读已提交(RC)隔离级别的时候
  • 当为可重复读(RR)隔离级别的时候

什么是mvcc

mvcc即多版本并发控制。他主要在mysql innoDB中提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突,也可以做到不加锁,非阻塞并发读
MVCC模型在MySQL中的具体实现则是由 3个隐式字段(DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID),undo日志 ,Read View 等去完成的
MVCC 只能在READ COMMITTED和REPEATABLE READ两个隔离级别下工作,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行,而SERIALIZABLE则会对所有读取的行都加锁。

当前读

像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁

快照读

像不加锁的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是未提交读和串行化级别,因为未提交读总是读取最新的数据⾏,⽽不是符合当前事务版本的数据行,而串行级别下的快照读会退化成当前读,会对所有读取的⾏都加锁;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

Read Committed隔离级别:每次select都生成一个快照读。
Read Repeatable隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。
快照读的实现方式:undolog和多版本并发控制MVCC

mvcc的原理 隐式字段

DB_TRX_ID: 6字节DB_TRX_ID字段,表示最后更新的事务id(update,delete,insert)。此外,删除在内部被视为更新,其中行中的特殊位被设置为将其标记为已软删除。

DB_ROLL_PTR: 7字节回滚指针,指向前一个版本的undolog记录,组成undo链表。如果更新了行,则撤消日志记录包含在更新行之前重建行内容所需的信息。
  DB_ROW_ID: 6字节的DB_ROW_ID字段,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
  
如上图,DB_ROW_ID是数据库默认为该行记录生成的唯一隐式主键,DB_TRX_ID是当前操作该记录的事务ID,而DB_ROLL_PTR是一个回滚指针,用于配合undo日志,指向上一个旧版本

undo log

undo log主要分为两种:

  • insert undo log
    代表事务在insert新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
  • update undo log
    事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除,只有在快速读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
Read View

Read View就是事务进行快照读操作的时候生产的读视图(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照,记录并维护系统当前活跃事务的ID(当每个事务开启时,都会被分配一个ID, 这个ID是递增的,所以最新的事务,ID值越大)

所以我们知道 Read View主要是用来做可见性判断的, 即当我们某个事务执行快照读的时候,对该记录创建一个Read View读视图,把它比作条件用来判断当前事务能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。
通俗来讲就是我们select的时候,要从版本链中取哪一个
read view参数:

m_ids:没有commit的事务id
min_trx_id:m_ids中最小的id
max_trx_id:是应该赋给下一个的事务id,比如此时m_ids为1,2,3,min_trx_id就为1,max_trx_id为4
creator_trx_id:是谁生成了这个readview,他的id

当为读已提交(RC)隔离级别的时候

在每次执行快照读时生成readview


根据判断规则,最后算出他只能读到trx_id=1,name=张三的那一条,对照图就正好是读已提交。

这个得出最后可以读到trx_id=2,的那一条,这里根据上面的正好也体现出来了,一个事务中的两次select得出的结果不同,是不可重复读。

当为可重复读(RR)隔离级别的时候

仅在第一次执行快照读时生成readview,后续的快照读复用

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/605617.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号