面试知识库

隔离级别 → MVCC → 间隙锁 → 死锁 追问链#

追问路径#

涉及知识点#

核心串联逻辑#

  1. 隔离级别递进:RU→RC→RR→Serializable,依次解决脏读、不可重复读、幻读,隔离性越强并发越低
  2. RR双机制:快照读用MVCC(ReadView+版本链)实现可重复读;当前读用Next-Key Lock锁范围防幻读
  3. MVCC可见性:ReadView记录生成时的活跃事务列表,沿undo log版本链找第一个对当前事务可见的版本(RC每次select生成新ReadView,RR只在首次)
  4. 锁加在索引上:未命中索引→表锁,这是锁等待和死锁的高发点;RC无间隙锁并发高但幻读,RR有间隙锁一致性强但易死锁
  5. 死锁治理:InnoDB自动检测回滚,根治靠固定加锁顺序+缩小事务+走索引
  6. 代码示例
    -- 排查最近一次死锁
    SHOW ENGINE INNODB STATUS\G   -- 看 LATEST DETECTED DEADLOCK 段
    
    -- 当前读会加Next-Key Lock,RR下锁住(10,20]区间防插入
    SELECT * FROM t WHERE id > 10 AND id <= 20 FOR UPDATE;
    sql

面试回答串联#

30秒速答#

“MySQL四个隔离级别RU/RC/RR/Serializable,InnoDB默认RR。RR靠MVCC的快照读避免不可重复读、靠间隙锁的当前读避免幻读。MVCC用每行的trx_id和undo log版本链加ReadView判断可见性。行锁加在索引上,没走索引会退化表锁。死锁是交叉持锁等待,InnoDB自动检测回滚,根治靠固定加锁顺序和缩小事务范围。“

2分钟展开答#

“MySQL有四个隔离级别:读未提交有脏读,读已提交解决脏读但有不可重复读,可重复读是InnoDB默认级别解决了不可重复读,串行化解决幻读但性能最差。InnoDB的RR靠两套机制:普通select是快照读走MVCC,update和select for update是当前读走加锁。MVCC的实现是每行有隐藏的trx_id和roll_pointer,历史版本通过undo log串成版本链,事务开启时生成ReadView记录当时活跃的事务列表,读的时候沿版本链找第一个对自己可见的版本——RC是每次select都生成新ReadView所以能读到别人已提交的,RR只在第一次select生成所以可重复读。RR下幻读的防范:快照读天然不会幻读,当前读靠间隙锁和Next-Key Lock锁住记录之间的空隙防止其他事务插入。这里关键点是行锁其实加在索引上,如果查询没命中索引会退化成锁全表,这是锁等待和死锁的常见根因。RC和RR的加锁区别在于RC没有间隙锁只锁命中行、并发高但有幻读,RR用Next-Key锁范围、一致性强但更容易死锁。死锁是两个事务交叉持有并互相等待对方的锁,InnoDB有死锁检测会自动回滚代价小的那个事务。线上定位用show engine innodb status看最近一次死锁详情,或者开innodb_print_all_deadlocks记到错误日志。根治上我会固定加锁顺序、尽量缩小事务范围、确保走索引避免锁升级、热点行用乐观锁。“

相关追问链#