mysql中的MVCC过程中会加锁吗?

这是一个很好的问题,答案是:MVCC本身的核心机制不依赖于锁来实现读写并发,但在实际的数据库实现中,锁仍然是必要的,用于处理“写-写”冲突和数据一致性。

简单来说,可以把 MVCC 和锁看作是互补的两种机制,分别解决不同的问题。下面我分层次详细解释:

1. MVCC 的无锁核心(解决“读-写”冲突)

MVCC的核心思想是避免让读操作和写操作相互阻塞。它通过以下机制实现,整个过程(读历史版本)完全不需要加锁

  • 多版本: 每次修改数据时,并不直接覆盖原有数据,而是创建一个新的数据版本,并标记版本号(如事务ID、时间戳)。
  • 快照读: 每个事务在开始时,会获取一个“一致性视图”或“快照”。在这个事务的生命周期内,所有的读操作都基于这个快照,只读取在该快照之前已提交的数据版本。
  • 版本链: 每一行数据可能有多个版本,通过指针连接成一个链表。读操作根据当前事务的快照信息,沿着版本链找到“可见”的那个旧版本。

结论: 正是因为读操作读取的是历史的、已提交的旧版本,而写操作创建新版本,所以读事务和写事务之间不会相互阻塞,也无需加共享锁或排他锁。这是MVCC最大的优势,极大地提升了数据库的并发读性能。

2. 为什么仍然需要锁?(解决“写-写”冲突和一致性)

虽然读写不冲突,但写操作和写操作之间仍然是冲突的。两个事务不能同时修改同一数据的同一版本。这时就必须引入锁机制。

  • 对当前数据的锁定: 当一个事务要修改(UPDATE/DELETE)某行数据时,它必须先找到这条数据的“当前最新版本”。在修改这个当前版本之前,数据库必须对其加上锁(通常是行级的排他锁,X锁),以防止其他事务同时修改它,造成更新丢失。
  • “当前读”需要锁: 在READ COMMITTEDREPEATABLE READ隔离级别下,有些特殊的读语句被称为“当前读”,它们读取的是数据的最新版本,而不是快照。这通常也需要加锁。
    • SELECT ... FOR UPDATE/ SELECT ... LOCK IN SHARE MODE: 显式加锁。
    • UPDATE/DELETE/INSERT语句: 在执行时,内部会自动对涉及的数据进行“当前读”并加锁。例如,执行UPDATE t SET ... WHERE id=1时,会先对id=1这行数据加X锁,然后修改。

结论: MVCC并不能消除“写-写”冲突。在修改数据时,数据库必须对当前数据版本加锁,以确保数据更新的原子性和一致性。

3. 不同隔离级别下的交互

  • 已提交读(Read Committed)​ 和 可重复读(Repeatable Read)
    • 普通SELECT是“快照读”,不加锁(通过MVCC实现)。
    • 写操作(UPDATE/DELETE)和锁定读是“当前读”,需要加锁
  • 可串行化(Serializable)
    • 为了保证最高级别的隔离,数据库通常会退回到更严格的锁机制。例如,在MySQL InnoDB的Serializable级别下,即使是普通的SELECT也会自动转换为SELECT ... LOCK IN SHARE MODE,从而加共享锁。此时MVCC的“无锁读”优势基本消失,主要靠锁来保证隔离。

4. 不同数据库的具体实现

  • MySQL InnoDB
    • 完美结合了MVCC和行级锁(记录锁、间隙锁、Next-Key Lock)。
    • MVCC解决普通读的并发,行锁解决写并发。间隙锁用于防止幻读。
  • PostgreSQL
    • 使用MVCC和多版本存储,其“写-写”冲突的检测不是通过锁,而是通过一种叫做“元组可见性”和“事务状态”的机制。当两个事务尝试更新同一行时,第一个提交的会成功,第二个提交的会失败(报错:could not serialize access due to concurrent update)。这是通过比较事务ID和行版本号来实现的,而不是阻塞等待锁。但PostgreSQL也有表锁、行锁等机制用于其他场景。

总结对比

操作/场景是否需要锁原因
MVCC 快照读(普通SELECT)不需要读取历史版本,与当前写操作无冲突
当前读/写操作(UPDATE/DELETE/锁定读)需要必须锁定“当前数据”,解决“写-写”冲突,保证数据一致性
事务提交需要(隐式)提交时需要保证修改的原子性和持久性,涉及日志写入等,系统内部有锁或锁存器

核心要点: MVCC是一种“乐观”的并发控制机制,它默认读和写不会冲突,让它们各自工作。而锁是一种“悲观”的机制,它默认冲突会发生,所以先加锁保护。在实际数据库(如InnoDB)中,两者协同工作:MVCC优雅地处理了“读-写”并发,而锁则强有力地保障了“写-写”并发的正确性。


作 者:南烛
链 接:https://www.itnotes.top/archives/915
来 源:IT笔记
文章版权归作者所有,转载请注明出处!


上一篇
下一篇