这篇文章主要讲解了“MySQL MVCC的实现原理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MYSQL MVCC的实现原理”吧!
成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:做网站、成都网站建设、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的大新网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
MVCC 首先是为并发而产生的(MVCC multi version Concurrency control),而因为要并发事务,使用了2PL 2段锁,下面画一个图来看看两段锁
2 Phase lock 包含两个区段,扩展和收缩,而在实际当中这个而两个阶段其实可以通过commit rollback来进行区分,在此之前都是 Growing 阶段,在这之后都就属于shrink 了。
而基于两段锁的原理,就产生最初的两种锁 S X 锁,S 锁用于读,在记录被加载S 锁的时候,是不能进行相关记录行的数据更新的,但可以添加其他S锁进行数据的读取, X 锁则是在记录更新时,不能有其他X 锁,或S锁在此记录上加锁。
而这样的锁的设置,就引起一些争论点,使用这样的方式的数据库的性能低下。那如何能在此理论下,提出一个能提升系统性能的方法,就变得重要了。
开发人员提出了,多版本控制的方法来降低由于锁的问题,而产生的性能问题,这就是 MVCC 的由来。
对于多版本的控制,来说在设计的时候回会在每行记录中增加三个隐藏的字段, DB_TRX_ID 用来记录这一行的的事务 当前使用它的事务ID , DB_ROLL_PTR 则是记录这条记录与UNDO 空间记录之间的关系,好在记录回滚的时候,映射出回滚段与记录之间的关系。
其中 DB_TRX_ID 是保留事务最新的 ID 号,而 DB_ROLL_PTR 则是指向UNDO LOG 中修改行中被修改前的信息。(这不就有两个版本了,1 新的修改的记录, 2 没被修改的记录)多版本控制仅仅在 RR , RC 两个MVCC 中进行支持。
在InnoDB多版本控制方案中,当您使用SQL语句删除一行时,它不会立即从数据库中物理删除。InnoDB只有在丢弃为删除而编写的update undo日志记录时,才会物理地删除相应的行及其索引记录。这个删除操作称为清除,它非常快,通常使用与执行删除操作的SQL语句相同的时间顺序。
从中我们可以推出,UNDO LOG 一定是要在事务commit前进行的,
1 数据提出修改
2 将数据修改前的信息刷新到 UNDO LOG
3 更新要更新的数据
4 将UNDO LOG 的信息落到磁盘中
5 BINLOG 记录
6 事务提交
注:这里未涉及 REDO LOG 以及各种BUFFER 的讨论
在多版本控制中,聚集索引和secondary INDEX 之间的数据更新是不同的,更新secondary索引列时,将删除旧的辅助索引记录,插入新记录,并最终清除删除标记的记录。二级索引记录被删除或二级索引页被update的事务更新时,InnoDB在聚集索引中查找数据库记录。在聚集索引中,检查记录的DB_TRX_ID,如果在读取事务启动后修改了记录,则从undo日志中检索记录的正确版本。
所以在多版本控制中,UNDO LOG 起到不可替代的作用,在事务未提交,中进行数据的读取是,UNDO LOG 将提供当时的记录信息,而表中的行中的隐藏字段将对多版本的控制是一个关键的设计。
同时如果一次进行的事务比较大,例如UPDATE 就要占用更大的UNDO LOG 的空间,如果更新的事务的大小,频次过多,还可能引起整体的数据性能低下,所以控制事务的大小对整体的系统的性能是至关重要的。
而要说 MVCC 最大的初衷,个人认为
1 读不影响写
2 写不影响读
是MVCC 最要实现的功能。
感谢各位的阅读,以上就是“MYSQL MVCC的实现原理”的内容了,经过本文的学习后,相信大家对MYSQL MVCC的实现原理这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!