大云海山数据库(He3DB)源码详解:He3DB-CLOG日志管理器函数之TransactionIdGetStatus

34 阅读4分钟

大云海山数据库(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

作者信息

公司职位
中移苏研助理软件研发工程师