Глава 66. Пользовательские менеджеры ресурсов 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, вследствие чего он может не запуститься.