openGauss源码解析(84)

openGauss源码解析:事务机制源码解析(15)

4. CLOG Partition优化

CLOG日志即是事务提交日志(详情可参考章节“5.2.2 事务ID分配及CLOG/CSNLOG)”,每个事务存在4种状态:IN_PROGRESS、COMMITED、ABORTED、SUB_COMMITED,每条日志占2 bit。CLOG日志需要存储在磁盘上,一个页面(8kB)可以包含215条,每个日志文件(段=256 x 8k)226条。当前CLOG的访问通过缓冲池实现,代码中使用统一的SLRU缓冲池算法。

图5-22 CLOG的日志缓冲池优化前

图5-23 CLOG的日志缓冲池优化后

如图5-22所示,CLOG的日志缓冲池在共享内存中且全局唯一,名称为名称为“CLOG Ctl”,为各工作线程共享该资源。在高并发的场景下,该资源的竞争成为性能瓶颈,优化分区后如图5-23。按页面号进行取模运算(求两个数相除的余数)将日志均分到多个共享内存的缓冲池中,由线程局部对象的数组ClogCtlData来记录,名称为“CLOG Ctl i”,同步增加共享内存中的缓冲池对象及对应的全局锁。也就是通过打散的方式提高整体吞吐。

CLOG分区优化需要将源代码中涉及原缓冲池的操作进行修改,改为操作对应的分区的缓冲池,而通过事务id、页面号能方便地找到对应的分区,与此同时对应的控制锁也从原来的一把锁改为多把锁的操作,涉及的结构体代码如下,涉及的函数如表5-8所示:

/* CLOG分区*/

#define NUM_CLOG_PARTITIONS 256 /*分区打散的个数*/

/* CLOG轻量级分区锁*/

#define CBufHashPartition(hashcode) \

((hashcode) % NUM_CLOG_PARTITIONS)

#define CBufMappingPartitionLock(hashcode) \

(&t_thrd.shemem_ptr_cxt.mainLWLockArray[FirstCBufMappingLock + CBufHashPartition(hashcode)].lock)

#define CBufMappingPartitionLockByIndex(i) \

(&t_thrd.shemem_ptr_cxt.mainLWLockArray[FirstCBufMappingLock + i].lock)

表5-8 CLOG分区优化函数

函数名

简述

CLOGShmemInit

调用SimpleLruInit 初始化共享内存中的CLOG缓冲区

ZeroCLOGPage

CLOG日志页面的初始化为0

BootStrapCLOG

创建数据库时,在缓冲区中创建初始可用的CLOG日志页面,并调用 ZeroCLOGPage初始化页面为0,写回到磁盘,并返回页面

CLogSetTreeStatus

设置事务提交的最终状态

CLogGetStatus

查询事务状态

ShutdownCLOG

关闭缓冲区,刷新到磁盘中

ExtendCLOG

为新分配的事务,创建CLOG页面

TruncateCLOG

日志检查点的建立使得部分事务的日志过期,可删除以节省空间

WriteZeroPageXlogRec

新建XLOG页面时,写“CLOG_ZEROPAGE” XLOG日志,以便将来恢复使用

clog_redo

CLOG日志相关的 redo 操作,含CLOG_ZEROPAGE及CLOG_TRUNCATE

posted @ 2024-04-30 10:09  openGauss-bot  阅读(16)  评论(0编辑  收藏  举报