mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
In checkpoint, move the check for in-progress xacts out of critical section.
GetVirtualXIDsDelayingChkpt calls palloc, which isn't safe in a critical section. I thought I covered this case with the exemption for the checkpointer, but CreateCheckPoint is also called from the startup process.
This commit is contained in:
@ -8076,6 +8076,42 @@ CreateCheckPoint(int flags)
|
|||||||
|
|
||||||
TRACE_POSTGRESQL_CHECKPOINT_START(flags);
|
TRACE_POSTGRESQL_CHECKPOINT_START(flags);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the other info we need for the checkpoint record.
|
||||||
|
*/
|
||||||
|
LWLockAcquire(XidGenLock, LW_SHARED);
|
||||||
|
checkPoint.nextXid = ShmemVariableCache->nextXid;
|
||||||
|
checkPoint.oldestXid = ShmemVariableCache->oldestXid;
|
||||||
|
checkPoint.oldestXidDB = ShmemVariableCache->oldestXidDB;
|
||||||
|
LWLockRelease(XidGenLock);
|
||||||
|
|
||||||
|
/* Increase XID epoch if we've wrapped around since last checkpoint */
|
||||||
|
checkPoint.nextXidEpoch = ControlFile->checkPointCopy.nextXidEpoch;
|
||||||
|
if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
|
||||||
|
checkPoint.nextXidEpoch++;
|
||||||
|
|
||||||
|
LWLockAcquire(OidGenLock, LW_SHARED);
|
||||||
|
checkPoint.nextOid = ShmemVariableCache->nextOid;
|
||||||
|
if (!shutdown)
|
||||||
|
checkPoint.nextOid += ShmemVariableCache->oidCount;
|
||||||
|
LWLockRelease(OidGenLock);
|
||||||
|
|
||||||
|
MultiXactGetCheckptMulti(shutdown,
|
||||||
|
&checkPoint.nextMulti,
|
||||||
|
&checkPoint.nextMultiOffset,
|
||||||
|
&checkPoint.oldestMulti,
|
||||||
|
&checkPoint.oldestMultiDB);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Having constructed the checkpoint record, ensure all shmem disk buffers
|
||||||
|
* and commit-log buffers are flushed to disk.
|
||||||
|
*
|
||||||
|
* This I/O could fail for various reasons. If so, we will fail to
|
||||||
|
* complete the checkpoint, but there is no reason to force a system
|
||||||
|
* panic. Accordingly, exit critical section while doing it.
|
||||||
|
*/
|
||||||
|
END_CRIT_SECTION();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In some cases there are groups of actions that must all occur on one
|
* In some cases there are groups of actions that must all occur on one
|
||||||
* side or the other of a checkpoint record. Before flushing the
|
* side or the other of a checkpoint record. Before flushing the
|
||||||
@ -8116,42 +8152,6 @@ CreateCheckPoint(int flags)
|
|||||||
}
|
}
|
||||||
pfree(vxids);
|
pfree(vxids);
|
||||||
|
|
||||||
/*
|
|
||||||
* Get the other info we need for the checkpoint record.
|
|
||||||
*/
|
|
||||||
LWLockAcquire(XidGenLock, LW_SHARED);
|
|
||||||
checkPoint.nextXid = ShmemVariableCache->nextXid;
|
|
||||||
checkPoint.oldestXid = ShmemVariableCache->oldestXid;
|
|
||||||
checkPoint.oldestXidDB = ShmemVariableCache->oldestXidDB;
|
|
||||||
LWLockRelease(XidGenLock);
|
|
||||||
|
|
||||||
/* Increase XID epoch if we've wrapped around since last checkpoint */
|
|
||||||
checkPoint.nextXidEpoch = ControlFile->checkPointCopy.nextXidEpoch;
|
|
||||||
if (checkPoint.nextXid < ControlFile->checkPointCopy.nextXid)
|
|
||||||
checkPoint.nextXidEpoch++;
|
|
||||||
|
|
||||||
LWLockAcquire(OidGenLock, LW_SHARED);
|
|
||||||
checkPoint.nextOid = ShmemVariableCache->nextOid;
|
|
||||||
if (!shutdown)
|
|
||||||
checkPoint.nextOid += ShmemVariableCache->oidCount;
|
|
||||||
LWLockRelease(OidGenLock);
|
|
||||||
|
|
||||||
MultiXactGetCheckptMulti(shutdown,
|
|
||||||
&checkPoint.nextMulti,
|
|
||||||
&checkPoint.nextMultiOffset,
|
|
||||||
&checkPoint.oldestMulti,
|
|
||||||
&checkPoint.oldestMultiDB);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Having constructed the checkpoint record, ensure all shmem disk buffers
|
|
||||||
* and commit-log buffers are flushed to disk.
|
|
||||||
*
|
|
||||||
* This I/O could fail for various reasons. If so, we will fail to
|
|
||||||
* complete the checkpoint, but there is no reason to force a system
|
|
||||||
* panic. Accordingly, exit critical section while doing it.
|
|
||||||
*/
|
|
||||||
END_CRIT_SECTION();
|
|
||||||
|
|
||||||
CheckPointGuts(checkPoint.redo, flags);
|
CheckPointGuts(checkPoint.redo, flags);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user