2025年9月25日: PostgreSQL 18 发布!
支持的版本:当前18)/ 17 / 16 / 15 / 14 / 13
开发版本:devel
不支持的版本:12

第 62 章 表访问方法接口定义

本章解释了核心 PostgreSQL 系统与管理表存储的表访问方法之间的接口。除了此处规定的内容外,核心系统对这些访问方法了解甚少,因此可以通过编写附加代码来开发全新的访问方法类型。

每个表访问方法都由 pg_am 系统目录中的一行来描述。 pg_am 条目指定了表访问方法的名称和一个处理函数。可以使用 CREATE ACCESS METHODDROP ACCESS METHOD SQL 命令来创建和删除这些条目。

表访问方法处理函数必须声明接受一个 internal 类型的参数,并返回伪类型 table_am_handler。该参数是一个哑值,仅用于阻止从 SQL 命令直接调用处理函数。

扩展 SQL 脚本文件可能像这样创建表访问方法处理函数:

CREATE OR REPLACE FUNCTION my_tableam_handler(internal)
  RETURNS table_am_handler AS 'my_extension', 'my_tableam_handler'
  LANGUAGE C STRICT;

CREATE ACCESS METHOD myam TYPE TABLE HANDLER my_tableam_handler;

函数的结果必须是指向 TableAmRoutine 类型结构的指针,该结构包含核心代码用于使用表访问方法的所有信息。返回值需要是服务器生命周期内的,这通常通过将其定义为全局范围内的 static const 变量来实现。

包含表访问方法处理函数的源文件可能看起来像这样:

#include "postgres.h"

#include "access/tableam.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

static const TableAmRoutine my_tableam_methods = {
    .type = T_TableAmRoutine,

    /* Methods of TableAmRoutine omitted from example, add them here. */
};

PG_FUNCTION_INFO_V1(my_tableam_handler);

Datum
my_tableam_handler(PG_FUNCTION_ARGS)
{
    PG_RETURN_POINTER(&my_tableam_methods);
}

TableAmRoutine 结构,也称为访问方法的API 结构,使用回调定义访问方法的行为。这些回调是指向普通 C 函数的指针,在 SQL 级别不可见或不可调用。所有回调及其行为都在 TableAmRoutine 结构中定义(结构内的注释定义了回调的要求)。大多数回调都有包装函数,这些函数从表访问方法的用户的角度(而不是实现者的角度)进行记录。有关详细信息,请参阅 src/include/access/tableam.h 文件。

要实现一个访问方法,实现者通常需要实现一个AM特定的元组表槽(tuple table slot)(参见 src/include/executor/tuptable.h),它允许访问方法外部的代码持有对 AM 元组的引用,并访问元组的列。

目前,AM 实际存储数据的方式相当宽松。例如,可以使用 postgres 的共享缓冲区缓存,但并非强制要求。如果使用,那么使用 PostgreSQL 的标准页面布局(如 第 66.6 节中所述)可能是有意义的。

表访问方法 API 的一个相当大的限制是,目前,如果 AM 希望支持修改和/或索引,那么每个元组必须有一个元组标识符(TID),由块号和项号组成(另请参见 第 66.6 节)。TID 的子部分不一定具有与 heap 相同的含义,但如果需要位图扫描支持(这是可选的),则块号需要提供局部性。TIDs具有与 heap 相同的含义,但如果需要位图扫描支持(它是可选的),则块号需要提供局部性。

为了崩溃安全,AM 可以使用 postgres 的 WAL,或者自定义实现。如果WAL被选中,可以使用 通用 WAL 记录,也可以实现 自定义 WAL 资源管理器

要以允许在单个事务中访问不同表访问方法的方式实现事务支持,可能需要与 src/backend/access/transam/xlog.c 中的机制紧密集成。

任何新的 table access method 的开发者都可以参考现有 heap 实现(位于 src/backend/access/heap/heapam_handler.c)以获取其实现的详细信息。

提交更正

如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用 此表格 报告文档问题。