Перейти к основному содержимому

Пользовательские диспетчеры ресурсов 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.
*
* Идентификаторы менеджеров ресурсов должны быть глобально уникальными для всех расширений.
* Обратитесь к https://wiki.postgresql.org/wiki/CustomWALResourceManagers, чтобы забронировать
* уникальный RmgrId для вашего расширения, чтобы избежать конфликтов с другими расширениями
* разработчиков. Во время разработки используйте RM_EXPERIMENTAL_ID, чтобы избежать ненужных
* резервирований идентификаторов.
*/
extern void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr);

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

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

Примечание:

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