CLOG以及CSNLOG分别维护事务ID->CommitLog以及事务ID->CommitSeqNoLog的映射关系。由于内存的资源有限,并且系统中可能会有长事务存在,内存中可能无法存放所有的映射关系,此时需要将这些映射写盘成物理文件,所以产生了CLOG(XID->CommitLog Map)、CSNLOG(XID->CommitSeqNoLog Map)文件。CSNLOG以及CLOG均采用了SLRU(simple least recently used,简单最近最少使用)机制来实现文件的读取及刷盘操作。
1) CLOG用于记录事务id的提交状态。openGauss中对于每个事务id使用4个bit位来标识它的状态。CLOG定义代码如下:
#define CLOG_XID_STATUS_IN_PROGRESS 0x00 表示事务未开始或还在运行中(故障场景可能是crash)
#define CLOG_XID_STATUS_COMMITTED 0x01 表示该事务已经提交
#define CLOG_XID_STATUS_ABORTED 0x02 表示该事务已经回滚
#define CLOG_XID_STATUS_SUB_COMMITTED 0x03 表示子事务已经提交而父事务状态未知
CLOG页面的物理组织形式如图5-10所示。
图5-10 CLOG页面的物理组织形式
图5-10标识事务1、4、5还在运行中,事务2已经提交,事务3已经回滚。
2) CSNLOG用于记录事务提交的序列号。openGauss为每个事务id分配8个字节uint64的CSN号,所以一个8kB页面能保存1k个事务的CSN号。CSNLOG达到一定大小后会分块,每个CSNLOG文件块的大小为256kB。同xid号类似,CSN号预留了几个特殊的号。CSNLOG定义代码如下:
#define COMMITSEQNO_INPROGRESS UINT64CONST(0x0) 表示该事务还未提交或回滚
#define COMMITSEQNO_ABORTED UINT64CONST(0x1) 表示该事务已经回滚
#define COMMITSEQNO_FROZEN UINT64CONST(0x2) 表示该事务已提交,且对任何快照可见
#define COMMITSEQNO_FIRST_NORMAL UINT64CONST(0x3) 事务正常的CSN号起始值
#define COMMITSEQNO_COMMIT_INPROGRESS (UINT64CONST(1) << 62) 事务正在提交中
同CLOG相似,CSNLOG的物理结构体如图5-11所示。
图5-11 CSNLOG的物理结构体
事务id 2048、2049、2050、2051、2052、2053的对应的CSN号依次是5、4、7、10、6、8;也就是说事务提交的次序依次是2049->2048->2052->2050->2053->2051。
3) 关键函数
64位xid页面xid_base的计算函数: