MYSQL MVCC 实现机理 与 知识漏洞要补

说来惭愧,被友人问了一些关于MYSQL 的问题,虽然算不上对答如流,但也算是沉稳应对。唯独折在 MVCC 中MYSQL INNODB 是如何实现的问题上,回答错误扣10分。本着知错能改,有漏洞要补的,精神。还是的把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 最要实现的功能。

在学习的过程中,一般都是由整体延展性的学习知识,可能由于各种问题,某些关键性的东西忘记,或根本就没有注意,或自以为自己会了,所以有个人能不停的问你一些问题,帮你做扫描,这是好事,谢谢那位友人。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值