暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

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

wukong 2025-01-23
43

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

背景

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

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

SimpleLruReadPage

源码解读

/* ctl:指向 SLRU 控制结构的指针,包含共享状态和其他控制信息。 pageno:要读取的页面编号。 write_ok:是否允许对页面进行写操作。 xid:当前事务 ID */ int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid) { LOG_FUNCTION_ENTRY(); SlruShared shared = ctl->shared;// 初始化共享状态 /* 外层循环:处理 I/O 等待 如果页面正在被其他进程读取或写入,当前进程需要等待 */ for (;;) { int slotno = 0; bool ok = false;//用于标记页面读取是否成功 /* 尝试找到页面是否已在内存中。如果页面不在内存中,则选择一个可以替换的槽位*/ slotno = SlruSelectLRUPage(ctl, pageno); /*检查选定槽位的页面编号是否与请求的页面编号匹配,并且页面状态不是空闲 */ if (shared->page_number[slotno] == pageno && shared->page_status[slotno] != SLRU_PAGE_EMPTY) { /* 检查页面是否正在被读取(SLRU_PAGE_READ_IN_PROGRESS)或正在被写入且不允许写操作 */ if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS || (shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS && !write_ok)) { SimpleLruWaitIO(ctl, slotno);//如果页面正在被读取或写入,调用 SimpleLruWaitIO 等待 I/O 完成,然后重新检查页面状态 continue; } // 页面已准备好 SlruRecentlyUsed(shared, slotno);//标记页面为最近使用,更新 LRU 状态 pgstat_count_slru_page_hit(shared->slru_stats_idx);//更新统计信息,记录页面命中次数 LOG_FUNCTION_EXIT(); return slotno; } /* We found no match; assert we selected a freeable slot */ Assert(shared->page_status[slotno] == SLRU_PAGE_EMPTY || (shared->page_status[slotno] == SLRU_PAGE_VALID && !shared->page_dirty[slotno])); /* 将槽位标记为正在读取(SLRU_PAGE_READ_IN_PROGRESS),并清除脏页标志 */ shared->page_number[slotno] = pageno; shared->page_status[slotno] = SLRU_PAGE_READ_IN_PROGRESS; shared->page_dirty[slotno] = false; /* Acquire per-buffer lock (cannot deadlock, see notes at top) */ LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_EXCLUSIVE); /* Release control lock while doing I/O */ LWLockRelease(shared->ControlLock); /* 从磁盘读取页面数据到槽位 */ ok = SlruPhysicalReadPage(ctl, pageno, slotno); /* 将新读取的页面的 LSN(Log Sequence Number)设置为零*/ SimpleLruZeroLSNs(ctl, slotno); LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE); //断言页面状态为正在读取,并根据读取结果更新页面状态 Assert(shared->page_number[slotno] == pageno && shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS && !shared->page_dirty[slotno]); shared->page_status[slotno] = ok ? SLRU_PAGE_VALID : SLRU_PAGE_EMPTY; LWLockRelease(&shared->buffer_locks[slotno].lock); /* 如果页面读取失败,调用 SlruReportIOError 报告错误 */ if (!ok) { SlruReportIOError(ctl, pageno, xid); } SlruRecentlyUsed(shared, slotno);//标记页面为最近使用,更新 LRU 状态 /* 更新统计信息,记录页面未命中次数 */ pgstat_count_slru_page_read(shared->slru_stats_idx); LOG_FUNCTION_EXIT(); return slotno; } LOG_FUNCTION_EXIT(); return; }

函数流程图

该函数流程图如下所示:
请添加图片描述

流程图解释

  1. 开始

    • 函数开始执行。
  2. 调用 SlruSelectLRUPage 获取槽位

    • 尝试找到页面是否已在内存中,或选择一个可以替换的槽位。
  3. 槽位页面是否匹配

    • 检查槽位的页面编号是否与请求的页面编号匹配。
  4. 页面状态是否为 READ_IN_PROGRESSWRITE_IN_PROGRESS

    • 如果页面正在被读取或写入,需要等待 I/O 完成。
  5. 调用 SimpleLruWaitIO 等待 I/O 完成

    • 等待页面的 I/O 操作完成。
  6. 重新检查页面状态

    • I/O 完成后,重新检查页面状态。
  7. 检查槽位是否为空或未脏

    • 确保槽位可以被使用。
  8. 标记槽位为 READ_IN_PROGRESS

    • 标记槽位为正在读取状态。
  9. 获取槽位锁

    • 获取槽位的独占锁,确保线程安全。
  10. 释放控制锁

    • 释放控制锁,允许其他进程访问 SLRU 缓冲区。
  11. 调用 SlruPhysicalReadPage 读取页面

    • 从磁盘读取页面数据到槽位。
  12. 设置 LSN 为零

    • 初始化页面的 LSN。
  13. 重新获取控制锁

    • 重新获取控制锁,更新页面状态。
  14. 读取是否成功

    • 检查页面读取是否成功。
  15. 更新页面状态为 VALIDEMPTY

    • 根据读取结果更新页面状态。
  16. 释放槽位锁

    • 释放槽位的独占锁。
  17. 标记页面为最近使用

    • 更新 LRU 状态。
  18. 更新统计信息

    • 记录页面命中或未命中的统计信息。
  19. 返回槽号

    • 返回槽号,函数结束。

函数调用栈

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

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

总结

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

函数名 作用
SubTransSetParent SimpleLruReadPage 函数的作用是从 SLRU 缓冲区中读取一个页面。它通过以下步骤实现:检查页面是否已在内存中。如果页面正在被读取或写入,等待 I/O 完成。如果页面不在内存中,选择一个空闲槽位。从磁盘读取页面数据到槽位。更新页面状态并返回槽号。

其余文章参考链接

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

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

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

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

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

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

作者信息

公司 职位
中移苏研 助理软件研发工程师
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论