Multi-Version Concurrency Control
多版本并发控制(MVCC)是一个比并发控制协议更大的概念,它类似于 git 这种版本控制思想。它设计到了 DBMS 设计和实现的方方面面。在 DBMS 中,MVCC 是一种很广泛被使用的。在过去十年里,它几乎被每个数据库所采纳,即使一些不支持多语句事务的系统(NoSQL)也会用它。
对于一个单独的逻辑对象,DMBS 会维护其多个物理版本。
当一个事务对一个对象写时,DBMS 会创建一个新的对于此对象的版本。
当一个事务读一个对象时,它会读取对象的最新版本当事务启动时。
Key Properties
Writers don’t block the readers.
Readers don’t block the writers.
只读事务可以不需要获取锁来读取一致性快照。时间戳来决定可见性。
多版本 DBMS 会支持 time-travel query,这种查询可以读取特定时间点的快照。
四个重要的 MVCC 设计决定:
Concurrency Control Protocol (T/O, OCC, 2PL, etc).
Version Storage
Garbage collection
Index Management
Version Storage
这是 DBMS 如何存储一个逻辑对象的不同物理版本的。
DBMS 将会使用元组的指针字段来创建对于每个逻辑对象的 版本链。这允许 DBMS 可以发现对于正在运行的事务可见的版本。索引总是指向链表的头部。一个线程遍历链表直到发现对其事务可见的版本。不同的存储策略决定了版本存储哪里或者存些什么。
Approach #1: Append-Only Storage: 新版本被附加在相同的表空间内。
Oldest-To-Newest (O2N): 附加新版本到链的尾部,查找需要遍历真个表。
Newest-To-Oldest (N2O): 链表的头部是新的,查找是快的,但是每次更新都要更新索引。
Approach #2: Time-Travel Storage: 老版本被复制到分离的表中。
Approach #3: Delta Storage: 修改后的属性的原始值被复制到单独的增量记录空间中。
Garbage Collection
DBMS 需要随着时间的推移从数据库中删除可回收的物理版本。
Approach #1: Tuple Level Garbage Collection: 通过直接检查元组来查找旧版本。
Background Vacuuming: 单独的线程定期扫描表并寻找可回收的版本,适用于任何版本存储方案。
Cooperative Cleaning: 工作线程在遍历版本链时识别可回收版本。仅适用于 O2N。
Approach #2: Transaction Level: 每个事务都跟踪自己的读/写集。当事务完成时,垃圾收集器可以使用它来识别要回收的元组。 DBMS 确定由已完成事务创建的所有版本何时不再可见。
Index Management
所有主键 (pkey) 索引始终指向版本链头。 DBMS 必须多久更新一次 pkey 索引取决于系统是否在更新元组时创建新版本。 如果事务更新了 pkey 属性,则将其视为 DELETE 后跟 INSERT。
管理二级索引更复杂:
Approach #1: Logical Pointers: 每个元组使用一个不变的标识符。 需要一个额外的间接层,将逻辑 id 映射到元组的物理位置(主键与元组 ID)。
Approach #2: Physical Pointers: 使用物理地址到版本链头。
最后更新于