diff --git a/contrib/pg_xlogdump/pg_xlogdump.c b/contrib/pg_xlogdump/pg_xlogdump.c
index 024ab01efa0..e947696429d 100644
--- a/contrib/pg_xlogdump/pg_xlogdump.c
+++ b/contrib/pg_xlogdump/pg_xlogdump.c
@@ -32,6 +32,7 @@ typedef struct XLogDumpPrivate
char *inpath;
XLogRecPtr startptr;
XLogRecPtr endptr;
+ bool endptr_reached;
} XLogDumpPrivate;
typedef struct XLogDumpConfig
@@ -40,6 +41,7 @@ typedef struct XLogDumpConfig
bool bkp_details;
int stop_after_records;
int already_displayed_records;
+ bool follow;
/* filter options */
int filter_by_rmgr;
@@ -308,7 +310,10 @@ XLogDumpReadPage(XLogReaderState *state, XLogRecPtr targetPagePtr, int reqLen,
else if (targetPagePtr + reqLen <= private->endptr)
count = private->endptr - targetPagePtr;
else
+ {
+ private->endptr_reached = true;
return -1;
+ }
}
XLogDumpXLogRead(private->inpath, private->timeline, targetPagePtr,
@@ -386,6 +391,7 @@ usage(void)
printf("\nOptions:\n");
printf(" -b, --bkp-details output detailed information about backup blocks\n");
printf(" -e, --end=RECPTR stop reading at log position RECPTR\n");
+ printf(" -f, --follow keep retrying after reaching end of WAL\n");
printf(" -n, --limit=N number of records to display\n");
printf(" -p, --path=PATH directory in which to find log segment files\n");
printf(" (default: ./pg_xlog)\n");
@@ -414,6 +420,7 @@ main(int argc, char **argv)
static struct option long_options[] = {
{"bkp-details", no_argument, NULL, 'b'},
{"end", required_argument, NULL, 'e'},
+ {"follow", no_argument, NULL, 'f'},
{"help", no_argument, NULL, '?'},
{"limit", required_argument, NULL, 'n'},
{"path", required_argument, NULL, 'p'},
@@ -436,10 +443,12 @@ main(int argc, char **argv)
private.timeline = 1;
private.startptr = InvalidXLogRecPtr;
private.endptr = InvalidXLogRecPtr;
+ private.endptr_reached = false;
config.bkp_details = false;
config.stop_after_records = -1;
config.already_displayed_records = 0;
+ config.follow = false;
config.filter_by_rmgr = -1;
config.filter_by_xid = InvalidTransactionId;
config.filter_by_xid_enabled = false;
@@ -450,7 +459,7 @@ main(int argc, char **argv)
goto bad_argument;
}
- while ((option = getopt_long(argc, argv, "be:?n:p:r:s:t:Vx:",
+ while ((option = getopt_long(argc, argv, "be:?fn:p:r:s:t:Vx:",
long_options, &optindex)) != -1)
{
switch (option)
@@ -467,6 +476,9 @@ main(int argc, char **argv)
}
private.endptr = (uint64) xlogid << 32 | xrecoff;
break;
+ case 'f':
+ config.follow = true;
+ break;
case '?':
usage();
exit(EXIT_SUCCESS);
@@ -683,9 +695,22 @@ main(int argc, char **argv)
(uint32) (first_record >> 32), (uint32) first_record,
(uint32) (first_record - private.startptr));
- while ((record = XLogReadRecord(xlogreader_state, first_record, &errormsg)))
+ for (;;)
{
- /* continue after the last record */
+ /* try to read the next record */
+ record = XLogReadRecord(xlogreader_state, first_record, &errormsg);
+ if (!record)
+ {
+ if (!config.follow || private.endptr_reached)
+ break;
+ else
+ {
+ sleep(1);
+ continue;
+ }
+ }
+
+ /* after reading the first record, continue at next one */
first_record = InvalidXLogRecPtr;
XLogDumpDisplayRecord(&config, xlogreader_state->ReadRecPtr, record);
diff --git a/doc/src/sgml/pg_xlogdump.sgml b/doc/src/sgml/pg_xlogdump.sgml
index 17396221198..1d1a2cea870 100644
--- a/doc/src/sgml/pg_xlogdump.sgml
+++ b/doc/src/sgml/pg_xlogdump.sgml
@@ -91,6 +91,17 @@ PostgreSQL documentation
+
+
+
+
+
+ After reaching the end of valid WAL, keep polling once per second for
+ new WAL to appear.
+
+
+
+