0001-Make-it-easy-to-print-LSN.patch
text/x-patch
Filename: 0001-Make-it-easy-to-print-LSN.patch
Type: text/x-patch
Part: 0
Message:
Re: Printing LSN made easy
Patch
Format: format-patch
Series: patch 0001
Subject: Make it easy to print LSN
| File | + | − |
|---|---|---|
| contrib/pageinspect/rawpage.c | 1 | 2 |
| src/backend/access/rmgrdesc/replorigindesc.c | 2 | 3 |
| src/backend/access/rmgrdesc/xlogdesc.c | 1 | 2 |
| src/backend/access/transam/xlog.c | 5 | 3 |
| src/backend/utils/adt/pg_lsn.c | 36 | 13 |
| src/include/access/xlogdefs.h | 7 | 0 |
| src/include/utils/pg_lsn.h | 3 | 0 |
From 698e481f5f55b967b5c60dba4bc577f8baa20ff4 Mon Sep 17 00:00:00 2001
From: Ashutosh Bapat <ashutosh.bapat@2ndquadrant.com>
Date: Fri, 16 Oct 2020 17:09:29 +0530
Subject: [PATCH] Make it easy to print LSN
The commit introduces following macros and functions to make it easy to
use LSNs in printf variants, elog, ereport and appendStringInfo
variants.
LSN_FORMAT - macro representing the format in which LSN is printed
LSN_FORMAT_ARG - macro to pass LSN as an argument to the above format
pg_lsn_out_internal - a function which returns palloc'ed char array
containing string representation of given LSN.
pg_lsn_out_buffer - similar to above but accepts and returns a char
array of size (MAXPG_LSNLEN + 1)
The commit also has some example usages of these.
Ashutosh Bapat
---
contrib/pageinspect/rawpage.c | 3 +-
src/backend/access/rmgrdesc/replorigindesc.c | 5 +-
src/backend/access/rmgrdesc/xlogdesc.c | 3 +-
src/backend/access/transam/xlog.c | 8 ++--
src/backend/utils/adt/pg_lsn.c | 49 ++++++++++++++------
src/include/access/xlogdefs.h | 7 +++
src/include/utils/pg_lsn.h | 3 ++
7 files changed, 55 insertions(+), 23 deletions(-)
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index c0181506a5..2cd055a5f0 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -261,8 +261,7 @@ page_header(PG_FUNCTION_ARGS)
{
char lsnchar[64];
- snprintf(lsnchar, sizeof(lsnchar), "%X/%X",
- (uint32) (lsn >> 32), (uint32) lsn);
+ snprintf(lsnchar, sizeof(lsnchar), LSN_FORMAT, LSN_FORMAT_ARG(lsn));
values[0] = CStringGetTextDatum(lsnchar);
}
else
diff --git a/src/backend/access/rmgrdesc/replorigindesc.c b/src/backend/access/rmgrdesc/replorigindesc.c
index 19e14f910b..a3f49b5750 100644
--- a/src/backend/access/rmgrdesc/replorigindesc.c
+++ b/src/backend/access/rmgrdesc/replorigindesc.c
@@ -29,10 +29,9 @@ replorigin_desc(StringInfo buf, XLogReaderState *record)
xlrec = (xl_replorigin_set *) rec;
- appendStringInfo(buf, "set %u; lsn %X/%X; force: %d",
+ appendStringInfo(buf, "set %u; lsn " LSN_FORMAT "; force: %d",
xlrec->node_id,
- (uint32) (xlrec->remote_lsn >> 32),
- (uint32) xlrec->remote_lsn,
+ LSN_FORMAT_ARG(xlrec->remote_lsn),
xlrec->force);
break;
}
diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c
index 3200f777f5..22bdae5d9a 100644
--- a/src/backend/access/rmgrdesc/xlogdesc.c
+++ b/src/backend/access/rmgrdesc/xlogdesc.c
@@ -89,8 +89,7 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
XLogRecPtr startpoint;
memcpy(&startpoint, rec, sizeof(XLogRecPtr));
- appendStringInfo(buf, "%X/%X",
- (uint32) (startpoint >> 32), (uint32) startpoint);
+ appendStringInfo(buf, LSN_FORMAT, LSN_FORMAT_ARG(startpoint));
}
else if (info == XLOG_PARAMETER_CHANGE)
{
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13f1d8c3dc..2436af5244 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -79,6 +79,7 @@
#include "utils/pg_rusage.h"
#include "utils/snapmgr.h"
#include "utils/timestamp.h"
+#include "utils/pg_lsn.h"
extern uint32 bootstrap_data_checksum_version;
@@ -5886,15 +5887,16 @@ recoveryStopsAfter(XLogReaderState *record)
recoveryTargetInclusive &&
record->ReadRecPtr >= recoveryTargetLSN)
{
+ char buf[MAXPG_LSNLEN + 1];
+
recoveryStopAfter = true;
recoveryStopXid = InvalidTransactionId;
recoveryStopLSN = record->ReadRecPtr;
recoveryStopTime = 0;
recoveryStopName[0] = '\0';
ereport(LOG,
- (errmsg("recovery stopping after WAL location (LSN) \"%X/%X\"",
- (uint32) (recoveryStopLSN >> 32),
- (uint32) recoveryStopLSN)));
+ (errmsg("recovery stopping after WAL location (LSN) \"%s\"",
+ pg_lsn_out_buffer(recoveryStopLSN, buf))));
return true;
}
diff --git a/src/backend/utils/adt/pg_lsn.c b/src/backend/utils/adt/pg_lsn.c
index ad0a7bd869..403a20c568 100644
--- a/src/backend/utils/adt/pg_lsn.c
+++ b/src/backend/utils/adt/pg_lsn.c
@@ -19,7 +19,6 @@
#include "utils/numeric.h"
#include "utils/pg_lsn.h"
-#define MAXPG_LSNLEN 17
#define MAXPG_LSNCOMPONENT 8
/*----------------------------------------------------------
@@ -81,18 +80,7 @@ Datum
pg_lsn_out(PG_FUNCTION_ARGS)
{
XLogRecPtr lsn = PG_GETARG_LSN(0);
- char buf[MAXPG_LSNLEN + 1];
- char *result;
- uint32 id,
- off;
-
- /* Decode ID and offset */
- id = (uint32) (lsn >> 32);
- off = (uint32) lsn;
-
- snprintf(buf, sizeof buf, "%X/%X", id, off);
- result = pstrdup(buf);
- PG_RETURN_CSTRING(result);
+ PG_RETURN_CSTRING(pg_lsn_out_internal(lsn));
}
Datum
@@ -317,3 +305,38 @@ pg_lsn_mii(PG_FUNCTION_ARGS)
/* Convert to pg_lsn */
return DirectFunctionCall1(numeric_pg_lsn, res);
}
+
+/*
+ * pg_lsn_out_internal
+ *
+ * Returns palloc'ed string representation of an LSN. Used by pg_lsn_out() but
+ * is useful to print LSN in non-performance critical paths. The caller may
+ * pfree the returned memory chunk.
+ */
+char *
+pg_lsn_out_internal(XLogRecPtr lsn)
+{
+ char buf[MAXPG_LSNLEN + 1];
+
+ snprintf(buf, sizeof(buf), LSN_FORMAT, LSN_FORMAT_ARG(lsn));
+
+ return pstrdup(buf);
+}
+
+/*
+ * pg_lsn_out_buffer
+ *
+ * Similar to the above function but saves the string representation of LSN in
+ * the given buffer which is expected to be at least MAXPG_LSNLEN long. It can
+ * be used in performance critical paths to avoid expensive memory allocation.
+ *
+ * The function returns pointer to the input buffer so that it can be used in
+ * printf variants.
+ */
+char *
+pg_lsn_out_buffer(XLogRecPtr lsn, char *buf)
+{
+ snprintf(buf, sizeof(buf), LSN_FORMAT, LSN_FORMAT_ARG(lsn));
+
+ return buf;
+}
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index e1f5812213..c704ca2454 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -35,6 +35,13 @@ typedef uint64 XLogRecPtr;
*/
#define FirstNormalUnloggedLSN ((XLogRecPtr) 1000)
+/* Handy macros to print LSN */
+#define LSN_FORMAT "%X/%X"
+#define LSN_FORMAT_ARG(lsn) (uint32) ((lsn) >> 32), (uint32) (lsn)
+
+/* Maximum length of string representation of an LSN */
+#define MAXPG_LSNLEN 17
+
/*
* XLogSegNo - physical log file sequence number.
*/
diff --git a/src/include/utils/pg_lsn.h b/src/include/utils/pg_lsn.h
index 25d6c5b38e..7a8637d2bd 100644
--- a/src/include/utils/pg_lsn.h
+++ b/src/include/utils/pg_lsn.h
@@ -26,4 +26,7 @@
extern XLogRecPtr pg_lsn_in_internal(const char *str, bool *have_error);
+extern char *pg_lsn_out_internal(XLogRecPtr lsn);
+extern char *pg_lsn_out_buffer(XLogRecPtr lsn, char *buf);
+
#endif /* PG_LSN_H */
--
2.17.1