Opengauss CLOG模块分区优化--2(具体实现)
创始人
2025-05-30 10:43:18

上篇讲解了opengauss CLOG模块分区优化原理篇,本文将从源代码实现层面讨论具体实现。原理部分内容见:Opengauss CLOG模块分区优化–1(原理)

优化实现

在这里插入图片描述
1 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)

2 CLOG 轻量级分区锁初始化

    for (id = 0; id < NUM_CLOG_PARTITIONS; id++, lock++) {LWLockInitialize(&lock->lock, LWTRANCHE_CLOG_BUFMAPPING);}

3 CLOG共享内存初始化
与原生的postgres相比,新增每个分区CLOG 共享内存的初始化 ,用分区锁代替之前的全局大锁

void CLOGShmemInit(void)
{int i = 0;int rc = 0;char name[SLRU_MAX_NAME_LENGTH];for (i = 0; i < NUM_CLOG_PARTITIONS; i++) {rc = sprintf_s(name, SLRU_MAX_NAME_LENGTH, "%s%d", "CLOG Ctl", i);securec_check_ss(rc, "\0", "\0");SimpleLruInit(ClogCtl(i),name,LWTRANCHE_CLOG_CTL,CLOGShmemBuffers(),CLOG_LSNS_PER_PAGE,CBufMappingPartitionLockByIndex(i),"pg_clog");}
}

4 CLOG模块的Bootstrap执行逻辑

/** This func must be called ONCE on system install.  It creates* the initial CLOG segment.  (The CLOG directory is assumed to* have been created by initdb, and CLOGShmemInit must have been* called already.)*/
void BootStrapCLOG(void)
{int slotno;int64 pageno;// 引导阶段批量初始化 32个clog页,需要进行写入刷盘操作for (pageno = 0; pageno < CLOG_BATCH_SIZE; pageno++) {(void)LWLockAcquire(ClogCtl(pageno)->shared->control_lock, LW_EXCLUSIVE);slotno = ZeroCLOGPage(pageno, false);SimpleLruWritePage(ClogCtl(pageno), slotno);Assert(!ClogCtl(pageno)->shared->page_dirty[slotno]);LWLockRelease(ClogCtl(pageno)->shared->control_lock);}pageno = TransactionIdToPage(t_thrd.xact_cxt.ShmemVariableCache->nextXid);(void)LWLockAcquire(ClogCtl(pageno)->shared->control_lock, LW_EXCLUSIVE);if (pageno >= CLOG_BATCH_SIZE) {/* Create and zero the first page of the commit log */slotno = ZeroCLOGPage(pageno, false);/* Make sure it's written out */SimpleLruWritePage(ClogCtl(pageno), slotno);Assert(!ClogCtl(pageno)->shared->page_dirty[slotno]);}LWLockRelease(ClogCtl(pageno)->shared->control_lock);
}

5 ShutdownCLOG
该函数的功能负责关闭CLOG缓冲区,并将各个分区的脏数据进行刷盘

/** This must be called ONCE during postmaster or standalone-backend shutdown*/
void ShutdownCLOG(void)
{/* Flush dirty CLOG pages to disk */TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(false);for (int i = 0; i < NUM_CLOG_PARTITIONS; i++) {(void)SimpleLruFlush(ClogCtl(i), false);}TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(false);
}

6 CheckPointCLOG
该函数的功能在检查点期间将各个分区的脏数据进行刷盘

/** Perform a checkpoint --- either during shutdown, or on-the-fly*/
void CheckPointCLOG(void)
{/* Flush dirty CLOG pages to disk */TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);int flush_num = 0;for (int i = 0; i < NUM_CLOG_PARTITIONS; i++) {flush_num += SimpleLruFlush(ClogCtl(i), true);}g_instance.ckpt_cxt_ctl->ckpt_clog_flush_num += flush_num;TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
}

7 ExtendCLOG

/** Make sure that CLOG has room for a newly-allocated XID.** NB: this is called while holding XidGenLock.  We want it to be very fast* most of the time; even when it's not so fast, no actual I/O need happen* unless we're forced to write out a dirty clog or xlog page to make room* in shared memory.*/
void ExtendCLOG(TransactionId newestXact, bool allowXlog)
{int64 pageno;/** No work except at first XID of a page.*/if (TransactionIdToPgIndex(newestXact) != 0 && !TransactionIdEquals(newestXact, FirstNormalTransactionId))return;pageno = TransactionIdToPage(newestXact);(void)LWLockAcquire(ClogCtl(pageno)->shared->control_lock, LW_EXCLUSIVE);/* Zero the page and make an XLOG entry about it */ZeroCLOGPage(pageno, !t_thrd.xlog_cxt.InRecovery);LWLockRelease(ClogCtl(pageno)->shared->control_lock);#endif
}

8 TruncateCLOG


/** Remove all CLOG segments before the one holding the passed transaction ID** Before removing any CLOG data, we must flush XLOG to disk, to ensure* that any recently-emitted HEAP_FREEZE records have reached disk; otherwise* a crash and restart might leave us with some unfrozen tuples referencing* removed CLOG data.  We choose to emit a special TRUNCATE XLOG record too.* Replaying the deletion from XLOG is not critical, since the files could* just as well be removed later, but doing so prevents a long-running hot* standby server from acquiring an unreasonably bloated CLOG directory.** Since CLOG segments hold a large number of transactions, the opportunity to* actually remove a segment is fairly rare, and so it seems best not to do* the XLOG flush unless we have confirmed that there is a removable segment.*/
void TruncateCLOG(TransactionId oldestXact)
{int64 cutoffPage;/** The cutoff point is the start of the segment containing oldestXact. We* pass the *page* containing oldestXact to SimpleLruTruncate.*/cutoffPage = TransactionIdToPage(oldestXact);/* Check to see if there's any files that could be removed */if (!SlruScanDirectory(ClogCtl(cutoffPage), SlruScanDirCbReportPresence, &cutoffPage))return; /* nothing to remove *//* Write XLOG record and flush XLOG to disk */WriteTruncateXlogRec(cutoffPage);/* Now we can remove the old CLOG segment(s) */SimpleLruTruncate(ClogCtl(cutoffPage), cutoffPage);ereport(LOG, (errmsg("Truncate CLOG at xid %lu", oldestXact)));
}

9 clog_redo

/** CLOG resource manager's routines*/
void clog_redo(XLogReaderState* record)
{uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;errno_t rc = EOK;/* Backup blocks are not used in clog records */Assert(!XLogRecHasAnyBlockRefs(record));if (info == CLOG_ZEROPAGE) {int64 pageno;int slotno;rc = memcpy_s(&pageno, sizeof(int64), XLogRecGetData(record), sizeof(int64));securec_check(rc, "", "");(void)LWLockAcquire(ClogCtl(pageno)->shared->control_lock, LW_EXCLUSIVE);slotno = ZeroCLOGPage(pageno, false);SimpleLruWritePage(ClogCtl(pageno), slotno);Assert(!ClogCtl(pageno)->shared->page_dirty[slotno]);LWLockRelease(ClogCtl(pageno)->shared->control_lock);} else if (info == CLOG_TRUNCATE) {int64 pageno;rc = memcpy_s(&pageno, sizeof(int64), XLogRecGetData(record), sizeof(int64));securec_check(rc, "", "");/** During XLOG replay, latest_page_number isn't set up yet; insert a* suitable value to bypass the sanity test in SimpleLruTruncate.*/ClogCtl(pageno)->shared->latest_page_number = pageno;SimpleLruTruncate(ClogCtl(pageno), pageno);} elseereport(PANIC, (errmsg("clog_redo: unknown op code %u", (uint32)info)));
}

10 WriteTruncateXlogRec


/** Write a TRUNCATE xlog record** We must flush the xlog record to disk before returning --- see notes* in TruncateCLOG().*/
static void WriteTruncateXlogRec(int64 pageno)
{XLogRecPtr recptr;XLogBeginInsert();XLogRegisterData((char*)(&pageno), sizeof(int64));recptr = XLogInsert(RM_CLOG_ID, CLOG_TRUNCATE);XLogFlush(recptr);
}

相关内容

热门资讯

【入门5 字符串】P1125 ... [NOIP2008 提高组] 笨小猴 题目描述 笨小猴的词汇量很小,所以每次做英语选择...
运动会稿件200字,运动会演讲... 运动会稿件200字目录运动会稿件200字运动会演讲稿200字关于运动会的作文200字运动会通讯稿20...
现代圣达菲报价及图片(现代圣达... 今天给各位分享现代圣达菲报价及图片的知识,其中也会对现代圣达菲2014款图片进行解释,如果能碰巧解决...
一团什么什么 极速百科网 极速... 一团什么什么目录一团什么什么一团什么什么一团花瓣是什么成语一团什么成语一团什么什么 1. 一团...
火影忍者鸣人在第几集九尾化过,... 火影忍者鸣人在第几集九尾化过目录火影忍者鸣人在第几集九尾化过谁告诉我火影里鸣人变身九尾 都有哪几集鸣...
nmap——一种用于查看目标主... 正如标题所言,nmap(network mapper)是一...
SpringCloud微服务技... SpringCloud微服务技术栈.黑马跟学 五今日目标1.初识elasticsearch1.1.了...
2023官方发布最新Sprin... 文章目录1、SpringMVC概述1.1 SpringMVC概念1.2 SpringMVC原理1.3...
6.深入理解类 目录 6.1 类成员 6.2 成员修饰符的顺序 6.3 实例类成员  6.4 静态字段  6.5 ...
rdquo 云 ldquo 字... rdquo 云 ldquo 字加偏旁变成什么字目录rdquo 云 ldquo 字加偏旁变成什么字云字...
又双叒叕念什么啥意思 极速百科... 又双叒叕念什么啥意思目录又双叒叕念什么啥意思又双叒叕念什么啥意思又双叒叕念什么?啥意思?“又双叒叕”...
早安心向阳光正能量的句子,早安... 早安心向阳光正能量的句子目录早安心向阳光正能量的句子早安发圈吸引人的句子正能量早安语录正能量的句子有...
真心话关于爱情 极速百科网 极... 真心话关于爱情目录真心话关于爱情真心话关于爱情关于爱情最感动的真心话有那些?爱情的真心话问题大全真心...
windows下使用gitea... windows下使用gitea搭建git服务器 详细过程 1、简述 使用过好几个git服务器...
区块链安全:闪电贷 Flash... 闪电贷主要用于 DeFi 中,在介绍闪电贷之前先介绍一下 CeFi 的模式。 CeFi...
怎么简单的区分方向盘打几圈,怎... 怎么简单的区分方向盘打几圈目录怎么简单的区分方向盘打几圈怎样判断打方向盘的圈数学开车当别人把方向盘打...
天道经典语录,天道100句经典... 天道经典语录目录天道经典语录天道100句经典语录《天道》里王志文的一段词求全王志文在天道中的经典台词...
ce能修改网络游戏吗,ce可以... ce能修改网络游戏吗目录ce能修改网络游戏吗ce可以修改私服传奇吗一般的网页游戏 能用CE修改吗?有...
带雨字的成语,带雨的四字成语有... 带雨字的成语目录带雨字的成语带雨的四字成语有哪些带雨的四字词语有哪些?与雨有关的成语带雨字的成语 ...
IP 报文 IP报文 IP(Internet Protocol)报文是TCP/IP协...
一行 MD5 居然让小伙伴都回... 1. 前言 大家好,当你点开这篇文章的时候也许心想是哪个 XX 小编混到这里,先不要着急扔臭鸡蛋,本...
Baumer工业相机堡盟相机如... 项目场景 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场...
心动是什么感觉 极速百科网 极... 心动是什么感觉目录心动是什么感觉心动是什么感觉心动是什么样的感觉呢?心动是什么感觉?心动是什么感觉 ...
黄河全长大约多少千米,黄河全长... 黄河全长大约多少千米目录黄河全长大约多少千米黄河全长多少米黄河全长多少千米黄河全长大约多少千米 ...
kb是指什么,kb是什么意思 ... kb是指什么目录kb是指什么kb是什么意思kb什么意思kb什么意思?什么单词缩写?kb是指什么 ...
点头什么的四字词语,四字成语点... 点头什么的四字词语目录点头什么的四字词语四字成语点头什么四字成语 点头什么???形容点头的成语有哪些...
2023年半导体行业研究报告 第一章 行业概况 半导体是一种电子材料,可以控制电流的流动。半导体材料的特性是在它们的...
代理怎么做,如何做代理 极速百... 代理怎么做目录代理怎么做如何做代理做代理怎么做?酒店第三方代理怎么做代理怎么做 1. 确定代理...
怎样灭苍蝇最有效的方法,灭苍蝇... 怎样灭苍蝇最有效的方法目录怎样灭苍蝇最有效的方法灭苍蝇最有效的方法 灭苍蝇最有效3种方法如何做到有效...
【Java (一:12-2) ... Java反射机制一、反射1.反射的概念2.获取class对象3. 获取Constructor对象4....