MySQL Innodb的MVCC实现原理

        之前面试时有被问到mysql的mvcc,虽然对mvcc的机制大概了解,但是mysql中是怎么实现mvcc的确实没有认真去了解过。今天就完整的学习一下。因为都是自己的理解,可能会有错误。如有发现,还请留言指正。

        mvcc是Multi-version concurrency control的缩写,也就是多版本并发控制。大家都知道,事务的隔离可以通过行锁来实现。在开启事务时,对操作记录加行锁,事务结束时释放锁。但是这样加锁会降低事务的并发量,并且对线程的阻塞和恢复操作也会损耗性能。那种在事务中使用了select …… for update/ lock in share mode 的就是对记录使用了行锁,实现一致性锁定读。而对于未加锁的记录,在innodb中的repeatable read级别下会通过mvcc进行并发控制,实现一致性非锁定读。

        一般概念上的mvcc是通过在row record上隐式的增加两个版本号(创建版本号和删除版本号)字段来记录数据的创建时间和删除时间。新增记录时,创建版本号填入当前事务的事务号,删除版本号置空;删除记录时,将记录标记为删除状态,并将当前事务号填入删除版本号;当进行更新记录操作时,则是先将旧记录标记为删除(并填入删除版本号),而后在插入一条新的记录,创建版本号填入当前事务号。这样在同一个事务中,不管期间有多少个其它并发事务对其查询的记录做过任何操作,都可以通过将查询出的所有记录进行版本号过滤(过滤掉创建版本号大于当前事务号和删除版本号小于当前事务号的记录),得到与事务开启时一致的查询结果。通过mvcc,减少了对数据加锁的操作,减小性能开销,大大提高了数据库的事务并发能力。

        MySQL中的mvcc虽然从原理上讲和上述实现相似,但是实际的实现则略有不同,主要是体现在update操作上。首先,row record上和mvcc相关的隐式字段有3个, DATA_TRX_ID,DATA_ROLL_PTR,DELETE BIT:

  • 6字节的DATA_TRX_ID 标记了最新更新这条行记录的transaction id

  • 7字节的DATA_ROLL_PTR 指向当前记录项的rollback segment的undo log记录,找之前版本的数据就是通过这个指针

  • DELETE BIT位用于标识该记录是否被删除,这里的不是真正的删除数据,而是标志出来的删除。真正意义的删除应该是在purge线程里执行的

        在更新行的时候,先对记录加锁,然后把行数据复制一份到回滚段的undo日志中,并将DATA_ROLL_PTR的指针指向undo中的记录。然后更新记录,同时将当前的事务号作为该行的更新版本填入DATA_TRX_ID字段。这样,当查询被其它事务修改了的记录时,可以根据DATA_ROLL_PTR 一层一层的回溯到当前事务开启前的数据版本,实现快照读。

        参考资料:InnoDB多版本(MVCC)实现简要分析Mysql中的MVCC

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值