mysql如何解决的幻读?

MySQL中InnoDB存储引擎通过以下方式解决幻读问题:

  1. 多版本并发控制(MVCC)

    • 在可重复读(Repeatable Read,RR)隔离级别下,MySQL的InnoDB存储引擎使用了多版本并发控制机制。在事务执行过程中,事务看到的是在其启动时刻的数据视图,即快照,而不是最新的数据。这意味着即使其他事务在事务执行期间插入了符合当前事务查询条件的新行,当前事务也不会看到这些新插入的行,从而避免了幻读现象。
  2. Next-Key Locks

    • 除了普通的行锁之外,InnoDB在RR隔离级别下对范围查询还采用了Next-Key Locks(即行锁加上间隙锁)。当一个事务对索引区间进行扫描时,不仅会对扫描到的行记录加锁,还会对扫描区间内的间隙加锁,这样就可以阻止其他事务在这个区间内插入新的行,确保即使事务重新执行相同的查询也不会看到新的行,即不会产生幻读。

MySQL的InnoDB引擎在RR隔离级别下有效地解决了幻读问题。而在读已提交(Read Committed)隔离级别下,每次查询都会获取最新的数据视图,因此不一定能完全避免幻读,但在可重复读级别下是可以保证的。

什么是MVCC

MVCC(Multi-Version Concurrency Control)即多版本并发控制,是一种数据库管理系统中广泛采用的并发控制技术,尤其在现代关系型数据库如MySQL的InnoDB存储引擎中得到了广泛应用。MVCC通过为数据库的每一行数据保存多个版本来实现并发控制,允许多个事务在同一时刻看到数据的不同版本,从而避免了在读写操作中对数据加锁造成的阻塞,提高了数据库的并发性能。

在MVCC机制下,每个事务看到的数据视图是一个快照,这个快照是在事务开始时根据一定的规则创建的。当事务进行读操作时,它只会读取到在事务开始前就已经提交的更改,或者事务自身所做的更改,而对于其他事务在此之后提交的更改则是不可见的。

MVCC的实现通常依赖于以下技术:

  1. 数据版本标识:每行数据除了当前的有效值外,还会存储创建版本号(例如事务ID)和删除版本号(如果已被删除的话),以此来区分各个版本的数据。

  2. 快照读与当前读:MVCC区分了快照读(Snapshot Read)和当前读(Current Read)。快照读不加锁,只读取历史版本数据,适用于大多数SELECT操作;而当前读会加锁,确保读取的是最新版本的数据,如SELECT…FOR UPDATE或SELECT…LOCK IN SHARE MODE。

  3. 回收旧版本:MVCC还需要一个机制来回收不再需要的历史版本数据,以避免无限增长的空间占用。

通过这些机制,MVCC能够在一定程度上缓解并发读写时的冲突,并提高数据库的并发性能,特别是在读取密集型的应用场景中表现尤为出色。然而,它并非完美无缺,也可能带来额外的存储开销和复杂性,以及对长时间运行事务的影响。

mvcc采用的是什么日志文件?

MVCC(多版本并发控制)在数据库中实现时,通常依赖于事务日志,尤其是用于回滚和生成历史版本数据的日志文件。在MySQL的InnoDB存储引擎中,MVCC主要依靠的是回滚日志(Undo Log)

回滚日志记录了事务修改数据之前的老版本信息,当事务回滚时,可以根据回滚日志恢复到事务开始前的状态,同时,其他事务在执行查询时,如果是在可重复读(Repeatable Read)隔离级别下,可以通过读取回滚日志中的历史版本数据来实现“快照读”,从而避免了与其他事务的写操作冲突,这就是MVCC的核心工作机制之一。

另外,MVCC并不是独立于其他日志系统存在的,InnoDB还使用了重做日志(Redo Log)来保证事务的持久性和崩溃恢复,以及用于主从复制的二进制日志(Binlog)。但这二者在实现MVCC特性的直接作用上不如回滚日志那么关键。

最后编辑: kuteng  文档更新时间: 2024-04-02 09:53   作者:kuteng