Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d9fadbf

Browse files
committed
Fix calculation for WAL segment recycling and removal
Commit 4b0d28d has removed the prior checkpoint and related facilities but has left WAL recycling based on the LSN of the prior checkpoint, which causes incorrect calculations for WAL removal and recycling for max_wal_size and min_wal_size. This commit changes things so as the base calculation point is the last checkpoint generated. Reported-by: Kyotaro Horiguchi Author: Kyotaro Horiguchi Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/20180723.135748.42558387.horiguchi.kyotaro@lab.ntt.co.jp Backpatch: 11-, where the prior checkpoint has been removed.
1 parent 1bc180c commit d9fadbf

File tree

1 file changed

+78
-81
lines changed
  • src/backend/access/transam

1 file changed

+78
-81
lines changed

src/backend/access/transam/xlog.c

Lines changed: 78 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,8 @@ static int emode_for_corrupt_record(int emode, XLogRecPtr RecPtr);
888888
static void XLogFileClose(void);
889889
static void PreallocXlogFiles(XLogRecPtr endptr);
890890
static void RemoveTempXlogFiles(void);
891-
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr);
892-
static void RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr);
891+
static void RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr);
892+
static void RemoveXlogFile(const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr);
893893
static void UpdateLastRemovedPtr(char *filename);
894894
static void ValidateXLOGDirectoryStructure(void);
895895
static void CleanupBackupHistory(void);
@@ -2287,7 +2287,7 @@ assign_checkpoint_completion_target(double newval, void *extra)
22872287
* XLOG segments? Returns the highest segment that should be preallocated.
22882288
*/
22892289
static XLogSegNo
2290-
XLOGfileslop(XLogRecPtr PriorRedoPtr)
2290+
XLOGfileslop(XLogRecPtr RedoRecPtr)
22912291
{
22922292
XLogSegNo minSegNo;
22932293
XLogSegNo maxSegNo;
@@ -2299,9 +2299,9 @@ XLOGfileslop(XLogRecPtr PriorRedoPtr)
22992299
* correspond to. Always recycle enough segments to meet the minimum, and
23002300
* remove enough segments to stay below the maximum.
23012301
*/
2302-
minSegNo = PriorRedoPtr / wal_segment_size +
2302+
minSegNo = RedoRecPtr / wal_segment_size +
23032303
ConvertToXSegs(min_wal_size_mb, wal_segment_size) - 1;
2304-
maxSegNo = PriorRedoPtr / wal_segment_size +
2304+
maxSegNo = RedoRecPtr / wal_segment_size +
23052305
ConvertToXSegs(max_wal_size_mb, wal_segment_size) - 1;
23062306

23072307
/*
@@ -2316,7 +2316,7 @@ XLOGfileslop(XLogRecPtr PriorRedoPtr)
23162316
/* add 10% for good measure. */
23172317
distance *= 1.10;
23182318

2319-
recycleSegNo = (XLogSegNo) ceil(((double) PriorRedoPtr + distance) /
2319+
recycleSegNo = (XLogSegNo) ceil(((double) RedoRecPtr + distance) /
23202320
wal_segment_size);
23212321

23222322
if (recycleSegNo < minSegNo)
@@ -3899,12 +3899,12 @@ RemoveTempXlogFiles(void)
38993899
/*
39003900
* Recycle or remove all log files older or equal to passed segno.
39013901
*
3902-
* endptr is current (or recent) end of xlog, and PriorRedoRecPtr is the
3903-
* redo pointer of the previous checkpoint. These are used to determine
3902+
* endptr is current (or recent) end of xlog, and RedoRecPtr is the
3903+
* redo pointer of the last checkpoint. These are used to determine
39043904
* whether we want to recycle rather than delete no-longer-wanted log files.
39053905
*/
39063906
static void
3907-
RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
3907+
RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
39083908
{
39093909
DIR *xldir;
39103910
struct dirent *xlde;
@@ -3947,7 +3947,7 @@ RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
39473947
/* Update the last removed location in shared memory first */
39483948
UpdateLastRemovedPtr(xlde->d_name);
39493949

3950-
RemoveXlogFile(xlde->d_name, PriorRedoPtr, endptr);
3950+
RemoveXlogFile(xlde->d_name, RedoRecPtr, endptr);
39513951
}
39523952
}
39533953
}
@@ -4021,14 +4021,14 @@ RemoveNonParentXlogFiles(XLogRecPtr switchpoint, TimeLineID newTLI)
40214021
/*
40224022
* Recycle or remove a log file that's no longer needed.
40234023
*
4024-
* endptr is current (or recent) end of xlog, and PriorRedoRecPtr is the
4025-
* redo pointer of the previous checkpoint. These are used to determine
4024+
* endptr is current (or recent) end of xlog, and RedoRecPtr is the
4025+
* redo pointer of the last checkpoint. These are used to determine
40264026
* whether we want to recycle rather than delete no-longer-wanted log files.
4027-
* If PriorRedoRecPtr is not known, pass invalid, and the function will
4028-
* recycle, somewhat arbitrarily, 10 future segments.
4027+
* If RedoRecPtr is not known, pass invalid, and the function will recycle,
4028+
* somewhat arbitrarily, 10 future segments.
40294029
*/
40304030
static void
4031-
RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
4031+
RemoveXlogFile(const char *segname, XLogRecPtr RedoRecPtr, XLogRecPtr endptr)
40324032
{
40334033
char path[MAXPGPATH];
40344034
#ifdef WIN32
@@ -4042,10 +4042,10 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
40424042
* Initialize info about where to try to recycle to.
40434043
*/
40444044
XLByteToSeg(endptr, endlogSegNo, wal_segment_size);
4045-
if (PriorRedoPtr == InvalidXLogRecPtr)
4045+
if (RedoRecPtr == InvalidXLogRecPtr)
40464046
recycleSegNo = endlogSegNo + 10;
40474047
else
4048-
recycleSegNo = XLOGfileslop(PriorRedoPtr);
4048+
recycleSegNo = XLOGfileslop(RedoRecPtr);
40494049

40504050
snprintf(path, MAXPGPATH, XLOGDIR "/%s", segname);
40514051

@@ -8706,6 +8706,7 @@ CreateCheckPoint(int flags)
87068706
bool shutdown;
87078707
CheckPoint checkPoint;
87088708
XLogRecPtr recptr;
8709+
XLogSegNo _logSegNo;
87098710
XLogCtlInsert *Insert = &XLogCtl->Insert;
87108711
uint32 freespace;
87118712
XLogRecPtr PriorRedoPtr;
@@ -9073,21 +9074,20 @@ CreateCheckPoint(int flags)
90739074
smgrpostckpt();
90749075

90759076
/*
9076-
* Delete old log files and recycle them
9077+
* Update the average distance between checkpoints if the prior checkpoint
9078+
* exists.
90779079
*/
90789080
if (PriorRedoPtr != InvalidXLogRecPtr)
9079-
{
9080-
XLogSegNo _logSegNo;
9081-
9082-
/* Update the average distance between checkpoints. */
90839081
UpdateCheckPointDistanceEstimate(RedoRecPtr - PriorRedoPtr);
90849082

9085-
/* Trim from the last checkpoint, not the last - 1 */
9086-
XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size);
9087-
KeepLogSeg(recptr, &_logSegNo);
9088-
_logSegNo--;
9089-
RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);
9090-
}
9083+
/*
9084+
* Delete old log files, those no longer needed for last checkpoint to
9085+
* prevent the disk holding the xlog from growing full.
9086+
*/
9087+
XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size);
9088+
KeepLogSeg(recptr, &_logSegNo);
9089+
_logSegNo--;
9090+
RemoveOldXlogFiles(_logSegNo, RedoRecPtr, recptr);
90919091

90929092
/*
90939093
* Make more log segments if needed. (Do this after recycling old log
@@ -9253,6 +9253,11 @@ CreateRestartPoint(int flags)
92539253
XLogRecPtr lastCheckPointEndPtr;
92549254
CheckPoint lastCheckPoint;
92559255
XLogRecPtr PriorRedoPtr;
9256+
XLogRecPtr receivePtr;
9257+
XLogRecPtr replayPtr;
9258+
TimeLineID replayTLI;
9259+
XLogRecPtr endptr;
9260+
XLogSegNo _logSegNo;
92569261
TimestampTz xtime;
92579262

92589263
/*
@@ -9395,68 +9400,60 @@ CreateRestartPoint(int flags)
93959400
LWLockRelease(ControlFileLock);
93969401

93979402
/*
9398-
* Delete old log files (those no longer needed even for previous
9399-
* checkpoint/restartpoint) to prevent the disk holding the xlog from
9400-
* growing full.
9403+
* Update the average distance between checkpoints/restartpoints if the
9404+
* prior checkpoint exists.
94019405
*/
94029406
if (PriorRedoPtr != InvalidXLogRecPtr)
9403-
{
9404-
XLogRecPtr receivePtr;
9405-
XLogRecPtr replayPtr;
9406-
TimeLineID replayTLI;
9407-
XLogRecPtr endptr;
9408-
XLogSegNo _logSegNo;
9409-
9410-
/* Update the average distance between checkpoints/restartpoints. */
94119407
UpdateCheckPointDistanceEstimate(RedoRecPtr - PriorRedoPtr);
94129408

9413-
XLByteToSeg(PriorRedoPtr, _logSegNo, wal_segment_size);
9414-
9415-
/*
9416-
* Get the current end of xlog replayed or received, whichever is
9417-
* later.
9418-
*/
9419-
receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9420-
replayPtr = GetXLogReplayRecPtr(&replayTLI);
9421-
endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9409+
/*
9410+
* Delete old log files, those no longer needed for last restartpoint to
9411+
* prevent the disk holding the xlog from growing full.
9412+
*/
9413+
XLByteToSeg(RedoRecPtr, _logSegNo, wal_segment_size);
94229414

9423-
KeepLogSeg(endptr, &_logSegNo);
9424-
_logSegNo--;
9415+
/*
9416+
* Retreat _logSegNo using the current end of xlog replayed or received,
9417+
* whichever is later.
9418+
*/
9419+
receivePtr = GetWalRcvWriteRecPtr(NULL, NULL);
9420+
replayPtr = GetXLogReplayRecPtr(&replayTLI);
9421+
endptr = (receivePtr < replayPtr) ? replayPtr : receivePtr;
9422+
KeepLogSeg(endptr, &_logSegNo);
9423+
_logSegNo--;
94259424

9426-
/*
9427-
* Try to recycle segments on a useful timeline. If we've been
9428-
* promoted since the beginning of this restartpoint, use the new
9429-
* timeline chosen at end of recovery (RecoveryInProgress() sets
9430-
* ThisTimeLineID in that case). If we're still in recovery, use the
9431-
* timeline we're currently replaying.
9432-
*
9433-
* There is no guarantee that the WAL segments will be useful on the
9434-
* current timeline; if recovery proceeds to a new timeline right
9435-
* after this, the pre-allocated WAL segments on this timeline will
9436-
* not be used, and will go wasted until recycled on the next
9437-
* restartpoint. We'll live with that.
9438-
*/
9439-
if (RecoveryInProgress())
9440-
ThisTimeLineID = replayTLI;
9425+
/*
9426+
* Try to recycle segments on a useful timeline. If we've been promoted
9427+
* since the beginning of this restartpoint, use the new timeline chosen
9428+
* at end of recovery (RecoveryInProgress() sets ThisTimeLineID in that
9429+
* case). If we're still in recovery, use the timeline we're currently
9430+
* replaying.
9431+
*
9432+
* There is no guarantee that the WAL segments will be useful on the
9433+
* current timeline; if recovery proceeds to a new timeline right after
9434+
* this, the pre-allocated WAL segments on this timeline will not be used,
9435+
* and will go wasted until recycled on the next restartpoint. We'll live
9436+
* with that.
9437+
*/
9438+
if (RecoveryInProgress())
9439+
ThisTimeLineID = replayTLI;
94419440

9442-
RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, endptr);
9441+
RemoveOldXlogFiles(_logSegNo, RedoRecPtr, endptr);
94439442

9444-
/*
9445-
* Make more log segments if needed. (Do this after recycling old log
9446-
* segments, since that may supply some of the needed files.)
9447-
*/
9448-
PreallocXlogFiles(endptr);
9443+
/*
9444+
* Make more log segments if needed. (Do this after recycling old log
9445+
* segments, since that may supply some of the needed files.)
9446+
*/
9447+
PreallocXlogFiles(endptr);
94499448

9450-
/*
9451-
* ThisTimeLineID is normally not set when we're still in recovery.
9452-
* However, recycling/preallocating segments above needed
9453-
* ThisTimeLineID to determine which timeline to install the segments
9454-
* on. Reset it now, to restore the normal state of affairs for
9455-
* debugging purposes.
9456-
*/
9457-
if (RecoveryInProgress())
9458-
ThisTimeLineID = 0;
9459-
}
9449+
/*
9450+
* ThisTimeLineID is normally not set when we're still in recovery.
9451+
* However, recycling/preallocating segments above needed ThisTimeLineID
9452+
* to determine which timeline to install the segments on. Reset it now,
9453+
* to restore the normal state of affairs for debugging purposes.
9454+
*/
9455+
if (RecoveryInProgress())
9456+
ThisTimeLineID = 0;
94609457

94619458
/*
94629459
* Truncate pg_subtrans if possible. We can throw away all data before

0 commit comments

Comments
 (0)