Глава 63. Пользовательские менеджеры ресурсов WAL
В этой главе описывается интерфейс взаимодействия ядра PostgreSQL с пользовательскими менеджерами ресурсов WAL, используя который расширения могут непосредственно интегрировать свои объекты в WAL.
Расширениям, особенно реализующим табличные методы доступа или индексные методы доступа, может потребоваться использовать WAL для восстановления, репликации и/или логического декодирования. Пользовательские менеджеры ресурсов представляют собой более гибкую альтернативу унифицированным записям WAL (которые игнорируются при логическом декодировании), но реализовать их в расширениях сложнее.
Чтобы создать новый пользовательский менеджер ресурсов WAL, сначала определите структуру RmgrData с реализациями методов менеджера ресурсов. Подробнее она описывается в src/backend/access/transam/README и в src/include/access/xlog_internal.h в исходном коде PostgreSQL.
/*
* Таблица методов для менеджеров ресурсов.
*
* Эта структура должна синхронизироваться с определением 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, чтобы он загружался при запуске PostgreSQL.
Примечание
Расширение должно оставаться в shared_preload_libraries до тех пор, пока в системе могут быть какие-либо пользовательские записи WAL. В противном случае сервер PostgreSQL не сможет применять или декодировать пользовательские записи WAL, вследствие чего он может не запуститься.