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

海山数据库(He3DB)源码详解:ResourceOwnerData及ResourceArray结构体解析

cxp 2025-01-23
10

海山数据库(He3DB)源码详解:ResourceOwnerData及ResourceArray结构体解析

本文介绍了事务执行过程中,检查一个堆元组是否对当前事务可见,用于确保事务可以看到正确的数据版本。

ResourceOwnerData 结构体的作用

ResourceOwnerData 是 PostgreSQL 中用于管理资源所有权的核心结构体。它定义了一个资源所有者(ResourceOwner)的内部数据结构,用于跟踪和管理事务或子事务中占用的各种资源。这些资源包括缓冲区、缓存引用、文件、锁等。以下是对 ResourceOwnerData 结构体及其成员的详细解读:

1. 树状结构

所有的ResourceOwnerData数据会构成树状结构,如下图所示:
alt text

  1. TopTransaction作为父节点,通过firstchild指针连接三个子节点;
  2. 三个子节点分别通过nextchild指针构成链表;

2. 结构体定义

typedef struct ResourceOwnerData { ResourceOwner parent; /* NULL if no parent (toplevel owner) */ ResourceOwner firstchild; /* head of linked list of children */ ResourceOwner nextchild; /* next child of same parent */ const char *name; /* name (just for debugging) */ /* We have built-in support for remembering: */ ResourceArray bufferarr; /* owned buffers */ ResourceArray catrefarr; /* catcache references */ ResourceArray catlistrefarr; /* catcache-list pins */ ResourceArray relrefarr; /* relcache references */ ResourceArray planrefarr; /* plancache references */ ResourceArray tupdescarr; /* tupdesc references */ ResourceArray snapshotarr; /* snapshot references */ ResourceArray filearr; /* open temporary files */ ResourceArray dsmarr; /* dynamic shmem segments */ ResourceArray jitarr; /* JIT contexts */ ResourceArray cryptohasharr; /* cryptohash contexts */ ResourceArray hmacarr; /* HMAC contexts */ /* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */ int nlocks; /* number of owned locks */ LOCALLOCK *locks[MAX_RESOWNER_LOCKS]; /* list of owned locks */ } ResourceOwnerData;
复制

1. 树状结构成员

  • ResourceOwner parent;

    • 类型ResourceOwner(指向另一个ResourceOwnerData的指针)
    • 作用:指向当前资源所有者的父节点。如果当前所有者是顶层所有者,则parentNULL
    • 用途:支持嵌套事务或子事务的资源管理。例如,在一个事务中开启一个子事务时,子事务的资源所有者会将父事务的资源所有者作为其parent
  • ResourceOwner firstchild;

    • 类型ResourceOwner
    • 作用:指向当前资源所有者的第一个子节点。
    • 用途:用于构建资源所有者的子节点链表,支持树状结构的遍历。
  • ResourceOwner nextchild;

    • 类型ResourceOwner
    • 作用:指向当前资源所有者的下一个兄弟节点。
    • 用途:用于链表结构,支持遍历同一父节点的所有子节点。
  • const char *name;

    • 类型const char*
    • 作用:资源所有者的名称。
    • 用途:主要用于调试,方便在日志或调试信息中标识资源所有者。

2. 资源管理相关成员

这些成员用于跟踪和管理不同类型的资源。每种资源类型都通过一个ResourceArray数组来管理。

  • ResourceArray bufferarr;

    • 作用:管理当前所有者占用的缓冲区资源。
    • 用途:确保在事务结束时释放所有占用的缓冲区。
  • ResourceArray catrefarr;

    • 作用:管理当前所有者对系统目录缓存(catcache)的引用。
    • 用途:确保在事务结束时释放对系统目录缓存的引用。
  • ResourceArray catlistrefarr;

    • 作用:管理当前所有者对系统目录缓存列表(catcache-list)的引用。
    • 用途:确保在事务结束时释放对系统目录缓存列表的引用。
  • ResourceArray relrefarr;

    • 作用:管理当前所有者对关系缓存(relcache)的引用。
    • 用途:确保在事务结束时释放对关系缓存的引用。
  • ResourceArray planrefarr;

    • 作用:管理当前所有者对计划缓存(plancache)的引用。
    • 用途:确保在事务结束时释放对计划缓存的引用。
  • ResourceArray tupdescarr;

    • 作用:管理当前所有者对元组描述符(tupdesc)的引用。
    • 用途:确保在事务结束时释放对元组描述符的引用。
  • ResourceArray snapshotarr;

    • 作用:管理当前所有者对快照(snapshot)的引用。
    • 用途:确保在事务结束时释放对快照的引用。
  • ResourceArray filearr;

    • 作用:管理当前所有者打开的临时文件。
    • 用途:确保在事务结束时关闭所有临时文件。
  • ResourceArray dsmarr;

    • 作用:管理当前所有者对动态共享内存段(dynamic shared memory segments)的引用。
    • 用途:确保在事务结束时释放对动态共享内存段的引用。
  • ResourceArray jitarr;

    • 作用:管理当前所有者对即时编译(JIT)上下文的引用。
    • 用途:确保在事务结束时释放对JIT上下文的引用。
  • ResourceArray cryptohasharr;

    • 作用:管理当前所有者对加密哈希上下文的引用。
    • 用途:确保在事务结束时释放对加密哈希上下文的引用。
  • ResourceArray hmacarr;

    • 作用:管理当前所有者对HMAC上下文的引用。
    • 用途:确保在事务结束时释放对HMAC上下文的引用。

3. 锁管理相关成员

这些成员用于跟踪和管理当前所有者持有的锁。

  • int nlocks;

    • 类型int
    • 作用:当前所有者持有的锁的数量。
    • 用途:记录当前所有者管理的锁的数量,确保在事务结束时释放所有锁。
  • LOCALLOCK *locks[MAX_RESOWNER_LOCKS];

    • 类型LOCALLOCK*数组
    • 作用:存储当前所有者持有的锁的指针。
    • 用途:确保在事务结束时释放所有持有的锁。MAX_RESOWNER_LOCKS是一个常量,限制了资源所有者可以持有的最大锁数量。

3. 总结

ResourceOwnerData 结构体是 PostgreSQL 中资源管理的核心组件,用于跟踪和管理事务或子事务中占用的各种资源。它的主要功能包括:

  1. 树状结构管理:通过parentfirstchildnextchild成员,支持嵌套事务的资源管理。
  2. 资源跟踪:通过ResourceArray数组,管理不同类型的资源,确保在事务结束时释放所有资源。
  3. 锁管理:通过nlockslocks成员,跟踪和管理当前所有者持有的锁,确保在事务结束时释放所有锁。

通过这种设计,ResourceOwner能够有效地管理资源的生命周期,确保资源在事务结束时被正确释放,从而避免资源泄漏和死锁问题。


ResourceArray 结构体的作用

ResourceArray 是 PostgreSQL 中用于存储和管理各种资源 ID 的通用结构体。它通过动态调整存储方式(从简单数组到哈希表)来高效地管理资源集合。以下是对 ResourceArray 结构体及其成员的详细解释:

1. 存储模式

ResourceArray 用于高效地存储和管理资源 ID。它支持以下两种存储模式:

  1. 简单数组模式:当资源数量较少时,使用线性数组存储资源 ID。
  2. 哈希表模式:当资源数量较多时,切换到哈希表存储,以提高查找效率。

这种设计结合了线性数组的简单性和哈希表的高效性,能够在不同场景下优化资源管理。

2. 结构体定义及成员

typedef struct ResourceArray { Datum *itemsarr; /* buffer for storing values */ Datum invalidval; /* value that is considered invalid */ uint32 capacity; /* allocated length of itemsarr[] */ uint32 nitems; /* how many items are stored in items array */ uint32 maxitems; /* current limit on nitems before enlarging */ uint32 lastidx; /* index of last item returned by GetAny */ } ResourceArray;
复制
  1. Datum *itemsarr;

    • 类型Datum 类型的指针数组。
    • 作用:用于存储资源 ID 的数组。
    • 说明
      • 在简单数组模式下,itemsarr 是一个线性数组,存储资源 ID。
      • 在哈希表模式下,itemsarr 是一个哈希表,每个槽位存储一个资源 ID 或 invalidval
      • Datum 是 PostgreSQL 中的通用数据类型,可以存储任意类型的数据。
  2. Datum invalidval;

    • 类型Datum
    • 作用:表示无效值的标识符。
    • 说明
      • 在哈希表模式下,invalidval 用于标记空槽位或已删除的槽位。
      • itemsarr[k] == invalidval 时,表示该槽位是空的或无效的。
  3. uint32 capacity;

    • 类型uint32(无符号 32 位整数)。
    • 作用:表示 itemsarr 的分配长度(即数组或哈希表的总容量)。
    • 说明
      • 在简单数组模式下,capacity 是数组的最大长度。
      • 在哈希表模式下,capacity 是哈希表的总槽数。
  4. uint32 nitems;

    • 类型uint32
    • 作用:表示当前存储的有效资源 ID 数量。
    • 说明
      • nitems 达到 maxitems 时,数组或哈希表需要扩容。
  5. uint32 maxitems;

    • 类型uint32
    • 作用:表示当前模式下 nitems 的上限。
    • 说明
      • 在简单数组模式下,maxitems 是数组的最大容量。
      • 在哈希表模式下,maxitems 是哈希表中允许存储的最大有效项数,通常小于 capacity,以避免哈希冲突过多。
  6. uint32 lastidx;

    • 类型uint32
    • 作用:记录最近一次通过 GetAny 方法返回的资源 ID 的索引。
    • 说明
      • ResourceArrayRemove 方法中,lastidx 可以加快查找速度,避免重复搜索。

3. 工作原理

  1. 简单数组模式

    • 当资源数量较少时,ResourceArray 使用线性数组存储资源 ID。
    • itemsarr 是一个线性数组,nitems 表示当前存储的资源数量。
    • nitems 达到 maxitems 时,切换到哈希表模式。
  2. 哈希表模式

    • 当资源数量较多时,ResourceArray 使用哈希表存储资源 ID。
    • itemsarr 是一个哈希表,每个槽位存储一个资源 ID 或 invalidval
    • capacity 是哈希表的总槽数,maxitems 是允许存储的最大有效项数。
    • 如果 nitems 超过 maxitems,则扩容哈希表并重新哈希。
  3. 动态调整

    • ResourceArray 会根据资源数量动态调整存储模式,以优化性能。
    • 在哈希表模式下,lastidx 用于记录最近一次操作的索引,以加快查找速度。

4. 总结

ResourceArray 是一个高效管理资源 ID 的通用结构体,支持动态调整存储方式(从简单数组到哈希表)。它的成员变量分别用于:

  • 存储资源 ID(itemsarr)。
  • 标记无效值(invalidval)。
  • 管理数组或哈希表的容量(capacity)。
  • 记录当前存储的有效资源数量(nitems)。
  • 设置存储上限(maxitems)。
  • 记录最近一次操作的索引(lastidx)。

这种设计使得 ResourceArray 能够在不同场景下高效地管理资源,同时支持动态扩容和快速查找。

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

评论