阅读(1073) (20)

PostgreSQL 系统目录声明和初始内容

2021-08-24 15:07:40 更新

PostgreSQL使用很多不同的系统目录来跟踪数据库对象(例如表和函数)的存在以及属性。系统目录和普通用户表之间在物理上没有什么不同,但是后端的C代码知道每一个目录的结构和属性,并且能够在较低的层次上直接操纵它们。因此,不建议尝试在运行中修改目录的结构,那样做会破坏内建在C代码中对目录行如何放置的设想。但是目录的结构可能会在主版本之间发生变化。

目录的结构声明在特殊格式的C头文件中,它们位于源码树的src/include/catalog/目录中。特别地,对每一个目录都有一个以其名称命名的头文件(例如,pg_class的头文件是pg_class.h),头文件定义了目录具有的列集合,以及一些其他的基本属性(例如OID)。其他定义目录结构的重要文件包括 indexing.htoasting.h,前者定义所有系统目录上的索引,而后者为需要TOAST表的目录定义TOAST表。

很多目录都有初始数据,这些数据必须在initdbbootstrap阶段装载到对应的目录中,这样才能让系统达到能够执行SQL命令的状态点(例如,pg_class.h必须包含表示其自身的一个项,还要为每个系统目录和索引都分别包含一项)。这些初始数据以可编辑的形式保存在 src/include/catalog/目录下的数据文件中。例如,pg_proc.dat描述了所有必须被插入到pg_proc目录的初始行。

为了创建目录文件并且将这些初始数据载入其中,一个以bootstrap模式运行的后端会读取包含着命令和初始数据的BKI(后端接口)文件。这种模式中用到的postgres.bki文件正是在编译PostgreSQL时从前述的头文件和数据文件准备而来,这一过程由名为genbki.pl的Perl脚本负责。尽管 postgres.bki与特定PostgreSQL发行版相关,但它是平台无关的并且被安装在安装树的share子目录中。

genbki.pl还会为每个目录产生一个头文件,例如为pg_class生成的头文件是pg_class_d.h。这个文件含有自动生成的宏定义,并且可能包含其他的宏、枚举声明,因此对于读取特定目录的客户端C代码很有用。

大部分PostgreSQL的开发者不需要直接与BKI文件打交道,但是几乎在后端中增加任何非平凡的特性都需要修改目录头文件或者初始数据文件。本章的剩余部分会给出一些相关的信息,并且将会完整地描述BKI文件格式。