Postgresql 中文操作指南
Chapter 63. Table Access Method Interface Definition
本章说明了 Postgre SQL 核心系统和 table access methods (管理表格存储)之间的接口。除了此处指定的内容外,核心系统对这些访问方法的了解甚少,因此可以通过编写附加代码来开发全新的访问方法类型。
This chapter explains the interface between the core PostgreSQL system and table access methods, which manage the storage for tables. The core system knows little about these access methods beyond what is specified here, so it is possible to develop entirely new access method types by writing add-on code.
pg_am 系统目录中的某行会描述每个表访问方法。 pg_am 条目会指定表访问方法的一个名称和一个 handler function 。可以使用 CREATE ACCESS METHOD 和 DROP ACCESS METHOD SQL 命令创建或删除这些条目。
Each table access method is described by a row in the pg_am system catalog. The pg_am entry specifies a name and a handler function for the table access method. These entries can be created and deleted using the CREATE ACCESS METHOD and DROP ACCESS METHOD SQL commands.
必須宣告一个表访问方法处理程序函数,以接受一个 internal 类型的单一参数,并返回 table_am_handler 伪类型。参数是虚拟值,只是为了阻止从 SQL 命令直接调用处理程序函数。函数的结果必须是一个 TableAmRoutine 类型结构的指针,其中包含核心代码利用表访问方法所需要知道的一切。返回值需要具有服务器生存期,一般是通过在全局作用域中将其定义为 static const 变量来实现的。 TableAmRoutine 结构(也称为访问方法的 API struct )使用回调函数定义访问方法的行为。这些回调函数指向普通 C 函数的指针,并且在 SQL 级别不可见或不可调用。所有回调函数及其行为都是在 TableAmRoutine 结构中定义的(结构中的注释定义了回调函数的要求)。大多数回调函数都有封装函数,它们是基于表访问方法的使用者(而不是实现者)的角度来进行说明的。有关详细信息,请参考 src/include/access/tableam.h 文件。
A table access method handler function must be declared to accept a single argument of type internal and to return the pseudo-type table_am_handler. The argument is a dummy value that simply serves to prevent handler functions from being called directly from SQL commands. The result of the function must be a pointer to a struct of type TableAmRoutine, which contains everything that the core code needs to know to make use of the table access method. The return value needs to be of server lifetime, which is typically achieved by defining it as a static const variable in global scope. The TableAmRoutine struct, also called the access method’s API struct, defines the behavior of the access method using callbacks. These callbacks are pointers to plain C functions and are not visible or callable at the SQL level. All the callbacks and their behavior is defined in the TableAmRoutine structure (with comments inside the struct defining the requirements for callbacks). Most callbacks have wrapper functions, which are documented from the point of view of a user (rather than an implementor) of the table access method. For details, please refer to the src/include/access/tableam.h file.
为了实现一种访问方法,实现者通常需要实现元数据中特定的元组表槽类型(请参阅 src/include/executor/tuptable.h ),它允许元数据外部的代码保存访问方法元组的引用并访问元组的列。
To implement an access method, an implementor will typically need to implement an AM-specific type of tuple table slot (see src/include/executor/tuptable.h), which allows code outside the access method to hold references to tuples of the AM, and to access the columns of the tuple.
现阶段,AM 实际存储数据的方式相当不受限制。例如,可以使用 postgres 的共享缓冲区缓存,但此操作不是必需的。如果使用它,最好使用 Section 73.6 中描述的 PostgreSQL 标准页面布局。
Currently, the way an AM actually stores data is fairly unconstrained. For example, it’s possible, but not required, to use postgres' shared buffer cache. In case it is used, it likely makes sense to use PostgreSQL’s standard page layout as described in Section 73.6.
表访问方法 API 有一个相当大的约束,即:如果 AM 想要支持修订和/或索引,则当前需要每个元组具有一个由块号和项号组成的元组标识符 (TID)(另请参阅 Section 73.6 )。TID 的子部分不一定具有与 heap 相同的含义,但如果需要位图扫描支持(此功能是可选的),则块号需要提供局部性。
One fairly large constraint of the table access method API is that, currently, if the AM wants to support modifications and/or indexes, it is necessary for each tuple to have a tuple identifier (TID) consisting of a block number and an item number (see also Section 73.6). It is not strictly necessary that the sub-parts of TIDs have the same meaning they e.g., have for heap, but if bitmap scan support is desired (it is optional), the block number needs to provide locality.
为了保证崩溃安全性,AM 可以使用 postgres 的 WAL 或自定义实现。如果选择 WAL,可以使用 Generic WAL Records ,也可以实现 Custom WAL Resource Manager 。
For crash safety, an AM can use postgres' WAL, or a custom implementation. If WAL is chosen, either Generic WAL Records can be used, or a Custom WAL Resource Manager can be implemented.
为了以允许在单个事务内访问不同表访问方法的方式实现事务支持,可能需要与 src/backend/access/transam/xlog.c 中的机制紧密集成。
To implement transactional support in a manner that allows different table access methods be accessed within a single transaction, it likely is necessary to closely integrate with the machinery in src/backend/access/transam/xlog.c.
任何新 table access method 的开发人员都可以参考 src/backend/access/heap/heapam_handler.c 中现有的 heap 实现,以了解其实现详情。
Any developer of a new table access method can refer to the existing heap implementation present in src/backend/access/heap/heapam_handler.c for details of its implementation.