2021-04-28 22:45:26
推荐
大家好,我是连边。前一篇文章中,我提到了undo log在MySQL InnoDB存储引擎中的作用,即实现MVCC(多版本并发控制)。今天,我将推荐一篇由田螺撰写的文章,这篇文章非常精彩,我坚信阅读之后,你会有满满的收获。
MVCC实现原理是一道高频率面试题,最近技术讨论群的小伙伴们一直在讨论,让我们一起深入了解。
MVCC的实现原理是数据库面试中的高频问题,技术讨论群的小伙伴们一直在探讨,让我们共同学习。
事务是由一系列有限的数据库操作组成的,这些操作要么全部执行,要么全部不执行。它是一个不可分割的工作单位。比如,当进行一笔转账操作时,如果转账过程中的某个环节出错,为了保证数据的一致性,就需要事务来回滚操作,确保转账操作的完整性。
事务具有四个典型特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
事务并发可能导致脏读、不可重复读、幻读等并发问题。
脏读发生在事务A读取到了事务B未提交的修改数据时。
不可重复读指的是在同一个事务内,前后多次读取同一数据时,返回的数据内容不一致。
幻读发生在事务A查询特定条件的数据时,事务B在此期间插入了符合查询条件的数据,导致事务A再次查询时结果集不同。
为了解决并发事务的并发问题,数据库设计了四种隔离级别,包括读未提交、读已提交、可重复读、串行化(Serializable)。
读未提交隔离级别允许事务读取其他未提交事务的数据,但会存在脏读、不可重复读、幻读问题。
读已提交隔离级别仅允许事务读取已提交的数据,解决了脏读问题,但仍然存在不可重复读和幻读问题。
可重复读隔离级别限制了事务在读取数据时不能修改数据,解决了不可重复读问题,但仍然存在幻读问题。
串行化隔离级别是事务隔离级别的最高级别,所有事务都是顺序执行的,可以避免脏读、不可重复读与幻读的所有并发问题,但性能较低。
通过加锁实现事务隔离性,但频繁加锁降低了数据库性能。为了解决性能问题,MVCC多版本并发控制应运而生。
MVCC(Multi-Version Concurrency Control)是一种并发控制方法,通常在数据库管理系统中实现对数据库的并发访问,在编程语言中实现事务内存。它允许数据库中的多个版本的数据同时存在。在某个事务操作时,通过查看记录的事务版本id,并根据事务隔离级别判断读取哪个版本的数据。
MVCC在读已提交、可重复读隔离级别中实现,提供了一种更高效的方式处理读写冲突,有效提高了数据库并发性能。
事务每次启动时,都会从数据库获取一个自增长的事务ID,用于判断事务的执行顺序。
InnoDB引擎中,每条记录都包含两个隐藏字段:trx_id(事务ID)和roll_pointer(回滚指针),在没有主键或非NULL唯一键的情况下,还可能包含一个row_id字段。
undo log用于记录数据修改前的状态,当事务回滚时,可以通过undo log还原数据。
多个事务并行操作同一行数据时,会产生多个版本。undo log与版本链相互关联,用于表示不同事务对同一行数据的修改。
快照读是指读取记录的可见版本,而当前读则指读取记录的最新版本。
Read View是数据库生成的读取数据的规则,用于判断当前事务可见的数据版本。
InnoDB通过Read View和undo log实现MVCC,undo log保存历史快照,Read View的可见性规则帮助判断当前版本的数据是否可见。
在读已提交隔离级别下,可能存在不可重复读问题。具体流程如下:
通过Read View生成时刻的事务ID和版本链,判断当前事务是否可见数据。在实例分析中,可以看到在不可重复读问题的场景下,事务A和事务B的交互情况。
在可重复读隔离级别下,解决不可重复读问题。通过复用老的Read View副本,确保相同的查询结果一致。
网络传言称MVCC的可重复读隔离级别解决了幻读问题。通过实例分析,发现RR隔离级别在特定场景下仍然存在幻读问题。
MVCC通过多版本并发控制方法,实现高效并发访问,解决事务并发带来的问题,提升数据库性能。通过理解MVCC的关键知识点和隔离级别的实现细节,可以更好地理解和应用MVCC在数据库中的实际应用。