Print WAL logical message contents in pg_waldump
authorAlvaro Herrera <[email protected]>
Thu, 10 Sep 2020 22:37:02 +0000 (19:37 -0300)
committerAlvaro Herrera <[email protected]>
Thu, 10 Sep 2020 22:37:02 +0000 (19:37 -0300)
This helps debuggability when looking at WAL streams containing logical
messages.

Author: Ashutosh Bapat <[email protected]>
Reviewed-by: Álvaro Herrera <[email protected]>
Discussion: https://postgr.es/m/CAExHW5sWx49rKmXbg5H1Xc1t+nRv9PaYKQmgw82HPt6vWDVmDg@mail.gmail.com

src/backend/access/rmgrdesc/logicalmsgdesc.c
src/backend/replication/logical/message.c
src/include/replication/message.h

index bff298c9287fe002ba7e1426b0cf5d1766264512..83ab93a24be9e1e22d8b6c011197ba3a8fd11bfe 100644 (file)
@@ -24,10 +24,21 @@ logicalmsg_desc(StringInfo buf, XLogReaderState *record)
    if (info == XLOG_LOGICAL_MESSAGE)
    {
        xl_logical_message *xlrec = (xl_logical_message *) rec;
+       char       *prefix = xlrec->message;
+       char       *message = xlrec->message + xlrec->prefix_size;
+       char       *sep = "";
 
-       appendStringInfo(buf, "%s message size %zu bytes",
-                        xlrec->transactional ? "transactional" : "nontransactional",
-                        xlrec->message_size);
+       Assert(prefix[xlrec->prefix_size] != '\0');
+
+       appendStringInfo(buf, "%s, prefix \"%s\"; payload (%zu bytes): ",
+                        xlrec->transactional ? "transactional" : "non-transactional",
+                        prefix, xlrec->message_size);
+       /* Write message payload as a series of hex bytes */
+       for (int cnt = 0; cnt < xlrec->message_size; cnt++)
+       {
+           appendStringInfo(buf, "%s%02X", sep, (unsigned char) message[cnt]);
+           sep = " ";
+       }
    }
 }
 
index db33cbe5a7a294e68aad271ef46b04725efa96bb..bd4b08543e66f30d296c5cc33d4bdbf0b9f07d44 100644 (file)
@@ -59,6 +59,7 @@ LogLogicalMessage(const char *prefix, const char *message, size_t size,
 
    xlrec.dbId = MyDatabaseId;
    xlrec.transactional = transactional;
+   /* trailing zero is critical; see logicalmsg_desc */
    xlrec.prefix_size = strlen(prefix) + 1;
    xlrec.message_size = size;
 
index 937addde48582b7c97f9665c3ec2b1edf967966a..e97891ebcafa7508b850088b82123b6dff3ca011 100644 (file)
@@ -23,9 +23,8 @@ typedef struct xl_logical_message
    bool        transactional;  /* is message transactional? */
    Size        prefix_size;    /* length of prefix */
    Size        message_size;   /* size of the message */
-   char        message[FLEXIBLE_ARRAY_MEMBER]; /* message including the null
-                                                * terminated prefix of length
-                                                * prefix_size */
+   /* payload, including null-terminated prefix of length prefix_size */
+   char        message[FLEXIBLE_ARRAY_MEMBER];
 } xl_logical_message;
 
 #define SizeOfLogicalMessage   (offsetof(xl_logical_message, message))