MVCC和锁的关系是怎样的?

66 阅读2分钟

MVCC(多版本并发控制)与锁并非对立关系,而是协同工作的机制,核心目标是在保证数据一致性的前提下,最大化提升数据库并发性能,二者的关系可从“分工互补”和“协同逻辑”两方面理解:

1. 核心分工:解决不同场景的并发问题

二者针对数据库并发的不同需求明确分工,避免单一机制的局限性:

MVCC:负责优化“读-写”并发

  • 通过保存数据的历史版本(如InnoDB的undo日志),让普通读操作(快照读)无需加锁,直接读取历史版本。
  • 作用是避免“读阻塞写、写阻塞读”,比如多个事务同时读取同一行时,无需等待写事务释放锁。

锁:负责控制“写-写”并发

  • 当多个事务同时修改同一行数据时,MVCC无法解决冲突(可能导致数据覆盖),此时需通过锁(如InnoDB的行级锁)强制互斥。
  • 作用是保证“写操作的原子性和一致性”,比如事务A修改行1时,会锁定行1,事务B需等待A提交/回滚后才能修改该行。

2. 协同逻辑:MVCC依赖锁实现完整功能

MVCC并非独立工作,其核心流程(如版本生成、快照有效性)需要锁的配合:

  • 写操作(INSERT/UPDATE/DELETE)时,先通过锁锁定目标行,再生成新数据版本(写入聚簇索引)和历史版本(写入undo日志);

  • 读操作(普通SELECT)时,无需加锁,直接通过undo日志回溯到事务快照对应的历史版本,实现“无锁读”;

  • 若读操作需要强一致性(如SELECT ... FOR UPDATE),则会放弃MVCC的快照读,直接加锁读取最新版本,此时MVCC与锁协同保证“读写一致性”。

总结

MVCC与锁是“互补协同”的关系:

MVCC通过版本控制优化读并发,减少锁的使用场景; 锁通过互斥控制写并发,解决MVCC无法处理的写冲突; 二者结合,既实现了高并发的“无锁读”,又保证了“写操作的安全性”,是InnoDB等数据库实现事务隔离级别的核心基础。