大云海山数据库(He3DB)源码详解:He3DB-CLOG日志管理器函数之TransactionIdGetStatus
背景
大云He3DB 采用了先进的存储引擎和查询优化技术,能够快速处理大量数据和复杂查询。无论是 OLTP(在线事务处理)还是 OLAP(在线分析处理)场景,都能提供出色的性能表现。He3DB 具备完善的数据备份和恢复机制,能够在系统故障或数据损坏时快速恢复数据,确保业务的连续性。He3DB 支持水平扩展和垂直扩展,可以轻松应对不断增长的数据需求。He3DB 提供了严格的访问控制和数据加密功能,确保数据的安全性和隐私性。
本文基于大云He3DB,针对CLOG日志管理模块进行源码解读分享,包含TransactionIdGetStatus函数
TransactionIdGetStatus函数
作用:实现CLOG日志的读操作
XidStatus
TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
{
int pageno = TransactionIdToPage(xid);
int byteno = TransactionIdToByte(xid);
int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
int slotno;
int lsnindex;
char *byteptr;
XidStatus status;
slotno = SimpleLruReadPage_ReadOnly(XactCtl, pageno, xid);
byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
lsnindex = GetLSNIndex(slotno, xid);
*lsn = XactCtl->shared->group_lsn[lsnindex];
LWLockRelease(XactSLRULock);
return status;
}
- 计算参数:
-
pageno
事务xid对应的CLOG页号
-
byteno
事务ID在页内的字节偏移
-
bshift
事务ID在字节内的位偏移(因为每个事务状态只占用几个位)
slotno = SimpleLruReadPage_ReadOnly(XactCtl, pageno, xid);
使用SimpleLruReadPage_ReadOnly
函数以只读方式读取CLOG页。这个函数负责从共享缓冲区中获取或读取指定的页,并返回一个槽号(slotno
),用于后续访问该页
int
SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
{
SlruShared shared = ctl->shared;
int slotno;
/* Try to find the page while holding only shared lock */
LWLockAcquire(shared->ControlLock, LW_SHARED);
/* See if page is already in a buffer */
for (slotno = 0; slotno < shared->num_slots; slotno++)
{
if (shared->page_number[slotno] == pageno &&
shared->page_status[slotno] != SLRU_PAGE_EMPTY &&
shared->page_status[slotno] != SLRU_PAGE_READ_IN_PROGRESS)
{
/* See comments for SlruRecentlyUsed macro */
SlruRecentlyUsed(shared, slotno);
/* update the stats counter of pages found in the SLRU */
pgstat_count_slru_page_hit(shared->slru_stats_idx);
return slotno;
}
}
LWLockRelease(shared->ControlLock);
LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);
return SimpleLruReadPage(ctl, pageno, true, xid);
}
-
获取共享锁,这允许它检查页面是否已经在缓存中,而不需要阻塞其他可能正在读取或写入不同页面的操作
-
遍历槽位号
-
检查是否有槽位中的页面编号与请求的页面编号相匹配,并且该槽位的页面状态不是空的(
SLRU_PAGE_EMPTY
)也不是正在读取中(SLRU_PAGE_READ_IN_PROGRESS
) -
- 如果有,更新该槽位为最近使用,且计数找到这样页面的次数,然后返回该槽位号
-
如果在共享锁下没有找到这样的页面,则释放该共享锁
-
获取排他锁
-
在排他锁前提下,调用
SimpleLruReadPage
返回新读取的页面槽位号,并返回
byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
- 从
page_buffer[slotno]
指向的页面开始,加上字节偏移量byteno
赋给byteptr
:指向了想要访问的特定字节的指针 - 先指针解引用获取
byteptr
的值,再右移bshift
位,再与CLOG_XACT_BITMASK
做与运算,最终得到status
lsnindex = GetLSNIndex(slotno, xid);
*lsn = XactCtl->shared->group_lsn[lsnindex];
- 获取
lsn
的索引 - 解引用lsn(
*lsn
)将得到的LSN存储在该指针指向的位置
LSN:日志序列号,用于跟踪事务日志中的位置
释放锁,并返回状态值status
函数流程图
总结
函数名 | 作用 |
---|---|
TransactionIdGetStatus | 实现CLOG日志的读操作 |
其余文章参考链接
大云海山数据库(He3DB)源码详解:He3DB-CLOG日志管理器函数之TransactionIdSetTreeStatus
大云海山数据库(He3DB)+AI(五):一种基于强化学习的数据库旋钮调优方法
大云海山数据库(He3DB)+AI(四):一种基于迁移学习的启发式数据库旋钮调优方法
大云海山数据库(He3DB)源码解读:海山PG 词法、语法分析
大云海山数据库(He3DB)源码详解:海山PG 空闲空间映射表FSM
大云海山数据库(He3DB)源码详解:主备复制SyncRepWaitForLSN
作者信息
公司 | 职位 |
---|---|
中移苏研 | 助理软件研发工程师 |