Postgresql 中文操作指南
Chapter 66. Custom WAL Resource Managers
本章介绍了核心 PostgreSQL 系统与自定义 WAL 资源管理器之间的界面,该界面使扩展能够直接与 WAL 集成。
This chapter explains the interface between the core PostgreSQL system and custom WAL resource managers, which enable extensions to integrate directly with the WAL.
扩展(尤其是 Table Access Method 或 Index Access Method )可能需要使用 WAL 进行恢复、复制和/或 Logical Decoding 。自定义资源管理器是 Generic WAL (不支持逻辑解码)的更灵活的替代方案,但对于扩展而言,其实现更复杂。
An extension, especially a Table Access Method or Index Access Method, may need to use WAL for recovery, replication, and/or Logical Decoding. Custom resource managers are a more flexible alternative to Generic WAL (which does not support logical decoding), but more complex for an extension to implement.
要想创建自定义 WAL 资源管理器,首先定义一个 RmgrData 结构,其中包含对资源管理器方法的实现。请参考 PostgreSQL 源中的 src/backend/access/transam/README 和 src/include/access/xlog_internal.h 。
To create a new custom WAL resource manager, first define an RmgrData structure with implementations for the resource manager methods. Refer to src/backend/access/transam/README and src/include/access/xlog_internal.h in the PostgreSQL source.
/*
* Method table for resource managers.
*
* This struct must be kept in sync with the PG_RMGR definition in
* rmgr.c.
*
* rm_identify must return a name for the record based on xl_info (without
* reference to the rmid). For example, XLOG_BTREE_VACUUM would be named
* "VACUUM". rm_desc can then be called to obtain additional detail for the
* record, if available (e.g. the last block).
*
* rm_mask takes as input a page modified by the resource manager and masks
* out bits that shouldn't be flagged by wal_consistency_checking.
*
* RmgrTable[] is indexed by RmgrId values (see rmgrlist.h). If rm_name is
* NULL, the corresponding RmgrTable entry is considered invalid.
*/
typedef struct RmgrData
{
const char *rm_name;
void (*rm_redo) (XLogReaderState *record);
void (*rm_desc) (StringInfo buf, XLogReaderState *record);
const char *(*rm_identify) (uint8 info);
void (*rm_startup) (void);
void (*rm_cleanup) (void);
void (*rm_mask) (char *pagedata, BlockNumber blkno);
void (*rm_decode) (struct LogicalDecodingContext *ctx,
struct XLogRecordBuffer *buf);
} RmgrData;
src/test/modules/test_custom_rmgrs 模块中包含一个可运行的示例,用以展示自定义 WAL 资源管理器的工作方式。
The src/test/modules/test_custom_rmgrs module contains a working example, which demonstrates usage of custom WAL resource managers.
然后,注册您的新资源管理器。
Then, register your new resource manager.
/*
* Register a new custom WAL resource manager.
*
* Resource manager IDs must be globally unique across all extensions. Refer
* to https://wiki.postgresql.org/wiki/CustomWALResourceManagers to reserve a
* unique RmgrId for your extension, to avoid conflicts with other extension
* developers. During development, use RM_EXPERIMENTAL_ID to avoid needlessly
* reserving a new ID.
*/
extern void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr);
必须从扩展模块的 RegisterCustomRmgr PG_init function. While developing a new extension, use _RM_EXPERIMENTAL_ID 中调用 rmid 。在准备好向用户发布扩展时,请在 Custom WAL Resource Manager 页面中预留一个新资源管理器 ID。
RegisterCustomRmgr must be called from the extension module’s PG_init function. While developing a new extension, use _RM_EXPERIMENTAL_ID for rmid. When you are ready to release the extension to users, reserve a new resource manager ID at the Custom WAL Resource Manager page.
将实现自定义资源管理器的扩展模块置于 shared_preload_libraries 中,以便在 PostgreSQL 启动期间尽早加载。
Place the extension module implementing the custom resource manager in shared_preload_libraries so that it will be loaded early during PostgreSQL startup.
Note
只要系统中仍存在任何自定义 WAL 记录,该扩展就必须保存在 shared_preload_libraries 中。否则 PostgreSQL 将无法应用或解码自定义 WAL 记录,进而可能阻止服务器启动。
The extension must remain in shared_preload_libraries as long as any custom WAL records may exist in the system. Otherwise PostgreSQL will not be able to apply or decode the custom WAL records, which may prevent the server from starting.