学习目的
openGauss
openGauss 数据库中 Commit Sequence Number 简称 CSN,使用一个全局自增的长整数作为逻辑的时间戳,模拟数据库内部的时序,该逻辑时间戳被称为提交顺序号。每当一个事务提交的时候,在提交序列号日志中(CSN LOG)会记录该事务号 XID(事务的全局唯-标识)对应的逻辑时间戳(CSN 值)。 CSN 日志中记录的 XID 值与 CSN 值的对应关系,即决定了所有事务的状态函数 在一个事务的实际执行过程中,并不会在开始就加载全部的 CSN 日志,而是在扫描到某条记录以后,才会去 CSN 日志中查询该条记录头部 xmin 和 xmax 这两个事务号对应的 CSN 值,并基于此进行可见性判断。称为基于逻辑提交时间戳的可见性判断。是对 PG 中可见性判断时查询活跃事务组的改进
PostgreSQL
PG 在获取查询快照时需要获取活跃事务列表,openGauss 虽然不用获取活跃事务列表,但在读取 tuple 后需要查询 XMIN,XMAX 对应的 CSN。哪种方式更高效个人还没有搞清楚,可能 openGauss 在高并发的事务处理时更有优势,因为 OLTP 环境中活跃事务较多,并且多数基于索引的查询,需要 XMIN,XMAX 转 CSN 的记录很少。
openGauss CSN原理简单如图

说明
每个非只读事务在运行过程中会取得一个xid号,在事务提交时会推进CSN,同时会将当前CSN与事务的xid映射关系保存起来(CSNLOG) 实心竖线标识取snapshot(快照)时刻,会获取最新提交CSN(3)的下一个值4。 TX1、TX3、TX5已经提交,对应的CSN号分别是1、2、3。 TX2、TX4、TX6正在运行, TX7、TX8是未来还未开启的事务。 对于当前snapshot而言,严格小于CSN号4的事务提交结果均可见 其余事务提交结果在获取快照时刻还未提交,不可见。
MVCC快照可见性判断的流程
获取快照时记录当前活跃的最小的xid,记为snapshot.xmin。当前最新提交的“事务id(latestCompleteXid) + 1”,记为snapshot.xmax。当前最新提交的“CSN号 + 1”(NextCommitSeqNo),记为snapshot.csn。

• xid大于等于snapshot.xmax时,该事务id不可见。
• xid比snapshot.xmin小时,说明该事务id在本次事务启动以前已经结束,需要去CLOG查询事务的提交状态,并在元组头上设置相应的标记位。
• xid处于snapshot.xmin和snapshot.xmax之间时,需要从CSN-XID映射中读取事务结束的CSN;如果CSN有值且比snapshot.csn小,表示该事务可见,否则不可见。
提交流程

流程解释
1. 设置CSN-XID映射commit-in-progress标记。
2. 原子更新NextCommitSeqNo值。
3. 生成redo日志,写CLOG,写CSNLOG。
4. 更新PGPROC将对应的事务信息从PGPROC中移除,xid设置为InvalidTransactionId、xmin设置为InvalidTransactionId等。




