PostgreSQL Source Code git master
test_custom_rmgrs.c
Go to the documentation of this file.
1/*--------------------------------------------------------------------------
2 *
3 * test_custom_rmgrs.c
4 * Code for testing custom WAL resource managers.
5 *
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/test/modules/test_custom_rmgrs/test_custom_rmgrs.c
11 *
12 * Custom WAL resource manager for records containing a simple textual
13 * payload, no-op redo, and no decoding.
14 *
15 * -------------------------------------------------------------------------
16 */
17
18#include "postgres.h"
19
20#include "access/xlog.h"
22#include "access/xloginsert.h"
23#include "fmgr.h"
24#include "utils/pg_lsn.h"
25#include "varatt.h"
26
28
29/*
30 * test_custom_rmgrs WAL record message.
31 */
33{
34 Size message_size; /* size of the message */
35 char message[FLEXIBLE_ARRAY_MEMBER]; /* payload */
37
38#define SizeOfTestCustomRmgrsMessage (offsetof(xl_testcustomrmgrs_message, message))
39#define XLOG_TEST_CUSTOM_RMGRS_MESSAGE 0x00
40
41/*
42 * While developing or testing, use RM_EXPERIMENTAL_ID for rmid. For a real
43 * extension, reserve a new resource manager ID to avoid conflicting with
44 * other extensions; see:
45 * https://wiki.postgresql.org/wiki/CustomWALResourceManagers
46 */
47#define RM_TESTCUSTOMRMGRS_ID RM_EXPERIMENTAL_ID
48#define TESTCUSTOMRMGRS_NAME "test_custom_rmgrs"
49
50/* RMGR API, see xlog_internal.h */
53const char *testcustomrmgrs_identify(uint8 info);
54
57 .rm_redo = testcustomrmgrs_redo,
58 .rm_desc = testcustomrmgrs_desc,
59 .rm_identify = testcustomrmgrs_identify
60};
61
62/*
63 * Module load callback
64 */
65void
67{
68 /*
69 * In order to create our own custom resource manager, we have to be
70 * loaded via shared_preload_libraries. Otherwise, registration will fail.
71 */
73}
74
75/* RMGR API implementation */
76
77/*
78 * Redo is just a noop for this module, because we aren't testing recovery of
79 * any real structure.
80 */
81void
83{
84 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
85
87 elog(PANIC, "testcustomrmgrs_redo: unknown op code %u", info);
88}
89
90void
92{
93 char *rec = XLogRecGetData(record);
94 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
95
97 {
99
100 appendStringInfo(buf, "payload (%zu bytes): ", xlrec->message_size);
102 }
103}
104
105const char *
107{
109 return "TEST_CUSTOM_RMGRS_MESSAGE";
110
111 return NULL;
112}
113
114/*
115 * SQL function for writing a simple message into WAL with the help of custom
116 * WAL resource manager.
117 */
119Datum
121{
123 char *payload = VARDATA_ANY(arg);
125 XLogRecPtr lsn;
127
128 xlrec.message_size = len;
129
132 XLogRegisterData((char *) payload, len);
133
134 /* Let's mark this record as unimportant, just in case. */
136
138
139 PG_RETURN_LSN(lsn);
140}
uint8_t uint8
Definition: c.h:486
#define FLEXIBLE_ARRAY_MEMBER
Definition: c.h:420
size_t Size
Definition: c.h:562
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:225
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
void * arg
const void size_t len
#define PG_RETURN_LSN(x)
Definition: pg_lsn.h:34
static char * buf
Definition: pg_test_fsync.c:72
uintptr_t Datum
Definition: postgres.h:69
void RegisterCustomRmgr(RmgrId rmid, const RmgrData *rmgr)
Definition: rmgr.c:107
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
Definition: stringinfo.c:281
const char * rm_name
Definition: c.h:644
char message[FLEXIBLE_ARRAY_MEMBER]
void testcustomrmgrs_desc(StringInfo buf, XLogReaderState *record)
void _PG_init(void)
const char * testcustomrmgrs_identify(uint8 info)
static const RmgrData testcustomrmgrs_rmgr
PG_MODULE_MAGIC
Datum test_custom_rmgrs_insert_wal_record(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(test_custom_rmgrs_insert_wal_record)
#define XLOG_TEST_CUSTOM_RMGRS_MESSAGE
#define SizeOfTestCustomRmgrsMessage
#define RM_TESTCUSTOMRMGRS_ID
#define TESTCUSTOMRMGRS_NAME
void testcustomrmgrs_redo(XLogReaderState *record)
struct xl_testcustomrmgrs_message xl_testcustomrmgrs_message
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317
#define XLOG_MARK_UNIMPORTANT
Definition: xlog.h:155
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
void XLogRegisterData(const char *data, uint32 len)
Definition: xloginsert.c:364
void XLogBeginInsert(void)
Definition: xloginsert.c:149
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLR_INFO_MASK
Definition: xlogrecord.h:62