Hello. I'm occasionally annoyed by the behavior of pg_waldump that it shows all records in the specified segment before entering waiting state.
tail -f shows only the last few dozen lines at the start. This behavior I think is useful also for pg_waldump -f. It was as simple than expected as attached. Any thoughts, opinions? regards. -- Kyotaro Horiguchi NTT Open Source Software Center
diff --git a/src/bin/pg_waldump/pg_waldump.c b/src/bin/pg_waldump/pg_waldump.c index 31e99c2a6d..dacdb600bf 100644 --- a/src/bin/pg_waldump/pg_waldump.c +++ b/src/bin/pg_waldump/pg_waldump.c @@ -72,6 +72,8 @@ typedef struct XLogDumpStats #define fatal_error(...) do { pg_log_fatal(__VA_ARGS__); exit(EXIT_FAILURE); } while(0) +#define FOLLOW_START_LINES 20 + static void print_rmgr_list(void) { @@ -752,6 +754,10 @@ main(int argc, char **argv) XLogRecPtr first_record; char *waldir = NULL; char *errormsg; + XLogRecPtr last_recs[FOLLOW_START_LINES]; + int last_idx = 0; + bool storing; + bool rounded; static struct option long_options[] = { {"bkp-details", no_argument, NULL, 'b'}, @@ -1065,10 +1071,41 @@ main(int argc, char **argv) (uint32) (first_record >> 32), (uint32) first_record, (uint32) (first_record - private.startptr)); + storing = config.follow; + rounded = false; + for (;;) { /* try to read the next record */ record = XLogReadRecord(xlogreader_state, &errormsg); + + if (storing) + { + if (record) + { + /* remember LSNs of the last FOLLOW_START_LINES records */ + last_recs[last_idx++] = xlogreader_state->ReadRecPtr; + last_idx = last_idx % FOLLOW_START_LINES; + + if (last_idx == 0) + rounded = true; + } + else + { + XLogRecPtr startPtr; + + /* find the first record to show */ + if (!rounded) + startPtr = last_recs[0]; + else + startPtr = last_recs[last_idx]; + + XLogFindNextRecord(xlogreader_state, startPtr); + storing = false; + } + continue; + } + if (!record) { if (!config.follow || private.endptr_reached)