64.2. Gestores de recursos WAL personalizados #

Esta sección explica la interfaz entre el núcleo del sistema de PostgreSQL y los gestores de recursos WAL personalizados, los cuales permiten a las extensiones integrarse directamente con el WAL.

Una extensión, especialmente un método de acceso a tablas o un método de acceso a índices, puede necesitar utilizar WAL para la recuperación, la replicación y/o la decodificación lógica.

Para crear un nuevo gestor de recursos WAL personalizado, primero define una estructura RmgrData con implementaciones para los métodos del gestor de recursos. Consulta src/backend/access/transam/README y src/include/access/xlog_internal.h en el código fuente de PostgreSQL.

/*
 * Tabla de métodos para gestores de recursos.
 *
 * Esta estructura debe mantenerse sincronizada con la definición de PG_RMGR en
 * rmgr.c.
 *
 * rm_identify debe devolver un nombre para el registro basado en xl_info (sin
 * referencia al rmid). Por ejemplo, XLOG_BTREE_VACUUM se llamaría
 * "VACUUM". Luego se puede llamar a rm_desc para obtener detalles adicionales del
 * registro, si están disponibles (por ejemplo, el último bloque).
 *
 * rm_mask toma como entrada una página modificada por el gestor de recursos y enmascara
 * los bits que no deberían ser señalados por wal_consistency_checking.
 *
 * RmgrTable[] está indexado por valores de RmgrId (ver rmgrlist.h). Si rm_name es
 * NULL, la entrada correspondiente de RmgrTable se considera inválida.
 */
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;

El módulo src/test/modules/test_custom_rmgrs contiene un ejemplo funcional que demuestra el uso de los gestores de recursos WAL personalizados.

Luego, registra tu nuevo gestor de recursos.

/*
 * Registrar un nuevo gestor de recursos WAL personalizado.
 *
 * Los IDs de los gestores de recursos deben ser globalmente únicos en todas las extensiones. Consulta
 * https://wiki.postgresql.org/wiki/CustomWALResourceManagers para reservar un
 * RmgrId único para tu extensión, a fin de evitar conflictos con otros
 * desarrolladores de extensiones. Durante el desarrollo, usa RM_EXPERIMENTAL_ID para evitar reservar
 * innecesariamente un nuevo ID.
 */
extern void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr);

RegisterCustomRmgr debe ser llamado desde la función _PG_init del módulo de la extensión. Mientras desarrollas una nueva extensión, utiliza RM_EXPERIMENTAL_ID para rmid. Cuando estés listo para lanzar la extensión a los usuarios, reserva un nuevo ID de gestor de recursos en la página de Custom WAL Resource Manager.

Coloca el módulo de la extensión que implementa el gestor de recursos personalizado en shared_preload_libraries para que se cargue temprano durante el inicio de PostgreSQL.

Note

La extensión debe permanecer en shared_preload_libraries mientras puedan existir registros WAL personalizados en el sistema. De lo contrario, PostgreSQL no podrá aplicar ni decodificar los registros WAL personalizados, lo que podría impedir que el servidor se inicie.