Пользовательские менеджеры ресурсов WAL

В этой граве рассматривается интерфейс между ядром системы QHB и пользовательскими менеджерами ресурсов WAL, позволяющий расширениям напрямую интегрировать свои объекты в WAL.

Расширению, особенно реализующему табличные методы доступа или индексные методы доступа, может понадобиться использовать WAL для восстановления, репликации и/или логического декодирования. Пользовательские менеджеры ресурсов представляют собой более гибкой альтернативу типовым записям WAL (которые не поддерживают логическое декодирование), но реализовать их в расширении сложнее.

Чтобы создать новый пользовательский менеджер ресурсов WAL, сначала определите структуру RmgrData с реализациями методов менеджера ресурсов.

/*
 * Таблица методов для менеджеров ресурсов.
 *
 * Эта структура должна быть постоянно синхронизирована с определением PG_RMGR в
 * файле rmgr.c.
 *
 * Метод rm_identify должен вернуть имя записи, исходя из xl_info (без ссылки на
 * rmid). Например, XLOG_BTREE_VACUUM мог бы быть назван "VACUUM". Затем может быть
 * вызван метод rm_desc для получения дополнительной информации о записи, если
 * таковая имеется (например, последний блок).
 *
 * Метод rm_mask принимает на вход страницу, модифицированную менеджером ресурсов, и
 * маскирует биты, которые не должны помечаться при проверке wal_consistency_checking.
 *
 * RmgrTable[] индексируется значениями RmgrId (см. rmgrlist.h). Если rm_name имеет
 * значение NULL, соответствующая запись RmgrTable считается недопустимой.
 */
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;

Затем зарегистрируйте свой новый менеджер ресурсов.

/*
 * Регистрация нового пользовательского менеджера ресурсов WAL.
 *
 * Идентификаторы менеджеров ресурсов должны быть глобально уникальными среди всех
 * расширений. Зарезервируйте уникальный RmgrId для вашего расширения на странице
 * https://wiki.postgresql.org/wiki/CustomWALResourceManagers, чтобы избежать
 * конфликтов с другими разработчиками расширений. Во время разработки пользуйтесь
 * RM_EXPERIMENTAL_ID, чтобы не резервировать новые идентификаторы без необходимости.
 */
extern void RegisterCustomRmgr(RmgrId rmid, RmgrData *rmgr);

Функцию RegisterCustomRmgr следует вызывать из функции _PG_init модуля расширения. Во время разработки нового расширения в качестве rmid используйте RM_EXPERIMENTAL_ID. Когда будете готовы представить расширение пользователям, зарезервируйте новый идентификатор менеджера ресурсов на странице Custom WAL Resource Manager (Пользовательский менеджер ресурсов WAL).

Добавьте модуль расширения, реализующий пользовательский менеджер ресурсов, в список параметра shared_preload_libraries чтобы он загружался сразу при запуске QHB.

Примечание
Расширение должно оставаться в shared_preload_libraries до тех пор, пока в системе могут существовать какие-либо пользовательские записи WAL. В противном случае QHB не сможет применять или декодировать пользовательские записи WAL, из-за чего сервер может не запуститься.