v5-0001-pg_waldump-emit-stats-when-interrupted-with-SIGIN.patch
application/octet-stream
Filename: v5-0001-pg_waldump-emit-stats-when-interrupted-with-SIGIN.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v5-0001
Subject: pg_waldump: emit stats when interrupted with SIGINT
| File | + | − |
|---|---|---|
| doc/src/sgml/ref/pg_waldump.sgml | 9 | 0 |
| src/bin/pg_waldump/pg_waldump.c | 30 | 0 |
From 29c3daacd8032e25e671422648cf4afc839a9c76 Mon Sep 17 00:00:00 2001
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
Date: Sun, 28 Nov 2021 06:27:05 +0000
Subject: [PATCH v5] pg_waldump: emit stats when interrupted with SIGINT
Currently, pg_waldump doesn't display WAL statistics if it gets
interrupted/terminated with SIGINT before reaching the end of WAL
although it accumulates statistics as of termination. This
behavior makes --stats with --follow option to appear as
blocking or hang even though the statistics are computed in the
background by the pg_waldump.
This patch traps the SIGINT signal and prints the accumulated
statistics as of the termination.
---
doc/src/sgml/ref/pg_waldump.sgml | 9 +++++++++
src/bin/pg_waldump/pg_waldump.c | 30 ++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/doc/src/sgml/ref/pg_waldump.sgml b/doc/src/sgml/ref/pg_waldump.sgml
index 432254d2d5..1a48288041 100644
--- a/doc/src/sgml/ref/pg_waldump.sgml
+++ b/doc/src/sgml/ref/pg_waldump.sgml
@@ -202,6 +202,15 @@ PostgreSQL documentation
full-page images) instead of individual records. Optionally
generate statistics per-record instead of per-rmgr.
</para>
+
+ <para>
+ If the <application>pg_waldump</application> is terminated or
+ interrupted with signal <systemitem>SIGINT</systemitem> while
+ calculating the statistics, the summary statistics computed as
+ of the termination will be displayed in non-quiet mode or without
+ <option>--quiet</option>.
+ </para>
+
</listitem>
</varlistentry>
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c
index 4690e0f515..699b7d567b 100644
--- a/src/bin/pg_waldump/pg_waldump.c
+++ b/src/bin/pg_waldump/pg_waldump.c
@@ -13,6 +13,7 @@
#include "postgres.h"
#include <dirent.h>
+#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -28,6 +29,7 @@
static const char *progname;
static int WalSegSz;
+static volatile sig_atomic_t time_to_stop = false;
typedef struct XLogDumpPrivate
{
@@ -67,12 +69,20 @@ typedef struct Stats
typedef struct XLogDumpStats
{
uint64 count;
+ XLogRecPtr startptr;
+ XLogRecPtr endptr;
Stats rmgr_stats[RM_NEXT_ID];
Stats record_stats[RM_NEXT_ID][MAX_XLINFO_TYPES];
} XLogDumpStats;
#define fatal_error(...) do { pg_log_fatal(__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
+static void
+sigint_handler(int signum)
+{
+ time_to_stop = true;
+}
+
static void
print_rmgr_list(void)
{
@@ -645,6 +655,9 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
}
total_len = total_rec_len + total_fpi_len;
+ printf("Summary of the WAL statistics computed between LSN %X/%X and LSN %X/%X is:\n",
+ LSN_FORMAT_ARGS(stats->startptr), LSN_FORMAT_ARGS(stats->endptr));
+
/*
* 27 is strlen("Transaction/COMMIT_PREPARED"), 20 is strlen(2^64), 8 is
* strlen("(100.00%)")
@@ -794,6 +807,8 @@ main(int argc, char **argv)
int option;
int optindex = 0;
+ pqsignal(SIGINT, sigint_handler);
+
pg_logging_init(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_waldump"));
progname = get_progname(argv[0]);
@@ -833,6 +848,9 @@ main(int argc, char **argv)
config.stats = false;
config.stats_per_record = false;
+ stats.startptr = InvalidXLogRecPtr;
+ stats.endptr = InvalidXLogRecPtr;
+
if (argc <= 1)
{
pg_log_error("no arguments specified");
@@ -1084,8 +1102,14 @@ main(int argc, char **argv)
LSN_FORMAT_ARGS(first_record),
(uint32) (first_record - private.startptr));
+ if (config.stats == true && !config.quiet)
+ stats.startptr = first_record;
+
for (;;)
{
+ if (time_to_stop)
+ break;
+
/* try to read the next record */
record = XLogReadRecord(xlogreader_state, &errormsg);
if (!record)
@@ -1112,7 +1136,10 @@ main(int argc, char **argv)
if (!config.quiet)
{
if (config.stats == true)
+ {
XLogDumpCountRecord(&config, &stats, xlogreader_state);
+ stats.endptr = xlogreader_state->EndRecPtr;
+ }
else
XLogDumpDisplayRecord(&config, xlogreader_state);
}
@@ -1127,6 +1154,9 @@ main(int argc, char **argv)
if (config.stats == true && !config.quiet)
XLogDumpDisplayStats(&config, &stats);
+ if (time_to_stop)
+ return EXIT_FAILURE;
+
if (errormsg)
fatal_error("error in WAL record at %X/%X: %s",
LSN_FORMAT_ARGS(xlogreader_state->ReadRecPtr),
--
2.25.1