/*--------------------------------------------------------------------------
*
* test_custom_rmgrs . c
* Code for testing custom WAL resource managers .
*
* Portions Copyright ( c ) 1996 - 2025 , PostgreSQL Global Development Group
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* src / test / modules / test_custom_rmgrs / test_custom_rmgrs . c
*
* Custom WAL resource manager for records containing a simple textual
* payload , no - op redo , and no decoding .
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
#include "postgres.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "access/xloginsert.h"
#include "fmgr.h"
#include "utils/pg_lsn.h"
#include "varatt.h"
PG_MODULE_MAGIC;
/*
* test_custom_rmgrs WAL record message .
*/
typedef struct xl_testcustomrmgrs_message
{
Size message_size; /* size of the message */
char message[FLEXIBLE_ARRAY_MEMBER]; /* payload */
} xl_testcustomrmgrs_message;
#define SizeOfTestCustomRmgrsMessage (offsetof(xl_testcustomrmgrs_message, message))
#define XLOG_TEST_CUSTOM_RMGRS_MESSAGE 0 x00
/*
* While developing or testing , use RM_EXPERIMENTAL_ID for rmid . For a real
* extension , reserve a new resource manager ID to avoid conflicting with
* other extensions ; see :
* https : //wiki.postgresql.org/wiki/CustomWALResourceManagers
*/
#define RM_TESTCUSTOMRMGRS_ID RM_EXPERIMENTAL_ID
#define TESTCUSTOMRMGRS_NAME "test_custom_rmgrs"
/* RMGR API, see xlog_internal.h */
void testcustomrmgrs_redo(XLogReaderState *record);
void testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record);
const char *testcustomrmgrs_identify(uint8 info);
static const RmgrData testcustomrmgrs_rmgr = {
.rm_name = TESTCUSTOMRMGRS_NAME,
.rm_redo = testcustomrmgrs_redo,
.rm_desc = testcustomrmgrs_desc,
.rm_identify = testcustomrmgrs_identify
};
/*
* Module load callback
*/
void
_PG_init(void )
{
/*
* In order to create our own custom resource manager , we have to be
* loaded via shared_preload_libraries . Otherwise , registration will fail .
*/
RegisterCustomRmgr(RM_TESTCUSTOMRMGRS_ID, &testcustomrmgrs_rmgr);
}
/* RMGR API implementation */
/*
* Redo is just a noop for this module , because we aren ' t testing recovery of
* any real structure .
*/
void
testcustomrmgrs_redo(XLogReaderState *record)
{
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
if (info != XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
elog(PANIC, "testcustomrmgrs_redo: unknown op code %u" , info);
}
void
testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record)
{
char *rec = XLogRecGetData(record);
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
if (info == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
{
xl_testcustomrmgrs_message *xlrec = (xl_testcustomrmgrs_message *) rec;
appendStringInfo(buf, "payload (%zu bytes): " , xlrec->message_size);
appendBinaryStringInfo(buf, xlrec->message, xlrec->message_size);
}
}
const char *
testcustomrmgrs_identify(uint8 info)
{
if ((info & ~XLR_INFO_MASK) == XLOG_TEST_CUSTOM_RMGRS_MESSAGE)
return "TEST_CUSTOM_RMGRS_MESSAGE" ;
return NULL;
}
/*
* SQL function for writing a simple message into WAL with the help of custom
* WAL resource manager .
*/
PG_FUNCTION_INFO_V1(test_custom_rmgrs_insert_wal_record);
Datum
test_custom_rmgrs_insert_wal_record(PG_FUNCTION_ARGS)
{
text *arg = PG_GETARG_TEXT_PP(0 );
char *payload = VARDATA_ANY(arg);
Size len = VARSIZE_ANY_EXHDR(arg);
XLogRecPtr lsn;
xl_testcustomrmgrs_message xlrec;
xlrec.message_size = len;
XLogBeginInsert();
XLogRegisterData(&xlrec, SizeOfTestCustomRmgrsMessage);
XLogRegisterData(payload, len);
/* Let's mark this record as unimportant, just in case. */
XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT);
lsn = XLogInsert(RM_TESTCUSTOMRMGRS_ID, XLOG_TEST_CUSTOM_RMGRS_MESSAGE);
PG_RETURN_LSN(lsn);
}
Messung V0.5 in Prozent C=85 H=100 G=92
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland