Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3d80a1e

Browse files
committed
Fix logic to skip checkpoint if no records have been inserted.
After the WAL format changes, the calculation of the size of a checkpointrecord became incorrect. Instead of trying to fix the math, check that theprevious record, i.e. the xl_prev value that we'd write for the nextrecord, matches the last checkpoint's redo pointer. That way it's notdependent on the size of the checkpoint record at all.The old logic was actually slightly wrong all along: if the previouscheckpoint record crossed a page boundary, the page headers threw off therecord size calculation, and the checkpoint was not skipped. The newcheckpoint would not cross a page boundary, so this only resulted in atmost one extra checkpoint after the system became idle. The new logic fixesthat. (It's not worth fixing in backbranches).However, it makes some sense to try to keep the latest checkpoint containedfully in a page, or at least in a single WAL segment, just on generalrobustness grounds. If something goes awfully wrong, it's more likely thatyou can recover the latest WAL segment, than the last two WAL segments. SoI added an extra check that the checkpoint is not skipped if the previouscheckpoint crossed a WAL segment.Reported by Jeff Janes.
1 parent9fa8b0e commit3d80a1e

File tree

1 file changed

+9
-7
lines changed
  • src/backend/access/transam

1 file changed

+9
-7
lines changed

‎src/backend/access/transam/xlog.c‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7903,6 +7903,7 @@ CreateCheckPoint(int flags)
79037903
uint32freespace;
79047904
XLogRecPtrPriorRedoPtr;
79057905
XLogRecPtrcurInsert;
7906+
XLogRecPtrprevPtr;
79067907
VirtualTransactionId*vxids;
79077908
intnvxids;
79087909

@@ -7988,6 +7989,7 @@ CreateCheckPoint(int flags)
79887989
*/
79897990
WALInsertLockAcquireExclusive();
79907991
curInsert=XLogBytePosToRecPtr(Insert->CurrBytePos);
7992+
prevPtr=XLogBytePosToRecPtr(Insert->PrevBytePos);
79917993

79927994
/*
79937995
* If this isn't a shutdown or forced checkpoint, and we have not inserted
@@ -7999,17 +8001,17 @@ CreateCheckPoint(int flags)
79998001
* (Perhaps it'd make even more sense to checkpoint only when the previous
80008002
* checkpoint record is in a different xlog page?)
80018003
*
8002-
* We have to make two tests to determine that nothing has happened since
8003-
* the start of the last checkpoint: current insertion point must match
8004-
* the end of the last checkpoint record, and its redo pointer must point
8005-
* to itself.
8004+
* If the previous checkpoint crossed a WAL segment, however, we create
8005+
* the checkpoint anyway, to have the latest checkpoint fully contained in
8006+
* the new segment. This is for a little bit of extra robustness: it's
8007+
* better if you don't need to keep two WAL segments around to recover the
8008+
* checkpoint.
80068009
*/
80078010
if ((flags& (CHECKPOINT_IS_SHUTDOWN |CHECKPOINT_END_OF_RECOVERY |
80088011
CHECKPOINT_FORCE))==0)
80098012
{
8010-
if (curInsert==ControlFile->checkPoint+
8011-
MAXALIGN(SizeOfXLogRecord+sizeof(CheckPoint))&&
8012-
ControlFile->checkPoint==ControlFile->checkPointCopy.redo)
8013+
if (prevPtr==ControlFile->checkPointCopy.redo&&
8014+
prevPtr /XLOG_SEG_SIZE==curInsert /XLOG_SEG_SIZE)
80138015
{
80148016
WALInsertLockRelease();
80158017
LWLockRelease(CheckpointLock);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp