GaussDB基于事务提交时间戳的MVCC和快照机制
GaussDB的UStore存储引擎MVCC使用的是“方式2”,数据文件中只保留最新版本,历史版本被存储于UNDO中,比较适合更新频繁的业务场景。
GaussDB中的快照隔离机制是基于提交时间戳来实现的。GaussDB使用一个全局自增的长整数作为逻辑时间戳,用来模拟数据库内部的时序,该逻辑时间戳被称为提交序列号(commit sequence number,简称CSN)。每当一个事务提交的时候,在提交序列号日志中(commit sequence number log,CSN日志)会记录该事务号xid(事务的全局唯一标识)对应的逻辑时间戳CSN值。
关于MVCC可见性判断
图2 GaussDB快照可见性判断示意图
图2中,棕色竖线表示取snapshot时刻,如果使用活跃事务列表快照方式,那么棕色竖线对应snapshot的集合应该是{2,4,6}。如果采用GaussDB的基于提交时间戳CSN的快照方案,会获取当前的CSN值,也就是3,事务TX2、TX4、TX6、TX7、TX8的CSN分别为4、6、5、7、8,对于该snapshot而言,这几个事务的修改都不可见。
GaussDB MVCC快照可见性的具体判断流程如下:
图3 GaussDB快照根据CSN可见性判断流程图
1)如果当前事务ID 大于数据tuple的 xmax,那么说明此行数据的更新/删除发生于本事务开始之前,此行数据对本事务一定不可见。
2)如果当前事务ID小于数据tuple的xmin,那么说明此行数据的更新/删除发生于本事务开始之后,就需要检索xmin对应的事务状态(Clog,即Commit Log)来读取此事务状态,以此来判断此行数据是否对当前事务可见。如果tuple的xmin对应的事务是已提交的,则tuple对当前事务是可见的;如果tuple的xmin对应的事务已被回滚了,则tuple对当前事务是不可见的。
3)如果xid落在了xmin、xmax中间,就需要依据CSN 来判断本事务的快照下对应数据的可见性(通过检索CSN Log来进行对比判断)。
如果读取的xid对应的CSN已提交,并且CSN < snapshot.CSN,那么数据对当前事务是可见的。
如果CSN > snapshot.CSN,或者事务尚未提交,那么数据对当前事务是不可见的。
相对于事务活跃列表方式的快照,GaussDB基于提交时间戳CSN方式的快照具有如下优点:
通过CSN提交序列号进行可见性判断,无需遍历活跃事务列表。
无锁化原子操作提供CSN序列号,锁等待少。
节点间事务交互仅需要一个CSN,网络开销跟事务规模无关。