MySQL--MVCC

MVCC基本概念

当前读

读取的是最新版本,读取时保证其他并发事务不能修改当前记录,会对读取记录加锁比如时常操作的出select...语句之外的共享锁和排他锁都是当前读。

快照读

简单的select语句(不加锁)就是快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。
Read Committed(RC):每次都生成一个快照读。
Repeatable Read(RR):开启事务的第一个select语句就是快照读的地方。
Serializable:快照读会退化到当前读。

MVCC

多版本并发控制。维护一个数据的多个版本,使读写没有冲突,快照读使MySQL实现MVCC提供了一个非阻塞读功能。MVCC具体实现依赖数据库记录中的三个隐式字段、undo log日志、readView。

MVCC核心

表三个隐藏字段

DB_TRX_ID

记录操作该数据事务的事务ID;

DB_ROLL_PTR

指向上一个版本数据在undo log 里的位置指针;

DB_ROW_ID

隐藏ID ,当创建表没有合适的索引作为聚集索引时,会用该隐藏ID创建聚集索引;

DB_ROW_ID是数据表无主键无唯一约束时自动创建的

undo log

回滚日志,记录了事物修改之前的数据信息,当事物回滚时候,通过undo log日志回滚数据。
当insert的时候,产生undo log日志只在回滚时需要,当事务提交后,可立即删除。
update、deleed时,产生undo log 日志不仅在回滚需要,在快照读时也需要,所以不会立即被删除。
  • undo log版本链

user表数据

id

name

age

DB_TRX_ID

DB_ROLL_PTR

1

abc

10

1

0x00001

版本链

不同事务或相同事务对同一条记录修改,会导致该记录的undo log生成一条记录版本链表,链表的头部时最新的旧记录,链表尾部是最早的旧记录。

readView

ReadView是快照读SQL执行时MVCC提取数据的依据,记录并维护当前活跃事务(未提交的)id.

ReadView中四个核心字段

字段

含义

m_ids

当前活跃事务id集合

min_trx_id

最小活跃事务id

max_trx_id

预分配事务id,当前最大事务+1(因为事务id是自增的)

creator_trx-id

ReadView创建者的事务id

版本链数据访问规则

trx_id 代表当前undolog版本链对应事务ID

不同的隔离级别,生成ReadView的时机不同

READ COMMITTED :在事务中每一次执行快照读时生成ReadView。
REPEATABLE READ:仅在事务中第一次执行快照读时生成ReadView,后续复用该ReadView。

RC

RR

RR级别下只有第一次执行快照读时生成ReadView,后续复用该ReadView。

MVCC是否解决了幻读

严格意义上并没有解决幻读MVCC利用版本链,undo log,Read View可以在快照读模式下解决幻读问题,并且不用加锁解决读写冲突问题,极大的增加了数据库的并发量。 但在当前读模式下仅仅依靠MVCC不能解决幻读问题,必须依赖next-key锁(行锁+GAP锁)来解决,这是因为当前读必须获取最新数据。

所以呢,MVCC的实现原理就是通过 InnoDB表的隐藏字段、UndoLog 版本链、ReadView来实现的,而MVCC + 锁(next-key ),则实现了事务的隔离性。 而一致性则是由redo log 与 undolog保证
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值