You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

InnoDB实现MVCC时如何规避一致读原子性问题与读写冲突?

InnoDB MVCC 并发读写冲突规避机制解答

你提到的并发场景在InnoDB实际实现中并不会发生,核心是InnoDB通过内存页闩锁(latch)、严格的修改顺序设计两层机制规避了这类问题:

  • 第一层保护是页级闩锁,这是专门用来保护内存中数据页结构的轻量锁,和事务级别的表锁、行锁完全不同,持有时间仅持续到页内操作完成,开销极低:

    • 读操作读取tuple的完整流程(包括读取trx_id、undo指针、所有字段值、判断可见性)全程持有对应页的共享S闩锁,持有期间其他线程无法拿到该页的排他X闩锁修改页内数据
    • 写操作修改tuple的完整流程(写入undo日志、更新undo指针、修改字段值、更新trx_id)全程持有对应页的排他X闩锁,持有期间其他线程无法拿到该页的S闩锁读取页内数据
      这就从根本上避免了你描述的「读操作读了trx_id之后,写操作中途插入修改数据」的情况,要么读操作先完成全量读取返回正确值,要么写操作先完成全量修改,读操作后续读取时根据trx_id判断可见性,未提交就顺着undo指针读取历史版本,绝不会读到半修改的脏数据。
  • 第二层是修改顺序的兜底设计,即便不考虑闩锁,InnoDB修改tuple的顺序也严格遵循写入undo -> 更新undo指针 -> 修改字段值 -> 更新trx_id的顺序,trx_id是最后修改的元数据。读操作优先读取trx_id,如果trx_id还是旧值,说明所有修改都未生效,读到的所有字段都是旧值;如果trx_id已经更新为新事务ID,说明所有字段修改都已经完成,此时再判断可见性,也不会出现半新半旧的异常结果。

另外你提到的非原子字节拷贝的问题也被闩锁完全覆盖,不管修改的字段长度是多少,读写操作在闩锁的保护下是串行执行的,不会出现读一半被修改的情况。

内容的提问来源于stack exchange,提问作者Zeng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 06:12:03