多版本并发控制(MVCC,Multi-Version Concurrency Control)这一概念作为严格锁定的替代方案而产生,目的是为了支持大量事务的并发处理。这对于减少数据访问时的冲突和锁定非常重要,尤其是在在线事务处理(OLTP)系统中。
传统的锁定方法(例如,行级锁定)在高竞争情况下可能导致应用程序的延迟。MVCC的任务是允许事务读取一致的数据快照,即使在进行写入操作期间,从而确保隔离和并发访问。
MVCC在流行的数据库管理系统(PostgreSQL、Oracle、MySQL/InnoDB)中通过存储行版本历史来实现。在读取时,每个事务只能看到在其启动之前已提交的行,而插入/更新操作则创建新版本的行,而不立即删除它们。
示例查询(PostgreSQL):
BEGIN TRANSACTION; SELECT * FROM orders WHERE status = 'processing'; UPDATE orders SET status = 'completed' WHERE id = 42; COMMIT;
在事务未完成时,其他用户将看到行的先前版本,只有在提交后更改才会对新事务可用。
关键特点:
MVCC能否完全消除所有类型的锁定和冲突?
不能,MVCC仍然可能会在同时更新相同的行时产生冲突——例如,在同时进行UPDATE时会产生提交冲突(写-写冲突),数据库管理系统将抛出错误或回滚其中一个事务。
MVCC中旧版本行何时被删除,这可能导致内存泄露吗?
在大多数数据库管理系统中,旧版本的行由专门的进程删除(PostgreSQL中的VACUUM)。如果不运行这些进程,数据库“膨胀”,性能下降。
在MVCC的条件下,“select for update”是否正常工作,为什么需要锁定?
是的,SELECT FOR UPDATE查询会锁定行以排除并发更改时的冲突,否则可能会出现“丢失更新”。
示例:
BEGIN; SELECT * FROM products WHERE id = 123 FOR UPDATE; UPDATE products SET quantity = quantity - 1 WHERE id = 123; COMMIT;
一家大型网络商店实现了频繁更新订单的方案,但没有配置VACUUM。一个月后,数据库膨胀了十倍,查询速度大幅下降。
优点:
缺点:
实现了定期的自动垃圾回收,采用了写冲突控制,对于关键查询使用REPEATABLE READ级别的隔离。
优点:
缺点: