Skip to content

Commit afeacd2

Browse files
committed
Fix assertion failure at end of PITR.
InitXLogInsert() cannot be called in a critical section, because it allocates memory. But CreateCheckPoint() did that, when called for the end-of-recovery checkpoint by the startup process. In the passing, fix the scratch space allocation in InitXLogInsert to go to the right memory context. Also update the comment at InitXLOGAccess, which hasn't been totally accurate since hot standby was introduced (in a hot standby backend, InitXLOGAccess isn't called at backend startup). Reported by Michael Paquier
1 parent a5eb85e commit afeacd2

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/backend/access/transam/xlog.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7254,10 +7254,9 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
72547254
}
72557255

72567256
/*
7257-
* This must be called during startup of a backend process, except that
7258-
* it need not be called in a standalone backend (which does StartupXLOG
7259-
* instead). We need to initialize the local copies of ThisTimeLineID and
7260-
* RedoRecPtr.
7257+
* This must be called in a backend process before creating WAL records
7258+
* (except in a standalone backend, which does StartupXLOG instead). We need
7259+
* to initialize the local copies of ThisTimeLineID and RedoRecPtr.
72617260
*
72627261
* Note: before Postgres 8.0, we went to some effort to keep the postmaster
72637262
* process's copies of ThisTimeLineID and RedoRecPtr valid too. This was
@@ -7594,6 +7593,16 @@ CreateCheckPoint(int flags)
75947593
if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
75957594
elog(ERROR, "can't create a checkpoint during recovery");
75967595

7596+
/*
7597+
* Initialize InitXLogInsert working areas before entering the critical
7598+
* section. Normally, this is done by the first call to
7599+
* RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
7600+
* an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
7601+
* done below in a critical section, and InitXLogInsert cannot be called
7602+
* in a critical section.
7603+
*/
7604+
InitXLogInsert();
7605+
75977606
/*
75987607
* Acquire CheckpointLock to ensure only one checkpoint happens at a time.
75997608
* (This is just pro forma, since in the present system structure there is

src/backend/access/transam/xloginsert.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -891,5 +891,6 @@ InitXLogInsert(void)
891891
* Allocate a buffer to hold the header information for a WAL record.
892892
*/
893893
if (hdr_scratch == NULL)
894-
hdr_scratch = palloc0(HEADER_SCRATCH_SIZE);
894+
hdr_scratch = MemoryContextAllocZero(xloginsert_cxt,
895+
HEADER_SCRATCH_SIZE);
895896
}

0 commit comments

Comments
 (0)