Add -f/--follow option to pg_xlogdump.

This is useful for seeing what WAL records are inserted in real-time, by
pointing pg_xlogdump to a live server.
This commit is contained in:
Heikki Linnakangas 2014-03-26 13:48:20 +02:00
parent 86cf41ed27
commit ce9bb92f8f
2 changed files with 39 additions and 3 deletions

View file

@ -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);

View file

@ -91,6 +91,17 @@ PostgreSQL documentation
</listitem>
</varlistentry>
<varlistentry>
<term><option>-f</option></term>
<term><option>--follow</option></term>
<listitem>
<para>
After reaching the end of valid WAL, keep polling once per second for
new WAL to appear.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-n <replaceable>limit</replaceable></option></term>
<term><option>--limit=<replaceable>limit</replaceable></option></term>