aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2020-06-24 14:23:39 -0400
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2020-06-24 14:23:39 -0400
commitb8fd4e02c6d01183bf6def5897ad6cf7766bfff4 (patch)
tree11d04fed6fe779e476f821bf072036619ac9d809 /src/backend/access/transam/xlog.c
parent0188bb82531f1b0ae3648fb81a4bd4a4f6242127 (diff)
downloadpostgresql-b8fd4e02c6d01183bf6def5897ad6cf7766bfff4.tar.gz
postgresql-b8fd4e02c6d01183bf6def5897ad6cf7766bfff4.zip
Adjust max_slot_wal_keep_size behavior per review
In pg_replication_slot, change output from normal/reserved/lost to reserved/extended/unreserved/ lost, which better expresses the possible states particularly near the time where segments are no longer safe but checkpoint has not run yet. Under the new definition, reserved means the slot is consuming WAL that's still under the normal WAL size constraints; extended means it's consuming WAL that's being protected by wal_keep_segments or the slot itself, whose size is below max_slot_wal_keep_size; unreserved means the WAL is no longer safe, but checkpoint has not yet removed those files. Such as slot is in imminent danger, but can still continue for a little while and may catch up to the reserved WAL space. Also, there were some bugs in the calculations used to report the status; fixed those. Backpatch to 13. Reported-by: Fujii Masao <masao.fujii@oss.nttdata.com> Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Reviewed-by: Fujii Masao <masao.fujii@oss.nttdata.com> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/20200616.120236.1809496990963386593.horikyota.ntt@gmail.com
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 34ede80c44f..e455384b5b0 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -9488,15 +9488,20 @@ CreateRestartPoint(int flags)
* (typically a slot's restart_lsn)
*
* Returns one of the following enum values:
- * * WALAVAIL_NORMAL means targetLSN is available because it is in the range
- * of max_wal_size.
*
- * * WALAVAIL_PRESERVED means it is still available by preserving extra
+ * * WALAVAIL_RESERVED means targetLSN is available and it is in the range of
+ * max_wal_size.
+ *
+ * * WALAVAIL_EXTENDED means it is still available by preserving extra
* segments beyond max_wal_size. If max_slot_wal_keep_size is smaller
* than max_wal_size, this state is not returned.
*
- * * WALAVAIL_REMOVED means it is definitely lost. A replication stream on
- * a slot with this LSN cannot continue.
+ * * WALAVAIL_UNRESERVED means it is being lost and the next checkpoint will
+ * remove reserved segments. The walsender using this slot may return to the
+ * above.
+ *
+ * * WALAVAIL_REMOVED means it has been removed. A replication stream on
+ * a slot with this LSN cannot continue after a restart.
*
* * WALAVAIL_INVALID_LSN means the slot hasn't been set to reserve WAL.
*/
@@ -9512,13 +9517,18 @@ GetWALAvailability(XLogRecPtr targetLSN)
* slot */
uint64 keepSegs;
- /* slot does not reserve WAL. Either deactivated, or has never been active */
+ /*
+ * slot does not reserve WAL. Either deactivated, or has never been active
+ */
if (XLogRecPtrIsInvalid(targetLSN))
return WALAVAIL_INVALID_LSN;
currpos = GetXLogWriteRecPtr();
- /* calculate oldest segment currently needed by slots */
+ /*
+ * calculate the oldest segment currently reserved by all slots,
+ * considering wal_keep_segments and max_slot_wal_keep_size
+ */
XLByteToSeg(targetLSN, targetSeg, wal_segment_size);
KeepLogSeg(currpos, &oldestSlotSeg);
@@ -9529,10 +9539,9 @@ GetWALAvailability(XLogRecPtr targetLSN)
*/
oldestSeg = XLogGetLastRemovedSegno() + 1;
- /* calculate oldest segment by max_wal_size and wal_keep_segments */
+ /* calculate oldest segment by max_wal_size */
XLByteToSeg(currpos, currSeg, wal_segment_size);
- keepSegs = ConvertToXSegs(Max(max_wal_size_mb, wal_keep_segments),
- wal_segment_size) + 1;
+ keepSegs = ConvertToXSegs(max_wal_size_mb, wal_segment_size) + 1;
if (currSeg > keepSegs)
oldestSegMaxWalSize = currSeg - keepSegs;
@@ -9540,27 +9549,23 @@ GetWALAvailability(XLogRecPtr targetLSN)
oldestSegMaxWalSize = 1;
/*
- * If max_slot_wal_keep_size has changed after the last call, the segment
- * that would been kept by the current setting might have been lost by the
- * previous setting. No point in showing normal or keeping status values
- * if the targetSeg is known to be lost.
+ * No point in returning reserved or extended status values if the
+ * targetSeg is known to be lost.
*/
- if (targetSeg >= oldestSeg)
+ if (targetSeg >= oldestSlotSeg)
{
- /*
- * show "normal" when targetSeg is within max_wal_size, even if
- * max_slot_wal_keep_size is smaller than max_wal_size.
- */
- if ((max_slot_wal_keep_size_mb <= 0 ||
- max_slot_wal_keep_size_mb >= max_wal_size_mb) &&
- oldestSegMaxWalSize <= targetSeg)
- return WALAVAIL_NORMAL;
-
- /* being retained by slots */
- if (oldestSlotSeg <= targetSeg)
+ /* show "reserved" when targetSeg is within max_wal_size */
+ if (targetSeg >= oldestSegMaxWalSize)
return WALAVAIL_RESERVED;
+
+ /* being retained by slots exceeding max_wal_size */
+ return WALAVAIL_EXTENDED;
}
+ /* WAL segments are no longer retained but haven't been removed yet */
+ if (targetSeg >= oldestSeg)
+ return WALAVAIL_UNRESERVED;
+
/* Definitely lost */
return WALAVAIL_REMOVED;
}