MVCC:数据库如何让读写同时发生,却尽量互不阻塞?

TL;DR

MVCC 通过保存多个数据版本,让查询读取符合事务规则的快照,从而减少读写之间的阻塞。本文解释版本可见性、旧版本清理、隔离级别和长事务风险,帮助读者理解现代数据库的并发基础。

MVCC 通过保存多个数据版本,让查询读取符合事务规则的快照,从而减少读写之间的阻塞。本文解释版本可见性、旧版本清理、隔离级别和长事务风险,帮助读者理解现代数据库的并发基础。

MVCC:数据库如何让读写同时发生,却尽量互不阻塞?

数据库要同时服务很多读者和写入者,却不能让每一次查询都排队等锁。MVCC,Multiversion Concurrency Control,多版本并发控制,提供了一种直观的办法:不要让所有人盯着同一份正在被修改的纸,而是让读者看到符合事务规则的某个数据快照。

“多版本”到底是什么

当一行数据被更新时,数据库可以保留旧版本信息,并给新旧版本附带事务可见性标记。一个查询根据自己的快照判断哪些版本可见,因此两个查询可能在同一时刻看到不同但各自一致的结果。

PostgreSQL 文档把 MVCC 描述为一种维护并发一致性的多版本模型:每条 SQL 语句可以看到某个时间点的数据,而不是直接暴露其他事务正在写入的中间状态。读取和写入因此可以减少相互阻塞。

它为什么需要清理

旧版本不是永远有用。等到没有活跃事务再需要它们,数据库就要通过 vacuum 或类似机制回收空间、更新统计信息并维护索引。如果清理跟不上,表会膨胀,查询和写入都可能变慢。

MVCC 也不是完全没有锁。更新同一行仍然需要协调,DDL、唯一约束和更高隔离级别也会引入额外冲突。它提供的是一种减少读写冲突的基础模型,不是“所有并发都免费”。

AI 编程中的实际意义

AI 生成数据库代码时,常常只写出 SQL,却没有说明事务隔离、快照可见性、长事务和清理策略。理解 MVCC 后,开发者会更警惕“查询一直开着不提交”“后台任务持有旧快照”“读到旧数据是否可接受”等问题。

读者应该记住

MVCC 用多个版本换取更好的并发读写体验。它让读者看到一致快照,但也带来了版本清理、空间增长和隔离级别选择等成本。

资料:PostgreSQL:MVCC 简介PostgreSQL 并发控制

KEEP READING