mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
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
This commit is contained in:
parent
a5eb85eb62
commit
afeacd2748
@ -7254,10 +7254,9 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This must be called during startup of a backend process, except that
|
* This must be called in a backend process before creating WAL records
|
||||||
* it need not be called in a standalone backend (which does StartupXLOG
|
* (except in a standalone backend, which does StartupXLOG instead). We need
|
||||||
* instead). We need to initialize the local copies of ThisTimeLineID and
|
* to initialize the local copies of ThisTimeLineID and RedoRecPtr.
|
||||||
* RedoRecPtr.
|
|
||||||
*
|
*
|
||||||
* Note: before Postgres 8.0, we went to some effort to keep the postmaster
|
* Note: before Postgres 8.0, we went to some effort to keep the postmaster
|
||||||
* process's copies of ThisTimeLineID and RedoRecPtr valid too. This was
|
* process's copies of ThisTimeLineID and RedoRecPtr valid too. This was
|
||||||
@ -7594,6 +7593,16 @@ CreateCheckPoint(int flags)
|
|||||||
if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
|
if (RecoveryInProgress() && (flags & CHECKPOINT_END_OF_RECOVERY) == 0)
|
||||||
elog(ERROR, "can't create a checkpoint during recovery");
|
elog(ERROR, "can't create a checkpoint during recovery");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize InitXLogInsert working areas before entering the critical
|
||||||
|
* section. Normally, this is done by the first call to
|
||||||
|
* RecoveryInProgress() or LocalSetXLogInsertAllowed(), but when creating
|
||||||
|
* an end-of-recovery checkpoint, the LocalSetXLogInsertAllowed call is
|
||||||
|
* done below in a critical section, and InitXLogInsert cannot be called
|
||||||
|
* in a critical section.
|
||||||
|
*/
|
||||||
|
InitXLogInsert();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Acquire CheckpointLock to ensure only one checkpoint happens at a time.
|
* Acquire CheckpointLock to ensure only one checkpoint happens at a time.
|
||||||
* (This is just pro forma, since in the present system structure there is
|
* (This is just pro forma, since in the present system structure there is
|
||||||
|
@ -891,5 +891,6 @@ InitXLogInsert(void)
|
|||||||
* Allocate a buffer to hold the header information for a WAL record.
|
* Allocate a buffer to hold the header information for a WAL record.
|
||||||
*/
|
*/
|
||||||
if (hdr_scratch == NULL)
|
if (hdr_scratch == NULL)
|
||||||
hdr_scratch = palloc0(HEADER_SCRATCH_SIZE);
|
hdr_scratch = MemoryContextAllocZero(xloginsert_cxt,
|
||||||
|
HEADER_SCRATCH_SIZE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user