Commit 18fb9d8d authored by Simon Riggs's avatar Simon Riggs

Reduce checkpoints and WAL traffic on low activity database server

Previously, we skipped a checkpoint if no WAL had been written since
last checkpoint, though this does not appear in user documentation.
As of now, we skip a checkpoint until we have written at least one
enough WAL to switch the next WAL file. This greatly reduces the
level of activity and number of WAL messages generated by a very
low activity server. This is safe because the purpose of a checkpoint
is to act as a starting place for a recovery, in case of crash.
This patch maintains minimal WAL volume for replay in case of crash,
thus maintaining very low crash recovery time.
parent 9aceb6ab
...@@ -7560,6 +7560,10 @@ CreateCheckPoint(int flags) ...@@ -7560,6 +7560,10 @@ CreateCheckPoint(int flags)
uint32 freespace; uint32 freespace;
uint32 _logId; uint32 _logId;
uint32 _logSeg; uint32 _logSeg;
uint32 redo_logId;
uint32 redo_logSeg;
uint32 insert_logId;
uint32 insert_logSeg;
TransactionId *inCommitXids; TransactionId *inCommitXids;
int nInCommit; int nInCommit;
...@@ -7636,8 +7640,8 @@ CreateCheckPoint(int flags) ...@@ -7636,8 +7640,8 @@ CreateCheckPoint(int flags)
LWLockAcquire(WALInsertLock, LW_EXCLUSIVE); LWLockAcquire(WALInsertLock, LW_EXCLUSIVE);
/* /*
* If this isn't a shutdown or forced checkpoint, and we have not inserted * If this isn't a shutdown or forced checkpoint, and we have not switched
* any XLOG records since the start of the last checkpoint, skip the * to the next WAL file since the start of the last checkpoint, skip the
* checkpoint. The idea here is to avoid inserting duplicate checkpoints * checkpoint. The idea here is to avoid inserting duplicate checkpoints
* when the system is idle. That wastes log space, and more importantly it * when the system is idle. That wastes log space, and more importantly it
* exposes us to possible loss of both current and previous checkpoint * exposes us to possible loss of both current and previous checkpoint
...@@ -7645,10 +7649,11 @@ CreateCheckPoint(int flags) ...@@ -7645,10 +7649,11 @@ CreateCheckPoint(int flags)
* (Perhaps it'd make even more sense to checkpoint only when the previous * (Perhaps it'd make even more sense to checkpoint only when the previous
* checkpoint record is in a different xlog page?) * checkpoint record is in a different xlog page?)
* *
* We have to make two tests to determine that nothing has happened since * While holding the WALInsertLock we find the current WAL insertion point
* the start of the last checkpoint: current insertion point must match * and compare that with the starting point of the last checkpoint, which
* the end of the last checkpoint record, and its redo pointer must point * is the redo pointer. We use the redo pointer because the start and end
* to itself. * points of a checkpoint can be hundreds of files apart on large systems
* when checkpoint writes are spread out over time.
*/ */
if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY | if ((flags & (CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_END_OF_RECOVERY |
CHECKPOINT_FORCE)) == 0) CHECKPOINT_FORCE)) == 0)
...@@ -7656,13 +7661,10 @@ CreateCheckPoint(int flags) ...@@ -7656,13 +7661,10 @@ CreateCheckPoint(int flags)
XLogRecPtr curInsert; XLogRecPtr curInsert;
INSERT_RECPTR(curInsert, Insert, Insert->curridx); INSERT_RECPTR(curInsert, Insert, Insert->curridx);
if (curInsert.xlogid == ControlFile->checkPoint.xlogid && XLByteToSeg(curInsert, insert_logId, insert_logSeg);
curInsert.xrecoff == ControlFile->checkPoint.xrecoff + XLByteToSeg(ControlFile->checkPointCopy.redo, redo_logId, redo_logSeg);
MAXALIGN(SizeOfXLogRecord + sizeof(CheckPoint)) && if (insert_logId == redo_logId &&
ControlFile->checkPoint.xlogid == insert_logSeg == redo_logSeg)
ControlFile->checkPointCopy.redo.xlogid &&
ControlFile->checkPoint.xrecoff ==
ControlFile->checkPointCopy.redo.xrecoff)
{ {
LWLockRelease(WALInsertLock); LWLockRelease(WALInsertLock);
LWLockRelease(CheckpointLock); LWLockRelease(CheckpointLock);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment