本章说明 PostgreSQL 核心系统与管理表存储的表访问方法之间的接口。除这里规定的内容之外,核心系统对这些访问方法知之甚少,因此可以通过编写附加代码来开发全新的访问方法类型。
每个表访问方法都由系统目录 pg_am 中的一行描述。pg_am 条目指定了该表访问方法的名称以及一个处理器函数。这些条目可以通过 CREATE ACCESS METHOD 和 DROP ACCESS METHOD SQL 命令创建和删除。
表访问方法的处理器函数必须声明为接受一个 internal 类型的参数,并返回伪类型 table_am_handler。这个参数只是一个占位值,用来防止处理器函数被 SQL 命令直接调用。 该函数的结果必须是一个指向 TableAmRoutine 类型结构体的指针,其中包含核心代码使用该表访问方法所需了解的全部信息。返回值需要具有服务器生命周期,这通常可通过把它定义为全局作用域中的 static const 变量来实现。TableAmRoutine 结构体也称为该访问方法的API 结构,它通过回调来定义访问方法的行为。这些回调是普通 C 函数的指针,在 SQL 层既不可见也不可调用。所有回调及其行为都定义在 TableAmRoutine 结构体中(结构体内的注释说明了对回调的要求)。大多数回调都有包装函数,其文档是从表访问方法使用者而非实现者的角度编写的。详情请参阅 src/include/access/tableam.h 文件。
要实现一种访问方法,实现者通常需要实现一种 AM 专用的元组表槽类型(见 src/include/executor/tuptable.h),这样访问方法之外的代码就能持有对该 AM 元组的引用,并访问元组的各列。
目前,AM 实际存储数据的方式所受限制相当少。例如,可以使用 postgres 的共享缓冲区缓存,但这并非必需。如果使用它,那么采用 PostgreSQL 在 Section 65.6 中描述的标准页面布局通常是有意义的。
当前,表访问方法 API 的一个相当重要的限制是,如果 AM 想要支持修改和/或索引,则每个元组都必须具有一个由块号和项号组成的元组标识符(TID)(另见 Section 65.6)。TID 的各个组成部分并不严格要求与 heap 中的含义完全相同,但如果希望支持位图扫描(这是可选的),块号就必须提供局部性。
为保证崩溃安全,AM 可以使用 postgres 的WAL,也可以使用自定义实现。 如果选择了 WAL,可以使用通用 WAL 记录, 也可以实现一个自定义 WAL 资源管理器。
要以允许在单个事务中访问不同表访问方法的方式实现事务支持,很可能需要与 src/backend/access/transam/xlog.c 中的机制紧密集成。
任何新表访问方法的开发者都可以参考现有的 heap 实现,其位于 src/backend/access/heap/heapam_handler.c 中,以了解其实现细节。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。