@@ -2221,13 +2221,18 @@ CalculateCheckpointSegments(void)
2221
2221
* Calculate the distance at which to trigger a checkpoint, to avoid
2222
2222
* exceeding max_wal_size_mb. This is based on two assumptions:
2223
2223
*
2224
- * a) we keep WAL for two checkpoint cycles, back to the "prev" checkpoint.
2224
+ * a) we keep WAL for only one checkpoint cycle (prior to PG11 we kept
2225
+ * WAL for two checkpoint cycles to allow us to recover from the
2226
+ * secondary checkpoint if the first checkpoint failed, though we
2227
+ * only did this on the master anyway, not on standby. Keeping just
2228
+ * one checkpoint simplifies processing and reduces disk space in
2229
+ * many smaller databases.)
2225
2230
* b) during checkpoint, we consume checkpoint_completion_target *
2226
2231
* number of segments consumed between checkpoints.
2227
2232
*-------
2228
2233
*/
2229
2234
target = (double ) ConvertToXSegs (max_wal_size_mb , wal_segment_size ) /
2230
- (2 .0 + CheckPointCompletionTarget );
2235
+ (1 .0 + CheckPointCompletionTarget );
2231
2236
2232
2237
/* round down */
2233
2238
CheckPointSegments = (int ) target ;
@@ -2279,23 +2284,8 @@ XLOGfileslop(XLogRecPtr PriorRedoPtr)
2279
2284
* To estimate where the next checkpoint will finish, assume that the
2280
2285
* system runs steadily consuming CheckPointDistanceEstimate bytes between
2281
2286
* every checkpoint.
2282
- *
2283
- * The reason this calculation is done from the prior checkpoint, not the
2284
- * one that just finished, is that this behaves better if some checkpoint
2285
- * cycles are abnormally short, like if you perform a manual checkpoint
2286
- * right after a timed one. The manual checkpoint will make almost a full
2287
- * cycle's worth of WAL segments available for recycling, because the
2288
- * segments from the prior's prior, fully-sized checkpoint cycle are no
2289
- * longer needed. However, the next checkpoint will make only few segments
2290
- * available for recycling, the ones generated between the timed
2291
- * checkpoint and the manual one right after that. If at the manual
2292
- * checkpoint we only retained enough segments to get us to the next timed
2293
- * one, and removed the rest, then at the next checkpoint we would not
2294
- * have enough segments around for recycling, to get us to the checkpoint
2295
- * after that. Basing the calculations on the distance from the prior redo
2296
- * pointer largely fixes that problem.
2297
- */
2298
- distance = (2.0 + CheckPointCompletionTarget ) * CheckPointDistanceEstimate ;
2287
+ */
2288
+ distance = (1.0 + CheckPointCompletionTarget ) * CheckPointDistanceEstimate ;
2299
2289
/* add 10% for good measure. */
2300
2290
distance *= 1.10 ;
2301
2291
@@ -6593,30 +6583,17 @@ StartupXLOG(void)
6593
6583
(errmsg ("checkpoint record is at %X/%X" ,
6594
6584
(uint32 ) (checkPointLoc >> 32 ), (uint32 ) checkPointLoc )));
6595
6585
}
6596
- else if ( StandbyMode )
6586
+ else
6597
6587
{
6598
6588
/*
6599
- * The last valid checkpoint record required for a streaming
6600
- * recovery exists in neither standby nor the primary.
6589
+ * We used to attempt to go back to a secondary checkpoint
6590
+ * record here, but only when not in standby_mode. We now
6591
+ * just fail if we can't read the last checkpoint because
6592
+ * this allows us to simplify processing around checkpoints.
6601
6593
*/
6602
6594
ereport (PANIC ,
6603
6595
(errmsg ("could not locate a valid checkpoint record" )));
6604
6596
}
6605
- else
6606
- {
6607
- checkPointLoc = ControlFile -> prevCheckPoint ;
6608
- record = ReadCheckpointRecord (xlogreader , checkPointLoc , 2 , true);
6609
- if (record != NULL )
6610
- {
6611
- ereport (LOG ,
6612
- (errmsg ("using previous checkpoint record at %X/%X" ,
6613
- (uint32 ) (checkPointLoc >> 32 ), (uint32 ) checkPointLoc )));
6614
- InRecovery = true; /* force recovery even if SHUTDOWNED */
6615
- }
6616
- else
6617
- ereport (PANIC ,
6618
- (errmsg ("could not locate a valid checkpoint record" )));
6619
- }
6620
6597
memcpy (& checkPoint , XLogRecGetData (xlogreader ), sizeof (CheckPoint ));
6621
6598
wasShutdown = ((record -> xl_info & ~XLR_INFO_MASK ) == XLOG_CHECKPOINT_SHUTDOWN );
6622
6599
}
@@ -6845,7 +6822,6 @@ StartupXLOG(void)
6845
6822
recoveryTargetTLI )));
6846
6823
ControlFile -> state = DB_IN_CRASH_RECOVERY ;
6847
6824
}
6848
- ControlFile -> prevCheckPoint = ControlFile -> checkPoint ;
6849
6825
ControlFile -> checkPoint = checkPointLoc ;
6850
6826
ControlFile -> checkPointCopy = checkPoint ;
6851
6827
if (InArchiveRecovery )
@@ -7619,12 +7595,11 @@ StartupXLOG(void)
7619
7595
{
7620
7596
if (fast_promote )
7621
7597
{
7622
- checkPointLoc = ControlFile -> prevCheckPoint ;
7598
+ checkPointLoc = ControlFile -> checkPoint ;
7623
7599
7624
7600
/*
7625
7601
* Confirm the last checkpoint is available for us to recover
7626
- * from if we fail. Note that we don't check for the secondary
7627
- * checkpoint since that isn't available in most base backups.
7602
+ * from if we fail.
7628
7603
*/
7629
7604
record = ReadCheckpointRecord (xlogreader , checkPointLoc , 1 , false);
7630
7605
if (record != NULL )
@@ -8090,7 +8065,7 @@ LocalSetXLogInsertAllowed(void)
8090
8065
* Subroutine to try to fetch and validate a prior checkpoint record.
8091
8066
*
8092
8067
* whichChkpt identifies the checkpoint (merely for reporting purposes).
8093
- * 1 for "primary", 2 for "secondary", 0 for "other" (backup_label)
8068
+ * 1 for "primary", 0 for "other" (backup_label)
8094
8069
*/
8095
8070
static XLogRecord *
8096
8071
ReadCheckpointRecord (XLogReaderState * xlogreader , XLogRecPtr RecPtr ,
@@ -8110,10 +8085,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
8110
8085
ereport (LOG ,
8111
8086
(errmsg ("invalid primary checkpoint link in control file" )));
8112
8087
break ;
8113
- case 2 :
8114
- ereport (LOG ,
8115
- (errmsg ("invalid secondary checkpoint link in control file" )));
8116
- break ;
8117
8088
default :
8118
8089
ereport (LOG ,
8119
8090
(errmsg ("invalid checkpoint link in backup_label file" )));
@@ -8135,10 +8106,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
8135
8106
ereport (LOG ,
8136
8107
(errmsg ("invalid primary checkpoint record" )));
8137
8108
break ;
8138
- case 2 :
8139
- ereport (LOG ,
8140
- (errmsg ("invalid secondary checkpoint record" )));
8141
- break ;
8142
8109
default :
8143
8110
ereport (LOG ,
8144
8111
(errmsg ("invalid checkpoint record" )));
@@ -8154,10 +8121,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
8154
8121
ereport (LOG ,
8155
8122
(errmsg ("invalid resource manager ID in primary checkpoint record" )));
8156
8123
break ;
8157
- case 2 :
8158
- ereport (LOG ,
8159
- (errmsg ("invalid resource manager ID in secondary checkpoint record" )));
8160
- break ;
8161
8124
default :
8162
8125
ereport (LOG ,
8163
8126
(errmsg ("invalid resource manager ID in checkpoint record" )));
@@ -8175,10 +8138,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
8175
8138
ereport (LOG ,
8176
8139
(errmsg ("invalid xl_info in primary checkpoint record" )));
8177
8140
break ;
8178
- case 2 :
8179
- ereport (LOG ,
8180
- (errmsg ("invalid xl_info in secondary checkpoint record" )));
8181
- break ;
8182
8141
default :
8183
8142
ereport (LOG ,
8184
8143
(errmsg ("invalid xl_info in checkpoint record" )));
@@ -8194,10 +8153,6 @@ ReadCheckpointRecord(XLogReaderState *xlogreader, XLogRecPtr RecPtr,
8194
8153
ereport (LOG ,
8195
8154
(errmsg ("invalid length of primary checkpoint record" )));
8196
8155
break ;
8197
- case 2 :
8198
- ereport (LOG ,
8199
- (errmsg ("invalid length of secondary checkpoint record" )));
8200
- break ;
8201
8156
default :
8202
8157
ereport (LOG ,
8203
8158
(errmsg ("invalid length of checkpoint record" )));
@@ -8933,8 +8888,7 @@ CreateCheckPoint(int flags)
8933
8888
(errmsg ("concurrent write-ahead log activity while database system is shutting down" )));
8934
8889
8935
8890
/*
8936
- * Remember the prior checkpoint's redo pointer, used later to determine
8937
- * the point where the log can be truncated.
8891
+ * Remember the prior checkpoint's redo ptr for UpdateCheckPointDistanceEstimate()
8938
8892
*/
8939
8893
PriorRedoPtr = ControlFile -> checkPointCopy .redo ;
8940
8894
@@ -8944,7 +8898,6 @@ CreateCheckPoint(int flags)
8944
8898
LWLockAcquire (ControlFileLock , LW_EXCLUSIVE );
8945
8899
if (shutdown )
8946
8900
ControlFile -> state = DB_SHUTDOWNED ;
8947
- ControlFile -> prevCheckPoint = ControlFile -> checkPoint ;
8948
8901
ControlFile -> checkPoint = ProcLastRecPtr ;
8949
8902
ControlFile -> checkPointCopy = checkPoint ;
8950
8903
ControlFile -> time = (pg_time_t ) time (NULL );
@@ -8982,8 +8935,7 @@ CreateCheckPoint(int flags)
8982
8935
smgrpostckpt ();
8983
8936
8984
8937
/*
8985
- * Delete old log files (those no longer needed even for previous
8986
- * checkpoint or the standbys in XLOG streaming).
8938
+ * Delete old log files and recycle them
8987
8939
*/
8988
8940
if (PriorRedoPtr != InvalidXLogRecPtr )
8989
8941
{
@@ -8992,7 +8944,8 @@ CreateCheckPoint(int flags)
8992
8944
/* Update the average distance between checkpoints. */
8993
8945
UpdateCheckPointDistanceEstimate (RedoRecPtr - PriorRedoPtr );
8994
8946
8995
- XLByteToSeg (PriorRedoPtr , _logSegNo , wal_segment_size );
8947
+ /* Trim from the last checkpoint, not the last - 1 */
8948
+ XLByteToSeg (RedoRecPtr , _logSegNo , wal_segment_size );
8996
8949
KeepLogSeg (recptr , & _logSegNo );
8997
8950
_logSegNo -- ;
8998
8951
RemoveOldXlogFiles (_logSegNo , PriorRedoPtr , recptr );
@@ -9258,8 +9211,7 @@ CreateRestartPoint(int flags)
9258
9211
CheckPointGuts (lastCheckPoint .redo , flags );
9259
9212
9260
9213
/*
9261
- * Remember the prior checkpoint's redo pointer, used later to determine
9262
- * the point at which we can truncate the log.
9214
+ * Remember the prior checkpoint's redo ptr for UpdateCheckPointDistanceEstimate()
9263
9215
*/
9264
9216
PriorRedoPtr = ControlFile -> checkPointCopy .redo ;
9265
9217
@@ -9273,7 +9225,6 @@ CreateRestartPoint(int flags)
9273
9225
if (ControlFile -> state == DB_IN_ARCHIVE_RECOVERY &&
9274
9226
ControlFile -> checkPointCopy .redo < lastCheckPoint .redo )
9275
9227
{
9276
- ControlFile -> prevCheckPoint = ControlFile -> checkPoint ;
9277
9228
ControlFile -> checkPoint = lastCheckPointRecPtr ;
9278
9229
ControlFile -> checkPointCopy = lastCheckPoint ;
9279
9230
ControlFile -> time = (pg_time_t ) time (NULL );
0 commit comments