@@ -677,7 +677,8 @@ static XLogRecPtr CreateOverwriteContrecordRecord(XLogRecPtr aborted_lsn,
677
677
XLogRecPtr pagePtr ,
678
678
TimeLineID newTLI );
679
679
static void CheckPointGuts (XLogRecPtr checkPointRedo , int flags );
680
- static void KeepLogSeg (XLogRecPtr recptr , XLogSegNo * logSegNo );
680
+ static void KeepLogSeg (XLogRecPtr recptr , XLogRecPtr slotsMinLSN ,
681
+ XLogSegNo * logSegNo );
681
682
static XLogRecPtr XLogGetReplicationSlotMinimumLSN (void );
682
683
683
684
static void AdvanceXLInsertBuffer (XLogRecPtr upto , TimeLineID tli ,
@@ -7087,6 +7088,7 @@ CreateCheckPoint(int flags)
7087
7088
VirtualTransactionId * vxids ;
7088
7089
int nvxids ;
7089
7090
int oldXLogAllowed = 0 ;
7091
+ XLogRecPtr slotsMinReqLSN ;
7090
7092
7091
7093
/*
7092
7094
* An end-of-recovery checkpoint is really a shutdown checkpoint, just
@@ -7315,6 +7317,11 @@ CreateCheckPoint(int flags)
7315
7317
*/
7316
7318
END_CRIT_SECTION ();
7317
7319
7320
+ /*
7321
+ * Get the current minimum LSN to be used later in WAL segments cleanup.
7322
+ */
7323
+ slotsMinReqLSN = XLogGetReplicationSlotMinimumLSN ();
7324
+
7318
7325
/*
7319
7326
* In some cases there are groups of actions that must all occur on one
7320
7327
* side or the other of a checkpoint record. Before flushing the
@@ -7507,17 +7514,20 @@ CreateCheckPoint(int flags)
7507
7514
* prevent the disk holding the xlog from growing full.
7508
7515
*/
7509
7516
XLByteToSeg (RedoRecPtr , _logSegNo , wal_segment_size );
7510
- KeepLogSeg (recptr , & _logSegNo );
7517
+ KeepLogSeg (recptr , slotsMinReqLSN , & _logSegNo );
7511
7518
if (InvalidateObsoleteReplicationSlots (RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT ,
7512
7519
_logSegNo , InvalidOid ,
7513
7520
InvalidTransactionId ))
7514
7521
{
7522
+ slotsMinReqLSN = XLogGetReplicationSlotMinimumLSN ();
7523
+ CheckPointReplicationSlots (shutdown );
7524
+
7515
7525
/*
7516
7526
* Some slots have been invalidated; recalculate the old-segment
7517
7527
* horizon, starting again from RedoRecPtr.
7518
7528
*/
7519
7529
XLByteToSeg (RedoRecPtr , _logSegNo , wal_segment_size );
7520
- KeepLogSeg (recptr , & _logSegNo );
7530
+ KeepLogSeg (recptr , slotsMinReqLSN , & _logSegNo );
7521
7531
}
7522
7532
_logSegNo -- ;
7523
7533
RemoveOldXlogFiles (_logSegNo , RedoRecPtr , recptr ,
@@ -7792,6 +7802,7 @@ CreateRestartPoint(int flags)
7792
7802
XLogRecPtr endptr ;
7793
7803
XLogSegNo _logSegNo ;
7794
7804
TimestampTz xtime ;
7805
+ XLogRecPtr slotsMinReqLSN ;
7795
7806
7796
7807
/* Concurrent checkpoint/restartpoint cannot happen */
7797
7808
Assert (!IsUnderPostmaster || MyBackendType == B_CHECKPOINTER );
@@ -7874,6 +7885,11 @@ CreateRestartPoint(int flags)
7874
7885
MemSet (& CheckpointStats , 0 , sizeof (CheckpointStats ));
7875
7886
CheckpointStats .ckpt_start_t = GetCurrentTimestamp ();
7876
7887
7888
+ /*
7889
+ * Get the current minimum LSN to be used later in WAL segments cleanup.
7890
+ */
7891
+ slotsMinReqLSN = XLogGetReplicationSlotMinimumLSN ();
7892
+
7877
7893
if (log_checkpoints )
7878
7894
LogCheckpointStart (flags , true);
7879
7895
@@ -7962,17 +7978,20 @@ CreateRestartPoint(int flags)
7962
7978
receivePtr = GetWalRcvFlushRecPtr (NULL , NULL );
7963
7979
replayPtr = GetXLogReplayRecPtr (& replayTLI );
7964
7980
endptr = (receivePtr < replayPtr ) ? replayPtr : receivePtr ;
7965
- KeepLogSeg (endptr , & _logSegNo );
7981
+ KeepLogSeg (endptr , slotsMinReqLSN , & _logSegNo );
7966
7982
if (InvalidateObsoleteReplicationSlots (RS_INVAL_WAL_REMOVED | RS_INVAL_IDLE_TIMEOUT ,
7967
7983
_logSegNo , InvalidOid ,
7968
7984
InvalidTransactionId ))
7969
7985
{
7986
+ slotsMinReqLSN = XLogGetReplicationSlotMinimumLSN ();
7987
+ CheckPointReplicationSlots (flags & CHECKPOINT_IS_SHUTDOWN );
7988
+
7970
7989
/*
7971
7990
* Some slots have been invalidated; recalculate the old-segment
7972
7991
* horizon, starting again from RedoRecPtr.
7973
7992
*/
7974
7993
XLByteToSeg (RedoRecPtr , _logSegNo , wal_segment_size );
7975
- KeepLogSeg (endptr , & _logSegNo );
7994
+ KeepLogSeg (endptr , slotsMinReqLSN , & _logSegNo );
7976
7995
}
7977
7996
_logSegNo -- ;
7978
7997
@@ -8067,6 +8086,7 @@ GetWALAvailability(XLogRecPtr targetLSN)
8067
8086
XLogSegNo oldestSegMaxWalSize ; /* oldest segid kept by max_wal_size */
8068
8087
XLogSegNo oldestSlotSeg ; /* oldest segid kept by slot */
8069
8088
uint64 keepSegs ;
8089
+ XLogRecPtr slotsMinReqLSN ;
8070
8090
8071
8091
/*
8072
8092
* slot does not reserve WAL. Either deactivated, or has never been active
@@ -8080,8 +8100,9 @@ GetWALAvailability(XLogRecPtr targetLSN)
8080
8100
* oldestSlotSeg to the current segment.
8081
8101
*/
8082
8102
currpos = GetXLogWriteRecPtr ();
8103
+ slotsMinReqLSN = XLogGetReplicationSlotMinimumLSN ();
8083
8104
XLByteToSeg (currpos , oldestSlotSeg , wal_segment_size );
8084
- KeepLogSeg (currpos , & oldestSlotSeg );
8105
+ KeepLogSeg (currpos , slotsMinReqLSN , & oldestSlotSeg );
8085
8106
8086
8107
/*
8087
8108
* Find the oldest extant segment file. We get 1 until checkpoint removes
@@ -8142,7 +8163,7 @@ GetWALAvailability(XLogRecPtr targetLSN)
8142
8163
* invalidation is optionally done here, instead.
8143
8164
*/
8144
8165
static void
8145
- KeepLogSeg (XLogRecPtr recptr , XLogSegNo * logSegNo )
8166
+ KeepLogSeg (XLogRecPtr recptr , XLogRecPtr slotsMinReqLSN , XLogSegNo * logSegNo )
8146
8167
{
8147
8168
XLogSegNo currSegNo ;
8148
8169
XLogSegNo segno ;
@@ -8155,7 +8176,7 @@ KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
8155
8176
* Calculate how many segments are kept by slots first, adjusting for
8156
8177
* max_slot_wal_keep_size.
8157
8178
*/
8158
- keep = XLogGetReplicationSlotMinimumLSN () ;
8179
+ keep = slotsMinReqLSN ;
8159
8180
if (keep != InvalidXLogRecPtr && keep < recptr )
8160
8181
{
8161
8182
XLByteToSeg (keep , segno , wal_segment_size );
0 commit comments