大云海山数据库(He3DB)源码详解:He3DB-SimpleLruReadPage_ReadOnly

30 阅读4分钟

大云海山数据库(He3DB)源码详解:He3DB-SimpleLruReadPage_ReadOnly

背景

大云He3DB 采用了先进的存储引擎和查询优化技术,能够快速处理大量数据和复杂查询。无论是 OLTP(在线事务处理)还是 OLAP(在线分析处理)场景,都能提供出色的性能表现。He3DB 具备完善的数据备份和恢复机制,能够在系统故障或数据损坏时快速恢复数据,确保业务的连续性。He3DB 支持水平扩展和垂直扩展,可以轻松应对不断增长的数据需求。He3DB 提供了严格的访问控制和数据加密功能,确保数据的安全性和隐私性。

本文基于大云He3DB,针对SimpleLruReadPage_ReadOnly进行源码解读分享

SimpleLruReadPage_ReadOnly

源码解读

/*
功能:尝试以只读模式读取指定的 SLRU 页面。
参数:
SlruCtl ctl:SLRU 控制结构,包含共享状态和其他控制信息。
int pageno:要读取的页面编号。
TransactionId xid:事务 ID
*/
int
SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
{
	LOG_FUNCTION_ENTRY();
	SlruShared	shared = ctl->shared;//获取共享状态
	int slotno = 0;

	LWLockAcquire(shared->ControlLock, LW_SHARED);

	/* 查找页面是否已在缓冲区中 */
	for (slotno = 0; slotno < shared->num_slots; slotno++)//遍历所有槽位
	{
		//检查当前槽位的页面编号是否与请求的 pageno 匹配。
		//确保页面状态不是 SLRU_PAGE_EMPTY(空槽位)或 SLRU_PAGE_READ_IN_PROGRESS(正在读取中)
		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);//更新页面命中的统计信息

			LOG_FUNCTION_EXIT();
			return slotno;
		}
	}

	/* No luck, so switch to normal exclusive lock and do regular read */
	LWLockRelease(shared->ControlLock);
	LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);

	LOG_FUNCTION_EXIT();
	return SimpleLruReadPage(ctl, pageno, true, xid);//传入 true 表示以只读模式读取
}

函数流程图

该函数流程图如下所示:

请添加图片描述

流程图解释

流程说明

  1. 开始:函数开始执行。
  2. 获取共享锁:以共享模式获取控制锁,允许多个线程同时读取。
  3. 遍历槽位:逐个检查槽位中的页面信息。
  4. 槽位页面是否匹配
    • 如果槽位的页面编号与请求的页面编号匹配,且状态不是 EMPTYREAD_IN_PROGRESS,则进入下一步。
    • 否则,继续检查下一个槽位。
  5. 更新最近使用状态:调用 SlruRecentlyUsed 更新 LRU 状态。
  6. 更新统计信息:记录页面命中的统计信息。
  7. 返回槽位编号:返回匹配的槽位编号。
  8. 是否遍历完所有槽位?
    • 如果所有槽位都已检查完毕,进入下一步。
    • 否则,继续遍历。
  9. 释放共享锁:释放共享锁,允许其他线程访问。
  10. 获取独占锁:以独占模式获取控制锁,用于后续的读取操作。
  11. 调用常规读取函数:调用 SimpleLruReadPage 函数完成页面读取。
  12. 返回结果:返回读取结果。
  13. 结束:函数执行完成。

这个流程图清晰地展示了函数的执行逻辑,包括共享锁和独占锁的切换,以及页面查找的过程。

函数调用栈

通过source insight可以查看函数的调用栈

source insight安装流程可以参考这篇文章:Source insight 工具安装及使用方法

总结

本文基于大云He3DB,针对SimpleLruReadPage_ReadOnly进行源码解读分享。

这个函数的主要逻辑是: 尝试在共享锁下快速查找页面。 如果找到页面,更新统计信息并返回槽位编号。 如果未找到页面,切换到独占锁并调用常规读取函数。 通过这种方式,函数尽量减少锁的冲突,提高读取效率。

其余文章参考链接

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

大云海山数据库(He3DB)+AI(五):一种基于强化学习的数据库旋钮调优方法

大云海山数据库(He3DB)+AI(四):一种基于迁移学习的启发式数据库旋钮调优方法

大云海山数据库(He3DB)源码解读:海山PG 词法、语法分析

大云海山数据库(He3DB)源码详解:海山PG 空闲空间映射表FSM

大云海山数据库(He3DB)源码详解:主备复制SyncRepWaitForLSN

作者信息

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