Print WAL logical message contents in pg_waldump
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Thu, 10 Sep 2020 22:37:02 +0000 (19:37 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
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 <ashutosh.bapat@2ndquadrant.com>
Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
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))