有口碑的南昌网站设计,广东省建设安全管理协会网站,wordpress 用微信登陆,建设局是干什么的单位一、 定义及作用 PostgreSQL 的磁盘管理器#xff08;Storage Manager#xff0c;简称 SMGR#xff09;是数据库系统中负责管理底层存储的核心模块。磁盘管理器并非直接操作磁盘上的文件#xff0c;而是通过VFD#xff08;虚拟文件描述符#xff0c;将在后续学习#xf…一、 定义及作用 PostgreSQL 的磁盘管理器Storage Manager简称 SMGR是数据库系统中负责管理底层存储的核心模块。磁盘管理器并非直接操作磁盘上的文件而是通过VFD虚拟文件描述符将在后续学习实现。 抽象存储层解耦存储逻辑 SMGR 提供了一层抽象接口屏蔽了不同存储类型如表、索引、TOAST 表等的底层细节使上层模块如执行器、缓冲池无需关心具体的存储实现。 管理文件操作 SMGR 负责文件的创建、删除、扩展、截断等操作确保数据文件能够高效地存储和访问。 支持多种存储类型 PostgreSQL 支持多种存储类型如堆表、索引、TOAST 表等SMGR 通过统一的接口管理这些存储类型。 与缓冲池交互 SMGR 与缓冲池Buffer Manager紧密协作确保数据页能够正确地加载到内存中。 提高可扩展性 通过 SMGR 的抽象接口PostgreSQL 可以更容易地支持新的存储类型或存储引擎如列存储、外部表等。 二、 核心数据结构
src/include/storage/smgr.h SMGR 的头文件定义了存储管理器的接口和数据结构。
SMgrRelationSMGR的核心数据结构主要作用是
管理文件句柄缓存关系的文件句柄避免频繁打开和关闭文件。支持多分支ForkPostgreSQL 中的表或索引可能包含多个分支如主数据分支、TOAST 分支等SMgrRelationData 支持管理这些分支的文件。缓存文件大小记录每个分支的最后一个已知大小用于优化文件扩展操作。支持临时关系通过 smgr_owner 指针区分临时关系和持久关系临时关系在事务结束时自动释放
/** smgr.c 维护了一个 SMgrRelation 对象表这些对象本质上是缓存的文件句柄。* SMgrRelation 通过 smgropen() 创建如果尚未存在并通过 smgrclose() 销毁。* 注意这些操作并不涉及 I/O它们只是创建或销毁哈希表条目。* 但 smgrclose() 可能会释放相关资源例如操作系统级别的文件描述符。** 一个 SMgrRelation 可能有一个“所有者”这只是从其他地方指向它的指针* 如果 SMgrRelation 被关闭smgr.c 会清除此指针。* 我们使用此机制来避免从 relcache 到 smgr 的悬空指针而无需让 smgr 显式感知 relcache。* 每个 SMgrRelation 只能有一个“所有者”指针但这已经足够。** 没有“所有者”的 SMgrRelation 被认为是临时的并在事务结束时被删除。*/typedef struct SMgrRelationData
{/* rnode 是哈希表查找键因此必须放在第一位 */RelFileNodeBackend smgr_rnode; /* 表的物理标识符 *//* 指向所有者指针的指针如果没有则为 NULL */struct SMgrRelationData **smgr_owner;/** 以下字段在缓存刷新事件时重置为 InvalidBlockNumber* 并记录每个分支的最后一个已知大小。* 此信息目前仅在恢复期间可靠因为分支扩展没有缓存失效机制。*/BlockNumber smgr_targblock; /* 当前插入目标块 */BlockNumber smgr_cached_nblocks[MAX_FORKNUM 1]; /* 每个分支的最后一个已知大小 *//* 未来可能会在此处添加其他公共字段 *//** 以下字段是 smgr.c 及其子模块私有的。* 不要从其他地方修改它们。*/int smgr_which; /* 存储管理器选择器 *//** 用于 md.c每个分支的打开段数量md_num_open_segs* 和段本身md_seg_fds。*/int md_num_open_segs[MAX_FORKNUM 1];struct _MdfdVec *md_seg_fds[MAX_FORKNUM 1];/* 如果没有所有者则链接到所有无所有者 SMgrRelations 的链表中 */dlist_node node;
} SMgrRelationData;typedef SMgrRelationData *SMgrRelation; 三、 核心函数
1. smgrinit(void) 作用初始化存储管理器模块。 说明在 PostgreSQL 启动时调用用于初始化 SMGR 的全局状态如哈希表、锁等。 2. smgropen(RelFileNode rnode, BackendId backend) 作用打开一个关系的存储管理器SMgrRelation。 参数 rnode关系的物理标识符RelFileNode。 backend后端 ID用于区分不同后端进程。 返回值返回一个 SMgrRelation 对象表示关系的存储管理器。 3. smgrexists(SMgrRelation reln, ForkNumber forknum) 作用检查指定分叉Fork的文件是否存在。 参数 reln关系的存储管理器。 forknum分叉编号如主数据分叉、TOAST 分叉等。 返回值如果文件存在返回 true否则返回 false。 4. smgrsetowner(SMgrRelation *owner, SMgrRelation reln) 作用设置关系的所有者。 参数 owner指向所有者指针的指针。 reln关系的存储管理器。 说明用于将 reln 的所有者设置为 owner避免悬空指针问题。 5. smgrclearowner(SMgrRelation *owner, SMgrRelation reln) 作用清除关系的所有者。 参数 owner指向所有者指针的指针。 reln关系的存储管理器。 说明用于清除 reln 的所有者通常在关系关闭时调用。 6. smgrclose(SMgrRelation reln) 作用关闭一个关系的存储管理器。 参数 reln关系的存储管理器。 说明释放与 reln 相关的资源如文件描述符并将其从哈希表中移除。 7. smgrcloseall(void) 作用关闭所有关系的存储管理器。 说明在事务结束时调用用于清理所有临时关系的存储管理器。 8. smgrclosenode(RelFileNodeBackend rnode) 作用关闭指定关系的存储管理器。 参数 rnode关系的物理标识符。 说明根据 rnode 查找并关闭对应的存储管理器。 9. smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo) 作用创建一个新的分叉文件。 参数 reln关系的存储管理器。 forknum分叉编号。 isRedo是否在恢复期间调用。 说明用于创建表或索引的分叉文件如主数据文件、TOAST 文件等。 10. smgrdosyncall(SMgrRelation *rels, int nrels) 作用同步所有指定关系的文件到磁盘。 参数 rels存储管理器数组。 nrels数组长度。 说明确保所有修改过的文件数据被写入磁盘。 11. smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) 作用删除所有指定关系的文件。 参数 rels存储管理器数组。 nrels数组长度。 isRedo是否在恢复期间调用。 说明用于删除表或索引的分叉文件。 12. smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync) 作用扩展指定分叉的文件并写入数据。 参数 reln关系的存储管理器。 forknum分叉编号。 blocknum要写入的块号。 buffer要写入的数据。 skipFsync是否跳过同步到磁盘。 说明用于扩展文件并写入数据块。 13. smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum) 作用预取指定分叉的数据块。 参数 reln关系的存储管理器。 forknum分叉编号。 blocknum要预取的块号。 返回值如果预取成功返回 true否则返回 false。 14. smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer) 作用从指定分叉的文件中读取数据块。 参数 reln关系的存储管理器。 forknum分叉编号。 blocknum要读取的块号。 buffer存储读取数据的缓冲区。 说明用于从文件中读取数据块到内存。 15. smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync) 作用将数据块写入指定分叉的文件。 参数 reln关系的存储管理器。 forknum分叉编号。 blocknum要写入的块号。 buffer要写入的数据。 skipFsync是否跳过同步到磁盘。 说明用于将数据块写入文件。 16. smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks) 作用将指定范围内的数据块写回磁盘。 参数 reln关系的存储管理器。 forknum分叉编号。 blocknum起始块号。 nblocks要写回的块数。 说明用于批量写回数据块优化 I/O 性能。 17. smgrnblocks(SMgrRelation reln, ForkNumber forknum) 作用获取指定分叉的文件大小块数。 参数 reln关系的存储管理器。 forknum分叉编号。 返回值文件的大小块数。 18. smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum) 作用获取指定分叉的文件大小块数使用缓存值。 参数 reln关系的存储管理器。 forknum分叉编号。 返回值文件的大小块数。 说明与 smgrnblocks 类似但使用缓存值以提高性能。 19. smgrtruncate(SMgrRelation reln, ForkNumber *forknum, int nforks, BlockNumber *nblocks) 作用截断指定分叉的文件到指定大小。 参数 reln关系的存储管理器。 forknum分叉编号数组。 nforks分叉数量。 nblocks每个分叉的目标大小块数。 说明用于截断文件释放多余的空间。 20. smgrimmedsync(SMgrRelation reln, ForkNumber forknum) 作用立即同步指定分叉的文件到磁盘。 参数 reln关系的存储管理器。 forknum分叉编号。 说明确保文件的修改被立即写入磁盘。 21. AtEOXact_SMgr(void) 作用在事务结束时清理存储管理器。 说明用于释放临时关系的存储管理器清理缓存等。 参考《PostgreSQL 数据库内核分析》