↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

百科 / Table AM / 核心表访问方法

heap

Core table AM

内置 heap 表访问方法将元组存储、可见性、扫描、索引获取和维护操作集成到 PostgreSQL 中。

当前查看 PostgreSQL 18.6。

说明

内置 heap 表访问方法将元组存储、可见性、扫描、索引获取和维护操作集成到 PostgreSQL 中。

接口类别
表访问方法
处理函数或例程
heapam_methods
记录的回调
43

接口与能力边界

矩阵记录此源码构建实际注册的回调。注册表明实现了相应接口钩子;操作是否允许还取决于选项、查询形式、权限和提供方规则。

下方保留同版本完整手册,包括配置、约束和示例。不声称已进行运行时能力测试。

堆存储、可见性与 WAL

此清单从 PostgreSQL 12 引入的 Table AM 接口开始。不会将更早版本的 PostgreSQL 堆存储重新标为 Table AM 实现。

堆可见性遵循 PostgreSQL 快照。WAL 和崩溃恢复行为取决于关系的持久性;临时表、无日志表与永久表不同。索引访问方法与表存储接口分开。

核心源码中注册的实现

{
	.type = T_TableAmRoutine,

	.slot_callbacks = heapam_slot_callbacks,

	.scan_begin = heap_beginscan,
	.scan_end = heap_endscan,
	.scan_rescan = heap_rescan,
	.scan_getnextslot = heap_getnextslot,

	.scan_set_tidrange = heap_set_tidrange,
	.scan_getnextslot_tidrange = heap_getnextslot_tidrange,

	.parallelscan_estimate = table_block_parallelscan_estimate,
	.parallelscan_initialize = table_block_parallelscan_initialize,
	.parallelscan_reinitialize = table_block_parallelscan_reinitialize,

	.index_fetch_begin = heapam_index_fetch_begin,
	.index_fetch_reset = heapam_index_fetch_reset,
	.index_fetch_end = heapam_index_fetch_end,
	.index_fetch_tuple = heapam_index_fetch_tuple,

	.tuple_insert = heapam_tuple_insert,
	.tuple_insert_speculative = heapam_tuple_insert_speculative,
	.tuple_complete_speculative = heapam_tuple_complete_speculative,
	.multi_insert = heap_multi_insert,
	.tuple_delete = heapam_tuple_delete,
	.tuple_update = heapam_tuple_update,
	.tuple_lock = heapam_tuple_lock,

	.tuple_fetch_row_version = heapam_fetch_row_version,
	.tuple_get_latest_tid = heap_get_latest_tid,
	.tuple_tid_valid = heapam_tuple_tid_valid,
	.tuple_satisfies_snapshot = heapam_tuple_satisfies_snapshot,
	.index_delete_tuples = heap_index_delete_tuples,

	.relation_set_new_filelocator = heapam_relation_set_new_filelocator,
	.relation_nontransactional_truncate = heapam_relation_nontransactional_truncate,
	.relation_copy_data = heapam_relation_copy_data,
	.relation_copy_for_cluster = heapam_relation_copy_for_cluster,
	.relation_vacuum = heap_vacuum_rel,
	.scan_analyze_next_block = heapam_scan_analyze_next_block,
	.scan_analyze_next_tuple = heapam_scan_analyze_next_tuple,
	.index_build_range_scan = heapam_index_build_range_scan,
	.index_validate_scan = heapam_index_validate_scan,

	.relation_size = table_block_relation_size,
	.relation_needs_toast_table = heapam_relation_needs_toast_table,
	.relation_toast_am = heapam_relation_toast_am,
	.relation_fetch_toast_slice = heap_fetch_toast_slice,

	.relation_estimate_size = heapam_estimate_rel_size,

	.scan_bitmap_next_tuple = heapam_scan_bitmap_next_tuple,
	.scan_sample_next_block = heapam_scan_sample_next_block,
	.scan_sample_next_tuple = heapam_scan_sample_next_tuple
}

注册的接口处理函数

接口操作源码观察回调实现
元组槽已注册处理函数;适用条件限制slot_callbacksheapam_slot_callbacks
开始扫描已注册处理函数;适用条件限制scan_beginheap_beginscan
初始化并行扫描已注册处理函数;适用条件限制parallelscan_initializetable_block_parallelscan_initialize
开始索引查找已注册处理函数;适用条件限制index_fetch_beginheapam_index_fetch_begin
获取指定元组已注册处理函数;适用条件限制index_fetch_tupleheapam_index_fetch_tuple
插入元组已注册处理函数;适用条件限制tuple_insertheapam_tuple_insert
更新元组已注册处理函数;适用条件限制tuple_updateheapam_tuple_update
删除元组已注册处理函数;适用条件限制tuple_deleteheapam_tuple_delete
对关系执行 VACUUM已注册处理函数;适用条件限制relation_vacuumheap_vacuum_rel
分析数据块已注册处理函数;适用条件限制scan_analyze_next_blockheapam_scan_analyze_next_block
TOAST 判定已注册处理函数;适用条件限制relation_needs_toast_tableheapam_relation_needs_toast_table

手册定义

第 62 章. Table Access Method Interface Definition

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

每个表访问方法都由系统目录 pg_am 中的一行描述。pg_am 条目指定了该表访问方法的名称以及一个处理器函数。这些条目可以通过CREATE ACCESS METHOD和DROP 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 文件。

实现访问方法时,通常需要实现专用的元组表槽位类型(参见 src/include/executor/tuptable.h),使访问方法之外的代码可以持有该方法的元组引用,并访问元组各列。

目前,AM 实际存储数据的方式所受限制相当少。例如,可以使用 postgres 的共享缓冲区缓存,但这并非必需。如果使用它,那么采用 PostgreSQL 在第 66.6 节中描述的标准页面布局通常是有意义的。

表访问方法 API 目前的一项较大限制是:若访问方法希望支持修改操作和/或索引,每个元组必须有一个由块号和项号组成的元组标识符 TID(另见第 66.6 节)。TID 各部分不必具有与 heap 中完全相同的含义;但如果要支持可选的位图扫描,块号就需要提供局部性。

为保证崩溃安全,AM 可以使用 postgres 的WAL,也可以使用自定义实现。如果选择了 WAL,可以使用通用 WAL 记录,也可以实现一个自定义 WAL 资源管理器。

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

开发新的表访问方法时,可以参照 src/backend/access/heap/heapam_handler.c 中现有的堆实现,了解实现细节。

相关条目

文档与源码

来源构建
版本
18.6
构建
PostgreSQL 18.6 source archive
来源指纹
555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f

版本比较

PostgreSQL 19 → 20: 属性变化。

以下差异保留原始字段名与英文源描述。

--- PostgreSQL 19
+++ PostgreSQL 20
@@ -1,11 +1,11 @@
 {
   "callbacks": {
+    "fetch_tid": "heapam_fetch_tid",
     "index_build_range_scan": "heapam_index_build_range_scan",
     "index_delete_tuples": "heap_index_delete_tuples",
-    "index_fetch_begin": "heapam_index_fetch_begin",
-    "index_fetch_end": "heapam_index_fetch_end",
-    "index_fetch_reset": "heapam_index_fetch_reset",
-    "index_fetch_tuple": "heapam_index_fetch_tuple",
+    "index_scan_begin": "heapam_index_scan_begin",
+    "index_scan_end": "heapam_index_scan_end",
+    "index_scan_reset": "heapam_index_scan_reset",
     "index_validate_scan": "heapam_index_validate_scan",
     "multi_insert": "heap_multi_insert",
     "parallelscan_estimate": "table_block_parallelscan_estimate",

比较已记录的接口与属性,排除来源指纹和构建元数据。某个样本中没有记录,不能据此判断实际引入或移除的版本。

导出 JSON · 返回Table AM · 收录范围为 PostgreSQL 12 至 20;最早采样版本不一定是实际引入版本。