28|MVCC:如何突破数据库并发读写性能瓶颈?
黄清昊
该思维导图由 AI 生成,仅供参考
你好,我是微扰君。
过去两讲,我们学习了数据库中查询优化的一个重要手段——索引,通过空间换时间的思想,从数据结构查询本身的时间复杂度和 IO 开销两个角度,去提高查询的速度。除此之外,查询能做的优化其实还有很多,比如同样的语句在采用不同查询计划的情况下,查询效率可能也是差距很大的。
今天我们就从业务开发非常常见的一个角度,并发,来聊一聊数据库可能的性能优化。首先来看并发场景下,我们在数据库中会碰到什么样的问题。
为什么需要事务
我们知道,主流的关系型数据库都能做到在高并发的场景下支持事务,比如 MySQL 的 InnoDB 引擎就支持事务,从而取代了并不支持事务的 MyISAM 引擎。但为了保证事务性,其实需要付出一定的性能代价。那事务是什么,我们来简单复习一下。
简单来说,事务就是指一系列操作,这些操作要么全部执行成功并提交,要么有一个失败然后全部回滚像什么都没发生一样,绝对不会存在中间有一部分操作得以执行,一部分没有执行。
为什么数据库中需要事务呢,一个非常经典的例子就是银行转账,比如说我们需要从 A 账户给 B 账户转 200 元。整个过程要分为两个步骤,分别是:对 A 的账户余额减去 200、对 B 的账户余额加上 200,如果这两个操作一个成功一个失败,显然会导致业务数据完整性出现问题。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
MVCC(多版本并发控制)是数据库中解决并发读写性能瓶颈的重要技术。本文首先介绍了事务的概念和隔离性问题,包括脏读、不可重复读和幻读。随后讨论了四种不同的事务隔离等级:读未提交、读已提交、可重复读和串行化,并解释了它们的实现方式和特点。最后,文章重点介绍了MVCC机制在InnoDB引擎中的应用,以实现数据库的可重复读隔离等级。通过MVCC,数据库能够在保证隔离性的同时提高并发读写性能,是一种兼顾性能和数据完整性的重要技术。MVCC通过引入版本或者视图来实现可重复读,避免了读的时候加锁,只有在写的时候才进行加锁,从而提高了系统的性能。核心是通过引入事务ID、隐藏列、undo log、快照读、当前读等基本概念,建立读视图来实现可见性保证。MVCC的多版本控制策略基于undo_log和版本链的乐观控制并发的方式,可以为我们提供更好的性能,本质是通过快照读,完全不加锁而满足隔离性。文章最后提出了思考题,引发读者对MVCC在不同隔离等级下的实现方式和性能提升的思考。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《业务开发算法 50 讲》,新⼈⾸单¥59
《业务开发算法 50 讲》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(5)
- 最新
- 精选
- demnox事务C更新id1会阻塞,因为事务B锁住了id1,只有事务B提交后,事务C才能继续执行2022-08-11归属地:重庆3
- Geek_455ad8“如果不在数组中,说明在仍活跃着的事务范围内,但其中有一些事务虽然不是开始最早的,但是结束的却比活跃数组中的事务早,以至于当前事务开始时,这些事务已经结束,所以也应该是不可见的。” 这句话是不是写错了?难道不应该是可见的么?2022-07-043
- 功夫熊猫git,svn这些工具是不是也拿的mvvc算法2022-08-09归属地:江苏
- peter老师辛苦了,请教几个问题啊: Q1:把 pointer 指向此前数据的 undo_log是谁做的? 讲undo log时,有一句话“所以每次新插入一条数据,除了插入数据本身和申请事务 ID,我们也要记得把 pointer 指向此前数据的 undo_log”,从这句话看,似乎“把 pointer 指向此前数据的 undo_log”是开发人员做的? 请问,这个操作是开发人员做的还是mysql自己做的? Q2:mysql的undo log除了用于事务和MVCC外,是否还有其他用途? Q3:读取加for update,一定会有幻读吗? Q4:读视图部分: A 处于中间部分的第二种情况是“如果不在数组中”: 既然“处于中间部分”,怎么会“不在数组”中呢? (处于中间的部分就要分类讨论了,下面两种情况XXX:我被这部分文字搞糊涂了。) B 事务C会加入到视图数组里面吗?2022-02-26
- Paul Shan请问老师能否举一个例子,事务是不活跃的(不在当前视图事务数组中)但是事务id又是小于高水位大于低水位,多谢!我找到的例子,事务如果不活跃的,必然是在当前事务开启之前已经结束了,也就是处于低水位之前的。而在当前事务开启之后还没提交的都应该在当前视图事务数组中,例如文中最后一个例子事务B,即便到了T6,事务B已经提交,但是依然还在事务数组中。 RC通过MVCC比较好解决,只要把条件简化为trx_id < high_id,也就是可视窗口更大,但是感觉效率没提升多少,但是带来了不可重复读的问题。 MVCC依赖全局唯一而且递增的trx_id,只适用于单机版本,无法在网络环境下实现并发。2022-02-261
收起评论