什么是mvcc,面试的时候怎么说

文章目录

在面试中聊 MVCC(Multi-Version Concurrency Control,多版本并发控制) ,你不能只背定义。面试官想看的是你能不能把"它是怎么工作的"和"为什么它能提高并发"这两件事讲透。

简单一句话概括:MVCC 是一种通过维护数据的多个快照版本,让"读-写"操作不再互相阻塞,从而提升数据库并发性能的机制。


第一部分:底层实现的三大支柱

在面试时,建议按照"数据存哪历史怎么找看哪一条"的逻辑来回答。

1. 隐藏字段(数据在哪)

InnoDB 在表的每一行数据后面,都偷偷加了两个关键的隐藏列:

  • DB_TRX_ID :记录最后一次修改该行的事务 ID
  • DB_ROLL_PTR回滚指针 ,指向该行数据存在 undo log 里的上一个版本。
2. Undo Log 版本链(历史怎么找)

每当你更新一条记录,旧的数据并不会被物理删除,而是被塞进 undo log 里。隐藏字段里的回滚指针会将这些旧版本串联起来,形成一条版本链

3. Read View(看哪一条)

这是 MVCC 的"指挥官"。当你执行 SELECT 时,InnoDB 会生成一个 Read View(读视图),它像一张当前活跃事务的"系统快照",包含:

  • m_ids:当前系统里还没提交的事务 ID 列表。
  • min_trx_idm_ids 里最小的 ID。
  • max_trx_id:系统即将分配给下一个事务的 ID。

第二部分:可见性判断逻辑(核心算法)

这是面试的高潮部分。你需要描述事务是如何顺着"版本链"寻找自己能看的数据的:

  1. 拿起版本链中最新记录的 trx_id
  2. 如果 trx_id < min_trx_id :说明这个版本在你开启查询前就提交了,可见
  3. 如果 trx_id >= max_trx_id :说明这个版本是在你开启查询后才生成的,不可见
  4. 如果在两者之间 :检查 trx_id 是否在 m_ids 列表里。
    • 如果在:说明事务还没提交,不可见
    • 如果不在:说明事务已经提交,可见
  5. 不可见怎么办? 顺着回滚指针去找上一个版本,重复上述判断。

第三部分:面试进阶------RC 与 RR 的区别

这是面试官最喜欢的"陷阱题"。MVCC 是如何实现不同隔离级别的?

  • RC(读已提交) :事务中每一次 SELECT 都会重新生成一个 Read View。所以如果你在两次查询之间有别人提交了,你能看到最新的。
  • RR(可重复读) :事务中只有第一次 SELECT 会生成 Read View,之后整个事务都复用这一个。所以不管别人怎么改,你看到的永远是初恋的样子。

面试话术示例(满分回答)

面试官:讲讲你对 MVCC 的理解。

:MVCC 是 InnoDB 实现"读-写"并发的核心。它的底色是"空间换时间",让读操作不加锁,也就是我们常说的"快照读"。

实现上,它主要靠三样东西:

  1. 隐藏列:存事务 ID 和回滚指针。
  2. Undo Log:形成数据的历史版本链。
  3. Read View:这是一套可见性算法。

核心逻辑就是当一个事务去读数据时,它会生成一个 Read View。然后顺着 Undo Log 的版本链,用自己的 Read View 规则去比对每个版本的事务 ID。

如果是 RC 级别 ,它每次查都生成新视图,所以会发生不可重复读;如果是 RR 级别,它整个事务只在第一次查询时生成视图,从而保证了可重复读,并且在很大程度上避免了幻读。


💡 小贴士

如果面试官问:"MVCC 能完全解决幻读吗?"

你要严谨一点:不能完全解决。 它能解决"快照读"下的幻读,但如果发生了"当前读"(比如执行了 SELECT ... FOR UPDATE),还是需要靠 Next-Key Lock(记录锁+间隙锁) 来封印。

相关推荐
2401_871492852 小时前
SQL如何实现按自定义排序进行分组汇总_ORDERBY与聚合函数
jvm·数据库·python
qq_330037992 小时前
如何清洗SQL输入数据_使用框架内置的ORM处理数据交互
jvm·数据库·python
倔强的石头_2 小时前
kingbase备份与恢复实战(五)—— PITR时间点恢复:恢复到误操作前一分钟(归档WAL)
数据库
小碗羊肉2 小时前
【MySQL | 第四篇】多表查询
数据库
sinat_383437363 小时前
Laravel 8 中实现错误日志与调试日志分离的完整配置指南
jvm·数据库·python
sunshine88511 小时前
财务RPA的深水区应用:超越自动化,迈向智能决策支持
数据库
efir OONA12 小时前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
zhangchaoxies12 小时前
如何在 Go 中安全复制接口指针所指向的值
jvm·数据库·python
陈陈CHENCHEN12 小时前
【数据库】MySQL 8.0.40 至 8.0.44 RPM 方式升级指南
数据库·mysql