多版本并发控制 (MVCC) 是一种数据库优化技术。MVCC 创建记录的重复副本,以便可以同时安全地读取和更新数据。
通过 MVCC,数据库读写不会互相阻塞,大大增强了用户体验。
MVCC 有什么好处?
如果 DBMS 正确实现多版本并发控制,则可以提供以下好处:
- 提高读取访问性能;
- 减少对数据库锁的需求;
- 更少的数据库访问争用问题;
- 持续的记录隔离以进行写操作;以及
- 减少数据库死锁的数量。
MVCC 数据库如何工作?
虽然 DBMS 供应商可以自由地以自己的方式实现 MVCC,但多版本并发控制通常的工作方式如下:
- 每个数据库记录都有一个版本号。
- 并发读取针对具有最高版本号的记录进行。
- 写操作针对记录的副本进行操作,而不是记录本身。
- 在副本更新的同时,用户继续阅读旧版本。
- 写入操作成功后,版本id会增加。
- 后续并发读取使用更新后的版本。
- 当出现新的更新时,将再次创建新版本,并继续此循环。
MVCC 和锁定有什么区别?
与传统的 DMBS 不同,多版本并发控制不会在即将发生写入操作时锁定记录。而是会创建记录的新版本(版本号增加)。
在对新记录进行过渡编辑和更新的同时,用户可以继续阅读旧版本的记录。这样就无需锁定,也不存在争用和死锁问题。
当记录的新版本提交到数据库时,所有未来的读取操作都将在更新的版本上进行。新的写入操作将再次创建新版本,然后循环继续。
多版本并发控制(MVCC)有哪些缺点?
虽然 MVCC 提供了许多好处,但多版本并发控制也存在两个主要缺点:
- 并发更新控制方法难以实现。
- 数据库的大小不断增大,并因 DBMS 记录的多个版本而变得臃肿。
对于用户甚至开发人员来说,实现 MVCC 并发控制方法的复杂性是完全隐藏的,因为该功能是由数据库供应商提供的。
开发人员可以编写 SQL,最终用户可以正常使用应用程序。DBMS 在后台使用多版本并发控制这一事实对他们来说是完全透明的。
PostgreSQL MVCC 多版本并发控制
每个供应商都有自己的策略来尽量减少 MVCC 的主要缺点:考虑到可能创建的记录版本数量,数据库的大小会不断扩大。
为了处理版本膨胀,PostgreSQL MVCC 数据库使用一个巧妙命名的进程 VACCUM 来识别和删除由多版本并发控制进程创建的重复和不需要的记录。
解决 MVCC 数据库空间超出问题
PostgreSQL MVCC VACCUM 进程解决了版本膨胀问题,但它在运行时会占用大量资源,并且在检查数据库中每个记录的状态时会导致自身的锁定。
尽管这可能会消耗额外的资源,但 RDBMS 管理员不应关闭 PostgreSQL MVCC VACCUM 进程。否则,系统最终将生成 MVCC 数据库空间超出错误,管理员需要将数据库脱机才能解决该问题。