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

26 阅读4分钟

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

作者信息

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