本章解释了核心 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 的标准页面布局(如 第 73.6 节 所述)可能是合理的。
表访问方法 API 的一个相当大的约束是,目前,如果 AM 要支持修改和/或索引,则每个元组都需要有一个元组标识符 (TID),该标识符由块号和项号组成(另请参阅 第 73.6 节)。TID 的子部分不必严格具有相同的含义,例如,它们对 heap
有相同的含义,但是如果需要位图扫描支持(它是可选的),则块号需要提供局部性。
对于崩溃安全性,AM 可使用 postgres 的 WAL,或自定义实现。如果选择 WAL,可以使用 通用 WAL 记录,也可以实现 自定义 WAL 资源管理器。
要以允许在单个事务中访问不同表访问方法的方式实现事务支持,可能需要与 src/backend/access/transam/xlog.c
中的机制紧密集成。
任何新 表访问方法
的开发者都可以参考 src/backend/access/heap/heapam_handler.c
中现有的 堆
实现,以了解其实现的详细信息。