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

大云海山数据库(He3DB)源码详解:He3DB-SubTrans日志管理器函数之SubTransGetParent、SubTransGetTopmostTransaction

Eric 2024-12-14
112

# 大云海山数据库(He3DB)源码详解:He3DB-SubTrans日志管理器函数之SubTransGetParent、SubTransGetTopmostTransaction

背景

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

本文基于大云He3DB,针对SubTrans日志管理模块进行源码解读分享,包含SubTransGetParent、SubTransGetTopmostTransaction函数

SubTransGetParent函数

作用:获取目标事务的父事务id

TransactionId SubTransGetParent(TransactionId xid) { int pageno = TransactionIdToPage(xid); int entryno = TransactionIdToEntry(xid); int slotno; TransactionId *ptr; TransactionId parent; Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin)); /* Bootstrap and frozen XIDs have no parent */ if (!TransactionIdIsNormal(xid)) return InvalidTransactionId; /* lock is acquired by SimpleLruReadPage_ReadOnly */ slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid); ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno]; ptr += entryno; parent = *ptr; LWLockRelease(SubtransSLRULock); return parent; }
int pageno = TransactionIdToPage(xid); int entryno = TransactionIdToEntry(xid);

pageno 计算事务idxid对应的页号
entryno 计算事务idxid对应的条目号

条目号:表示在一个页面中的具体位置。每个页面被划分为多个条目,每个条目对应一个事务的父事务 ID

  • 断言:确保给定的事务ID xid 大于等于最小事务ID TransactionXmin,确保给定的事务id有效
  • 事务ID是递增的,较早的事务ID表示较早的事务
  • 最小事务id通常对应于系统启动后的第一个事务
  • 如果是Bootstrap或者冻结frozen 的事务,这些事务无父事务,则返回无效的事务id
slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid); ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno]; ptr += entryno; parent = *ptr;
  • 获取页号对应的槽位号
  • 获取页缓冲区中槽位号对应的指针
  • 指针移动到指定条目号处
  • 解引用获取事务id并赋给parent

根据子事务日志写操作函数可知,此时条目号对应的指针存放的是父事务id

  • 释放锁并返回获取的父事务idparent

函数流程图

在这里插入图片描述

SubTransGetTopmostTransaction函数

TransactionId SubTransGetTopmostTransaction(TransactionId xid) { TransactionId parentXid = xid, previousXid = xid; Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin)); while (TransactionIdIsValid(parentXid)) { previousXid = parentXid; if (TransactionIdPrecedes(parentXid, TransactionXmin)) break; parentXid = SubTransGetParent(parentXid); if (!TransactionIdPrecedes(parentXid, previousXid)) elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u", previousXid, parentXid); } Assert(TransactionIdIsValid(previousXid)); return previousXid; }
  • 初始化变量parentXidpreviousXidxid
  • 回溯,不可能区查询无效的事务id,因此采用断言确保当前传入的事务idxid大于等于最小事务idTransactionXmin
  • 通过while循环来查找最顶层父事务id
    • 存储父事务idparentXidpreviousXid
    • 如果parentXid在最小事务id之前,则无效跳出循环
      • TransactionIdPrecedes(A, B):如果A早于B,返回true

    • 调用子事务日志读操作SubTransGetParent获取parentXid父事务id,保存在parentXid 中,即回溯,往上一层->通过父事务A获取该A的父事务A’
    • 判断最新的父事务id-A‘是否先于之前的父事务id-A,若A’先于A,说明爷爷先于爹,合理
    • 判断previousXid是否有效,若有效,返回previousXid

函数流程图

在这里插入图片描述

总结

函数名 作用
SubTransGetParent 获取目标事务的父事务id
SubTransGetTopmostTransaction 获取给定TransactionId的顶层事务ID

其余文章参考链接

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

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

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

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

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

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

作者信息

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

评论