diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 9f00ea90e32..048ff284f76 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -11278,7 +11278,7 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
extended means
that max_wal_size is exceeded but the files are
still retained, either by the replication slot or
- by wal_keep_segments.
+ by wal_keep_size.
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 1c491fb8ffc..ca6a3a523ff 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -3151,7 +3151,7 @@ include_dir 'conf.d'
checkpoints. This is a soft limit; WAL size can exceed
max_wal_size under special circumstances, such as
heavy load, a failing archive_command, or a high
- wal_keep_segments setting.
+ wal_keep_size setting.
If this value is specified without units, it is taken as megabytes.
The default is 1 GB.
Increasing this parameter can increase the amount of time needed for
@@ -3778,21 +3778,21 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
-
- wal_keep_segments (integer)
+
+ wal_keep_size (integer)
- wal_keep_segments configuration parameter
+ wal_keep_size configuration parameter
- Specifies the minimum number of past log file segments kept in the
+ Specifies the minimum size of past log file segments kept in the
pg_wal
directory, in case a standby server needs to fetch them for streaming
- replication. Each segment is normally 16 megabytes. If a standby
+ replication. If a standby
server connected to the sending server falls behind by more than
- wal_keep_segments segments, the sending server might remove
- a WAL segment still needed by the standby, in which case the
+ wal_keep_size megabytes, the sending server might
+ remove a WAL segment still needed by the standby, in which case the
replication connection will be terminated. Downstream connections
will also eventually fail as a result. (However, the standby
server can recover by fetching the segment from archive, if WAL
@@ -3800,14 +3800,15 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"' # Windows
- This sets only the minimum number of segments retained in
+ This sets only the minimum size of segments retained in
pg_wal; the system might need to retain more segments
for WAL archival or to recover from a checkpoint. If
- wal_keep_segments is zero (the default), the system
+ wal_keep_size is zero (the default), the system
doesn't keep any extra segments for standby purposes, so the number
of old WAL segments available to standby servers is a function of
the location of the previous checkpoint and status of WAL
archiving.
+ If this value is specified without units, it is taken as megabytes.
This parameter can only be set in the
postgresql.conf file or on the server command line.
diff --git a/doc/src/sgml/high-availability.sgml b/doc/src/sgml/high-availability.sgml
index 6a9184f314e..89f6d6eda63 100644
--- a/doc/src/sgml/high-availability.sgml
+++ b/doc/src/sgml/high-availability.sgml
@@ -785,7 +785,7 @@ archive_cleanup_command = 'pg_archivecleanup /path/to/archive %r'
archiving, the server might recycle old WAL segments before the standby
has received them. If this occurs, the standby will need to be
reinitialized from a new base backup. You can avoid this by setting
- wal_keep_segments to a value large enough to ensure that
+ wal_keep_size to a value large enough to ensure that
WAL segments are not recycled too early, or by configuring a replication
slot for the standby. If you set up a WAL archive that's accessible from
the standby, these solutions are not required, since the standby can
@@ -929,7 +929,7 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
In lieu of using replication slots, it is possible to prevent the removal
- of old WAL segments using , or by
+ of old WAL segments using , or by
storing the segments in an archive using
.
However, these methods often result in retaining more WAL segments than
diff --git a/doc/src/sgml/ref/pg_basebackup.sgml b/doc/src/sgml/ref/pg_basebackup.sgml
index aa41fb444fa..e246efbdb52 100644
--- a/doc/src/sgml/ref/pg_basebackup.sgml
+++ b/doc/src/sgml/ref/pg_basebackup.sgml
@@ -305,7 +305,7 @@ PostgreSQL documentation
The write-ahead log files are collected at the end of the backup.
Therefore, it is necessary for the
- parameter to be set high
+ parameter to be set high
enough that the log is not removed before the end of the backup.
If the log has been rotated when it's time to transfer it, the
backup will fail and be unusable.
diff --git a/doc/src/sgml/wal.sgml b/doc/src/sgml/wal.sgml
index 1902f36291d..7a13d8d5025 100644
--- a/doc/src/sgml/wal.sgml
+++ b/doc/src/sgml/wal.sgml
@@ -578,7 +578,8 @@
Independently of max_wal_size,
- + 1 most recent WAL files are
+ the most recent megabytes of
+ WAL files plus one additional WAL file are
kept at all times. Also, if WAL archiving is used, old segments can not be
removed or recycled until they are archived. If WAL archiving cannot keep up
with the pace that WAL is generated, or if archive_command
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 0a97b1d37fb..184c6672f3b 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -88,7 +88,7 @@ extern uint32 bootstrap_data_checksum_version;
/* User-settable parameters */
int max_wal_size_mb = 1024; /* 1 GB */
int min_wal_size_mb = 80; /* 80 MB */
-int wal_keep_segments = 0;
+int wal_keep_size_mb = 0;
int XLOGbuffers = -1;
int XLogArchiveTimeout = 0;
int XLogArchiveMode = ARCHIVE_MODE_OFF;
@@ -9525,7 +9525,7 @@ GetWALAvailability(XLogRecPtr targetLSN)
/*
* Calculate the oldest segment currently reserved by all slots,
- * considering wal_keep_segments and max_slot_wal_keep_size. Initialize
+ * considering wal_keep_size and max_slot_wal_keep_size. Initialize
* oldestSlotSeg to the current segment.
*/
currpos = GetXLogWriteRecPtr();
@@ -9576,9 +9576,9 @@ GetWALAvailability(XLogRecPtr targetLSN)
/*
* Retreat *logSegNo to the last segment that we need to retain because of
- * either wal_keep_segments or replication slots.
+ * either wal_keep_size or replication slots.
*
- * This is calculated by subtracting wal_keep_segments from the given xlog
+ * This is calculated by subtracting wal_keep_size from the given xlog
* location, recptr and by making sure that that result is below the
* requirement of replication slots. For the latter criterion we do consider
* the effects of max_slot_wal_keep_size: reserve at most that much space back
@@ -9616,14 +9616,20 @@ KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
}
}
- /* but, keep at least wal_keep_segments if that's set */
- if (wal_keep_segments > 0 && currSegNo - segno < wal_keep_segments)
+ /* but, keep at least wal_keep_size if that's set */
+ if (wal_keep_size_mb > 0)
{
- /* avoid underflow, don't go below 1 */
- if (currSegNo <= wal_keep_segments)
- segno = 1;
- else
- segno = currSegNo - wal_keep_segments;
+ uint64 keep_segs;
+
+ keep_segs = ConvertToXSegs(wal_keep_size_mb, wal_segment_size);
+ if (currSegNo - segno < keep_segs)
+ {
+ /* avoid underflow, don't go below 1 */
+ if (currSegNo <= keep_segs)
+ segno = 1;
+ else
+ segno = currSegNo - keep_segs;
+ }
}
/* don't delete WAL segments newer than the calculated segment */
@@ -11328,7 +11334,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive, TimeLineID *stoptli_p)
* If archiving is enabled, wait for all the required WAL files to be
* archived before returning. If archiving isn't enabled, the required WAL
* needs to be transported via streaming replication (hopefully with
- * wal_keep_segments set high enough), or some more exotic mechanism like
+ * wal_keep_size set high enough), or some more exotic mechanism like
* polling and copying files from pg_wal with script. We have no knowledge
* of those mechanisms, so it's up to the user to ensure that he gets all
* the required WAL.
diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c
index 9fe147bf44e..f88694672fb 100644
--- a/src/backend/replication/slotfuncs.c
+++ b/src/backend/replication/slotfuncs.c
@@ -413,19 +413,20 @@ pg_get_replication_slots(PG_FUNCTION_ARGS)
else
{
XLogSegNo targetSeg;
- XLogSegNo keepSegs;
+ uint64 slotKeepSegs;
+ uint64 keepSegs;
XLogSegNo failSeg;
XLogRecPtr failLSN;
XLByteToSeg(slot_contents.data.restart_lsn, targetSeg, wal_segment_size);
- /* determine how many segments slots can be kept by slots ... */
- keepSegs = XLogMBVarToSegs(max_slot_wal_keep_size_mb, wal_segment_size);
- /* ... and override by wal_keep_segments as needed */
- keepSegs = Max(keepSegs, wal_keep_segments);
+ /* determine how many segments slots can be kept by slots */
+ slotKeepSegs = XLogMBVarToSegs(max_slot_wal_keep_size_mb, wal_segment_size);
+ /* ditto for wal_keep_size */
+ keepSegs = XLogMBVarToSegs(wal_keep_size_mb, wal_segment_size);
/* if currpos reaches failLSN, we lose our segment */
- failSeg = targetSeg + keepSegs + 1;
+ failSeg = targetSeg + Max(slotKeepSegs, keepSegs) + 1;
XLogSegNoOffsetToRecPtr(failSeg, 0, wal_segment_size, failLSN);
values[i++] = Int64GetDatum(failLSN - currlsn);
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 99a3e4f6f65..6f603cbbe8c 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -2636,12 +2636,13 @@ static struct config_int ConfigureNamesInt[] =
},
{
- {"wal_keep_segments", PGC_SIGHUP, REPLICATION_SENDING,
- gettext_noop("Sets the number of WAL files held for standby servers."),
- NULL
+ {"wal_keep_size", PGC_SIGHUP, REPLICATION_SENDING,
+ gettext_noop("Sets the size of WAL files held for standby servers."),
+ NULL,
+ GUC_UNIT_MB
},
- &wal_keep_segments,
- 0, 0, INT_MAX,
+ &wal_keep_size_mb,
+ 0, 0, MAX_KILOBYTES,
NULL, NULL, NULL
},
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 29e01521966..5a0b8e98217 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -290,7 +290,7 @@
#max_wal_senders = 10 # max number of walsender processes
# (change requires restart)
-#wal_keep_segments = 0 # in logfile segments; 0 disables
+#wal_keep_size = 0 # in megabytes; 0 disables
#max_slot_wal_keep_size = -1 # in megabytes; -1 disables
#wal_sender_timeout = 60s # in milliseconds; 0 disables
diff --git a/src/bin/pg_rewind/t/RewindTest.pm b/src/bin/pg_rewind/t/RewindTest.pm
index 7516af7a01a..41ed7d4b3be 100644
--- a/src/bin/pg_rewind/t/RewindTest.pm
+++ b/src/bin/pg_rewind/t/RewindTest.pm
@@ -135,11 +135,11 @@ sub setup_cluster
extra => $extra,
auth_extra => [ '--create-role', 'rewind_user' ]);
- # Set wal_keep_segments to prevent WAL segment recycling after enforced
+ # Set wal_keep_size to prevent WAL segment recycling after enforced
# checkpoints in the tests.
$node_primary->append_conf(
'postgresql.conf', qq(
-wal_keep_segments = 20
+wal_keep_size = 320MB
));
return;
}
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index d8391aa3783..219a7299e1f 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -107,7 +107,7 @@ extern bool reachedConsistency;
extern int wal_segment_size;
extern int min_wal_size_mb;
extern int max_wal_size_mb;
-extern int wal_keep_segments;
+extern int wal_keep_size_mb;
extern int max_slot_wal_keep_size_mb;
extern int XLOGbuffers;
extern int XLogArchiveTimeout;
@@ -273,7 +273,7 @@ typedef enum WALAvailability
WALAVAIL_INVALID_LSN, /* parameter error */
WALAVAIL_RESERVED, /* WAL segment is within max_wal_size */
WALAVAIL_EXTENDED, /* WAL segment is reserved by a slot or
- * wal_keep_segments */
+ * wal_keep_size */
WALAVAIL_UNRESERVED, /* no longer reserved, but not removed yet */
WALAVAIL_REMOVED /* WAL segment has been removed */
} WALAvailability;
diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl
index 1fced12fca5..20f4a1bbc3d 100644
--- a/src/test/recovery/t/019_replslot_limit.pl
+++ b/src/test/recovery/t/019_replslot_limit.pl
@@ -116,19 +116,19 @@ $start_lsn = $node_primary->lsn('write');
$node_primary->wait_for_catchup($node_standby, 'replay', $start_lsn);
$node_standby->stop;
-# wal_keep_segments overrides max_slot_wal_keep_size
+# wal_keep_size overrides max_slot_wal_keep_size
$result = $node_primary->safe_psql('postgres',
- "ALTER SYSTEM SET wal_keep_segments to 8; SELECT pg_reload_conf();");
+ "ALTER SYSTEM SET wal_keep_size to '8MB'; SELECT pg_reload_conf();");
# Advance WAL again then checkpoint, reducing remain by 6 MB.
advance_wal($node_primary, 6);
$result = $node_primary->safe_psql('postgres',
"SELECT wal_status as remain FROM pg_replication_slots WHERE slot_name = 'rep1'"
);
is($result, "extended",
- 'check that wal_keep_segments overrides max_slot_wal_keep_size');
-# restore wal_keep_segments
+ 'check that wal_keep_size overrides max_slot_wal_keep_size');
+# restore wal_keep_size
$result = $node_primary->safe_psql('postgres',
- "ALTER SYSTEM SET wal_keep_segments to 0; SELECT pg_reload_conf();");
+ "ALTER SYSTEM SET wal_keep_size to 0; SELECT pg_reload_conf();");
# The standby can reconnect to primary
$node_standby->start;