Skip to content

Commit f2c52ee

Browse files
committed
pg_waldump: Emit stats summary when interrupted by SIGINT
Previously, pg_waldump would not display its statistics summary if it got interrupted by SIGINT (or say a simple Ctrl+C). It gains with this commit a signal handler for SIGINT, trapping the signal to exit at the earliest convenience to allow a display of the stats summary before exiting. This makes the reports more interactive, similarly to strace -c. This new behavior makes the combination of the options --stats and --follow much more useful, so as the user will get a report for any invocation of pg_waldump in such a case. Information about the LSN range of the stats computed is added as a header to the report displayed. This implementation comes from a suggestion by Álvaro Herrera and myself, following a complaint by the author of this patch about --stats and --follow not being useful together originally. As documented, this is not supported on Windows, though its support would be possible by catching the terminal events associated to Ctrl+C, for example (this may require a more centralized implementation, as other tools could benefit from a common API). Author: Bharath Rupireddy Discussion: https://postgr.es/m/CALj2ACUUx3PcK2z9h0_m7vehreZAUbcmOky9WSEpe8TofhV=PQ@mail.gmail.com
1 parent 0df9641 commit f2c52ee

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

doc/src/sgml/ref/pg_waldump.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,15 @@ PostgreSQL documentation
202202
full-page images) instead of individual records. Optionally
203203
generate statistics per-record instead of per-rmgr.
204204
</para>
205+
206+
<para>
207+
If <application>pg_waldump</application> is terminated by signal
208+
<systemitem>SIGINT</systemitem>
209+
(<keycombo action="simul"><keycap>Control</keycap><keycap>C</keycap></keycombo>,
210+
the summary of the statistics computed is displayed up to the
211+
termination point. This operation is not supported on
212+
<productname>Windows</productname>.
213+
</para>
205214
</listitem>
206215
</varlistentry>
207216

src/bin/pg_waldump/pg_waldump.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "postgres.h"
1414

1515
#include <dirent.h>
16+
#include <signal.h>
1617
#include <sys/stat.h>
1718
#include <unistd.h>
1819

@@ -28,6 +29,7 @@
2829
static const char *progname;
2930

3031
static int WalSegSz;
32+
static volatile sig_atomic_t time_to_stop = false;
3133

3234
typedef struct XLogDumpPrivate
3335
{
@@ -67,12 +69,27 @@ typedef struct Stats
6769
typedef struct XLogDumpStats
6870
{
6971
uint64 count;
72+
XLogRecPtr startptr;
73+
XLogRecPtr endptr;
7074
Stats rmgr_stats[RM_NEXT_ID];
7175
Stats record_stats[RM_NEXT_ID][MAX_XLINFO_TYPES];
7276
} XLogDumpStats;
7377

7478
#define fatal_error(...) do { pg_log_fatal(__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
7579

80+
/*
81+
* When sigint is called, just tell the system to exit at the next possible
82+
* moment.
83+
*/
84+
#ifndef WIN32
85+
86+
static void
87+
sigint_handler(int signum)
88+
{
89+
time_to_stop = true;
90+
}
91+
#endif
92+
7693
static void
7794
print_rmgr_list(void)
7895
{
@@ -632,6 +649,12 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
632649
double rec_len_pct,
633650
fpi_len_pct;
634651

652+
/*
653+
* Leave if no stats have been computed yet, as tracked by the end LSN.
654+
*/
655+
if (XLogRecPtrIsInvalid(stats->endptr))
656+
return;
657+
635658
/*
636659
* Each row shows its percentages of the total, so make a first pass to
637660
* calculate column totals.
@@ -645,6 +668,9 @@ XLogDumpDisplayStats(XLogDumpConfig *config, XLogDumpStats *stats)
645668
}
646669
total_len = total_rec_len + total_fpi_len;
647670

671+
printf("WAL statistics between %X/%X and %X/%X:\n",
672+
LSN_FORMAT_ARGS(stats->startptr), LSN_FORMAT_ARGS(stats->endptr));
673+
648674
/*
649675
* 27 is strlen("Transaction/COMMIT_PREPARED"), 20 is strlen(2^64), 8 is
650676
* strlen("(100.00%)")
@@ -794,6 +820,10 @@ main(int argc, char **argv)
794820
int option;
795821
int optindex = 0;
796822

823+
#ifndef WIN32
824+
pqsignal(SIGINT, sigint_handler);
825+
#endif
826+
797827
pg_logging_init(argv[0]);
798828
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_waldump"));
799829
progname = get_progname(argv[0]);
@@ -833,6 +863,9 @@ main(int argc, char **argv)
833863
config.stats = false;
834864
config.stats_per_record = false;
835865

866+
stats.startptr = InvalidXLogRecPtr;
867+
stats.endptr = InvalidXLogRecPtr;
868+
836869
if (argc <= 1)
837870
{
838871
pg_log_error("no arguments specified");
@@ -1084,8 +1117,17 @@ main(int argc, char **argv)
10841117
LSN_FORMAT_ARGS(first_record),
10851118
(uint32) (first_record - private.startptr));
10861119

1120+
if (config.stats == true && !config.quiet)
1121+
stats.startptr = first_record;
1122+
10871123
for (;;)
10881124
{
1125+
if (time_to_stop)
1126+
{
1127+
/* We've been Ctrl-C'ed, so leave */
1128+
break;
1129+
}
1130+
10891131
/* try to read the next record */
10901132
record = XLogReadRecord(xlogreader_state, &errormsg);
10911133
if (!record)
@@ -1112,7 +1154,10 @@ main(int argc, char **argv)
11121154
if (!config.quiet)
11131155
{
11141156
if (config.stats == true)
1157+
{
11151158
XLogDumpCountRecord(&config, &stats, xlogreader_state);
1159+
stats.endptr = xlogreader_state->EndRecPtr;
1160+
}
11161161
else
11171162
XLogDumpDisplayRecord(&config, xlogreader_state);
11181163
}
@@ -1127,6 +1172,9 @@ main(int argc, char **argv)
11271172
if (config.stats == true && !config.quiet)
11281173
XLogDumpDisplayStats(&config, &stats);
11291174

1175+
if (time_to_stop)
1176+
exit(0);
1177+
11301178
if (errormsg)
11311179
fatal_error("error in WAL record at %X/%X: %s",
11321180
LSN_FORMAT_ARGS(xlogreader_state->ReadRecPtr),

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy