简介

与Postgres 数据库类似,Opengauss在事务模块也引入CLOG日志即事务提交日志,基础知识见postgres 源码解析9 CLOG管理器–1。在Opengauss 中每个事务存在四种状态:CLOG_XID_STATUS_IN_PROGRESS、 CLOG_XID_STATUS_COMMITTED、 CLOG_XID_STATUS_ABORTED 和 CLOG_XID_STATUS_SUB_COMMITTED。每条日志占2 bit. 由于内存资源有限,且系统中可能会有长事务的存在,内存中可能无法存放所有的事务状态信息,因此产生CLOG日志子模块,每个CLOG页面默认8KB(页面组织形式如下),一个页面能存放2^15条,每个段文件包含256个页面。对CLOG日志的访问是通过缓冲池实现,采用SLRU算法。
在这里插入图片描述

2 CLOG SLRU的实现
CLOG日志缓冲区在共享内存中全局唯一, 为各工作线程共享该资源。高并发场景下,该资源的竞争会成为性能瓶颈,优化分区后如下图。以CLOG页面为key,将CLOG日志页均分至缓冲池对应的分区中,由线程局部对象的数组ClogCtlData来表示,名称为CLogCtl。同步增加共享内存中的缓冲池对象和对应的全局锁,即通过将全局锁分散成多个分区锁进而提升整体吞吐性能。
在这里插入图片描述

CLOG 全局控制锁的分区裁剪优化实现

CLOG分区优化将源代码中涉及原缓冲池的操作适应性的修改,对CLOG对应的缓冲区裁剪分成若干个分区,通过事务ID所在的页面号快速找到对应分区,与此同时,将原全局控制锁从原来的一把锁分成多把锁,涉及的结构体代码如下:

/* Clog partitions */
#define NUM_CLOG_PARTITIONS 256    //CLOG分区数

CLOG轻量级分区锁

/* CLog lwlock partition*/
#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)

在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐