在看MVCC之前我们先补充些基础内容,首先来看下事务的ACID和数据的总体运行流程
数据库整体的使用流程:
ACID流程图
mysql核心日志:
在MySQL数据库中有三个非常重要的日志binlog,undolog,redolog.
mvcc概念介绍:
MVCC(Multi-Version Concurrency Control):多版本并发控制,是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。 MVCC 在 MySQL InnoDB 中的实现主要是为了提高数据库并发性能,用更好的方式去处理读-写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读。
当前读和快照读的概念:
当前读(Current Read)指的是读取数据当前最新数据。这种读取方式需要保证其他并发事务不能修改当前记录,因此会对读取的记录进行加锁。在执行当前读操作时,用户可以访问数据库中最新的数据状态,包括最近提交的事务所做的修改。这种读取方式具有实时数据可见性,因为它读取的是已提交的最新数据。加锁的SELECT操作,或者对数据进行增删改都会进行当前读。
快照读(Snapshot Read)则是指在读取数据时,生成读取快照,并在同一个事务中可能会一直读取此快照的数据。快照读读到的数据可能不是最新的,而是历史版本的数据。这些历史版本的数据可以从undo log中获取。在事务中的SELECT不加锁的情况下,会执行快照读。快照读依赖readview来实现。需要注意的是,快照读的前提是隔离级别不是串行级别,因为在串行级别下的快照读会退化成当前读。
总的来说,当前读和快照读的主要区别在于它们读取数据的方式和时间点。当前读总是读取最新的已提交数据,而快照读则可能读取历史版本的数据。这两种读取方式在数据库操作中各有其应用场景和优势。
他们相互之间的联系:
- MVCC与快照读:
- 快照读是MVCC的一个实现方式。当执行快照读时,数据库会提供一个数据的一致性快照,而不是当前最新的数据。这个快照是基于某个时间点的数据版本,可能不是最新的。
- 由于快照读是基于多版本的,因此它不需要对读取的数据加锁,从而实现了非阻塞的读取操作。
- 在MySQL的InnoDB存储引擎中,快照读是通过
read view
机制来实现的。read view
记录了某个时间点的系统活跃事务列表,并根据这个列表来判断哪些数据版本对当前事务是可见的。- MVCC与当前读:
- 当前读是读取数据的最新版本,并且在读取时会加锁,以确保其他并发事务不能修改当前记录。
- 在MVCC的上下文中,当前读会读取最新的数据版本,这个版本是与当前事务ID相关联的。
- 当前读通常发生在执行
SELECT ... FOR UPDATE
、UPDATE
、DELETE
等操作时,这些操作需要确保读取的数据在事务处理期间不会被其他事务修改。
代码实例:
1.创建表
CREATE TABLE example (
id INT PRIMARY KEY,
value INT
);
INSERT INTO example (id, value) VALUES (1, 100);
INSERT INTO example (id, value) VALUES (2, 200);
事务A(当前读):
START TRANSACTION;
SELECT * FROM example WHERE id = 1 FOR UPDATE; -- 当前读,会加锁
事务B(快照读):
START TRANSACTION;
SELECT * FROM example WHERE id = 1; -- 快照读,不会加锁,读取的是事务开始时的数据版本
事务A修改数据:
UPDATE example SET value = 150 WHERE id = 1; -- 事务A修改数据
事务B修改数据:
START TRANSACTION;
SELECT * FROM example WHERE id = 1 FOR UPDATE; -- 事务B的当前读
好了 本篇文章就到这里 在这里我向大家推荐一个性价比很高课程:
https://xxetb.xetslk.com/s/2PjJ3T