From 37a7587abb11b6ebcb82d0fbf3cff7505355a679 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Sat, 9 Apr 2022 13:14:03 +0000 Subject: [PATCH v2] Allow pg_walfile_{name, name_offset} to run in recovery Right now, pg_walfile_name and pg_walfile_name_offset don't run while the server is in recovery (standby, PITR/archive, crash). This reduces their usability if the server opens up for read-only connections in recovery. This patch enables them to compute WAL file name even in recovery with a timeline ID of last the last successfully replayed WAL record. They continue to use the timeline ID with which new WAL records are being inserted and flushed when not in recovery. --- doc/src/sgml/func.sgml | 8 +++++ src/backend/access/transam/xlogfuncs.c | 48 +++++++++++++++++--------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 5047e090db..0a08e34813 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -28442,6 +28442,14 @@ postgres=# SELECT * FROM pg_walfile_name_offset((pg_backup_stop()).lsn); needs to be archived. + + Both pg_walfile_name_offset and pg_walfile_name + use a timeline ID internally to the extract write-ahead log file name. When + not in recovery, they use the timeline ID with which new write-ahead log + records are being inserted and flushed. When in recovery, they use the + timeline ID of the last successfully replayed write-ahead log record. + + diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index b61ae6c0b4..795fd8d26b 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -44,6 +44,8 @@ static StringInfo label_file; static StringInfo tblspc_map_file; +static TimeLineID GetTLIForWALFileNameComputation(void); + /* * pg_backup_start: set up for taking an on-line backup dump * @@ -316,6 +318,30 @@ pg_last_wal_replay_lsn(PG_FUNCTION_ARGS) PG_RETURN_LSN(recptr); } +/* + * Get timeLine ID for computing WAL file name. + * + * When not in recovery, it returns the timeline into which new WAL is being + * inserted and flushed. + * + * When in crash/archive/standby recovery, it returns the timeline of the last + * WAL record that is successfully replayed. + */ +static TimeLineID +GetTLIForWALFileNameComputation(void) +{ + TimeLineID tli; + + if (RecoveryInProgress()) + (void) GetXLogReplayRecPtr(&tli); + else + tli = GetWALInsertionTimeLine(); + + Assert(tli > 0); + + return tli; +} + /* * Compute an xlog file name and decimal byte offset given a WAL location, * such as is returned by pg_backup_stop() or pg_switch_wal(). @@ -336,13 +362,9 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS) TupleDesc resultTupleDesc; HeapTuple resultHeapTuple; Datum result; + TimeLineID tli; - if (RecoveryInProgress()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("recovery is in progress"), - errhint("%s cannot be executed during recovery.", - "pg_walfile_name_offset()"))); + tli = GetTLIForWALFileNameComputation(); /* * Construct a tuple descriptor for the result row. This must match this @@ -360,8 +382,7 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS) * xlogfilename */ XLByteToPrevSeg(locationpoint, xlogsegno, wal_segment_size); - XLogFileName(xlogfilename, GetWALInsertionTimeLine(), xlogsegno, - wal_segment_size); + XLogFileName(xlogfilename, tli, xlogsegno, wal_segment_size); values[0] = CStringGetTextDatum(xlogfilename); isnull[0] = false; @@ -394,17 +415,12 @@ pg_walfile_name(PG_FUNCTION_ARGS) XLogSegNo xlogsegno; XLogRecPtr locationpoint = PG_GETARG_LSN(0); char xlogfilename[MAXFNAMELEN]; + TimeLineID tli; - if (RecoveryInProgress()) - ereport(ERROR, - (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("recovery is in progress"), - errhint("%s cannot be executed during recovery.", - "pg_walfile_name()"))); + tli = GetTLIForWALFileNameComputation(); XLByteToPrevSeg(locationpoint, xlogsegno, wal_segment_size); - XLogFileName(xlogfilename, GetWALInsertionTimeLine(), xlogsegno, - wal_segment_size); + XLogFileName(xlogfilename, tli, xlogsegno, wal_segment_size); PG_RETURN_TEXT_P(cstring_to_text(xlogfilename)); } -- 2.25.1