读取适合自己的版本
更新不必立刻让所有读者失去旧内容。多版本并发控制保留足够的版本信息,再依据事务的快照和可见性规则,为不同读取选出应当看到的数据状态。
PostgreSQL用这种模型使普通读取不必为看见一致数据而等待写者完成。快照具体覆盖哪一时刻,仍随隔离级别而变:Read Committed通常按语句建立视图,Repeatable Read则维持更稳定的事务视图。
版本不消除写入冲突
两个写者修改同一对象时仍可能等待、冲突或撤销。显式锁也可以与多版本读取共存,因此看到MVCC这一名称,不能推断系统没有锁,或每个事务一定能成功提交。
快照隔离还可能允许跨行读写形成串行化异常。PostgreSQL在Serializable级别增加依赖监测;“读到了完整旧版本”与“全部并发事务可解释成串行顺序”承担不同保证。
旧版本需要安全回收
旧行版本只要还可能被事务看见,就不能随意丢弃;不再需要以后,其空间又应回收,避免更新让存储不断增长。PostgreSQL的VACUUM承担相关清理工作。
普通VACUUM主要把死版本空间标记为可复用,通常不把整张表压缩成最小文件,也不保证空间立即归还操作系统。版本保留、清理开销与长事务的影响,是理解并发收益时必须同时考虑的代价。
参考:[4]