Hi, Right now pg_waldump just prints whether the message is transactional or not and its size. That doesn't help much to understand the message itself. If it prints the contents of a logical WAL message, it helps debugging logical replication related problems. Prefix is a null-terminated ASCII string, so no problem printing that. Even the contents can be printed as a series of hex bytes. Here's a patch to do that.
I tested this manually as below postgres=# select pg_logical_emit_message(false, 'some_prefix', 'some message'::text); pg_logical_emit_message ------------------------- 0/1570658 (1 row) $> pg_waldump --start 0/1570600 -p data/ first record is after 0/1570600, at 0/1570608, skipping over 8 bytes rmgr: LogicalMessage len (rec/tot): 74/ 74, tx: 0, lsn: 0/01570608, prev 0/015705D0, desc: MESSAGE nontransactional message size 12 bytes, prefix some_prefix; mesage: 73 6F 6D 65 20 6D 65 73 73 61 67 65 rmgr: Standby len (rec/tot): 50/ 50, tx: 0, lsn: 0/01570658, prev 0/01570608, desc: RUNNING_XACTS nextXid 504 latestCompletedXid 503 oldestRunningXid 504 pg_waldump: fatal: error in WAL record at 0/1570658: invalid record length at 0/1570690: wanted 24, got 0 I didn't find any tests for pg_waldump to test its output, so haven't added one in the patch. -- Best Wishes, Ashutosh Bapat
From 1547277944f7aceb1d5b0a3ae46ec2acf02f3b06 Mon Sep 17 00:00:00 2001 From: Ashutosh Bapat <ashutosh.ba...@2ndquadrant.com> Date: Tue, 18 Aug 2020 11:05:29 +0530 Subject: [PATCH] Print prefix and logical WAL message content in pg_waldump Print logical WAL message prefix which is a null terminated ASCII string. Print the actual message as a space separated hex byte string since it may contain binary data. This is useful for debugging purposes. Ashutosh Bapat --- src/backend/access/rmgrdesc/logicalmsgdesc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/backend/access/rmgrdesc/logicalmsgdesc.c b/src/backend/access/rmgrdesc/logicalmsgdesc.c index bff298c928..fdd03362e7 100644 --- a/src/backend/access/rmgrdesc/logicalmsgdesc.c +++ b/src/backend/access/rmgrdesc/logicalmsgdesc.c @@ -24,10 +24,24 @@ logicalmsg_desc(StringInfo buf, XLogReaderState *record) if (info == XLOG_LOGICAL_MESSAGE) { xl_logical_message *xlrec = (xl_logical_message *) rec; + /* + * Per LogLogicalMessage() actual logical message follows a null-terminated prefix of length + * prefix_size. + */ + char *prefix = xlrec->message; + char *message = xlrec->message + xlrec->prefix_size; + int cnt; + char *sep = ""; - appendStringInfo(buf, "%s message size %zu bytes", + appendStringInfo(buf, "%s message size %zu bytes, prefix %s; mesage: ", xlrec->transactional ? "transactional" : "nontransactional", - xlrec->message_size); + xlrec->message_size, prefix); + /* Write actual message as a series of hex bytes. */ + for (cnt = 0; cnt < xlrec->message_size; cnt++) + { + appendStringInfo(buf, "%s%02X", sep, (unsigned char)message[cnt]); + sep = " "; + } } } -- 2.17.1