Skip to content

Commit 1118cd3

Browse files
committed
Remove vacuum_defer_cleanup_age
vacuum_defer_cleanup_age was introduced before hot_standby_feedback and replication slots existed. It is hard to use reasonably - commonly it will either be set too low (not preventing recovery conflicts, while still causing some bloat), or too high (causing a lot of bloat). The alternatives do not have that issue. That on its own might not be sufficient reason to remove vacuum_defer_cleanup_age, but it also complicates computation of xid horizons. See e.g. the bug fixed in be504a3. It also is untested. This commit removes TransactionIdRetreatSafely(), as there are no users anymore. There might be potential future users, hence noting that here. Reviewed-by: Daniel Gustafsson <[email protected]> Reviewed-by: Justin Pryzby <[email protected]> Reviewed-by: Alvaro Herrera <[email protected]> Discussion: https://postgr.es/m/[email protected]
1 parent 441ee16 commit 1118cd3

File tree

8 files changed

+15
-170
lines changed

8 files changed

+15
-170
lines changed

doc/src/sgml/config.sgml

-35
Original file line numberDiff line numberDiff line change
@@ -4614,41 +4614,6 @@ ANY <replaceable class="parameter">num_sync</replaceable> ( <replaceable class="
46144614
</listitem>
46154615
</varlistentry>
46164616

4617-
<varlistentry id="guc-vacuum-defer-cleanup-age" xreflabel="vacuum_defer_cleanup_age">
4618-
<term><varname>vacuum_defer_cleanup_age</varname> (<type>integer</type>)
4619-
<indexterm>
4620-
<primary><varname>vacuum_defer_cleanup_age</varname> configuration parameter</primary>
4621-
</indexterm>
4622-
</term>
4623-
<listitem>
4624-
<para>
4625-
Specifies the number of transactions by which <command>VACUUM</command> and
4626-
<link linkend="storage-hot"><acronym>HOT</acronym> updates</link>
4627-
will defer cleanup of dead row versions. The
4628-
default is zero transactions, meaning that dead row versions can be
4629-
removed as soon as possible, that is, as soon as they are no longer
4630-
visible to any open transaction. You may wish to set this to a
4631-
non-zero value on a primary server that is supporting hot standby
4632-
servers, as described in <xref linkend="hot-standby"/>. This allows
4633-
more time for queries on the standby to complete without incurring
4634-
conflicts due to early cleanup of rows. However, since the value
4635-
is measured in terms of number of write transactions occurring on the
4636-
primary server, it is difficult to predict just how much additional
4637-
grace time will be made available to standby queries.
4638-
This parameter can only be set in the <filename>postgresql.conf</filename>
4639-
file or on the server command line.
4640-
</para>
4641-
<para>
4642-
You should also consider setting <varname>hot_standby_feedback</varname>
4643-
on standby server(s) as an alternative to using this parameter.
4644-
</para>
4645-
<para>
4646-
This does not prevent cleanup of dead rows which have reached the age
4647-
specified by <varname>old_snapshot_threshold</varname>.
4648-
</para>
4649-
</listitem>
4650-
</varlistentry>
4651-
46524617
</variablelist>
46534618
</sect2>
46544619

doc/src/sgml/high-availability.sgml

+6-22
Original file line numberDiff line numberDiff line change
@@ -944,12 +944,11 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
944944
retained by replication slots.
945945
</para>
946946
<para>
947-
Similarly, <xref linkend="guc-hot-standby-feedback"/>
948-
and <xref linkend="guc-vacuum-defer-cleanup-age"/> provide protection against
949-
relevant rows being removed by vacuum, but the former provides no
950-
protection during any time period when the standby is not connected,
951-
and the latter often needs to be set to a high value to provide adequate
952-
protection. Replication slots overcome these disadvantages.
947+
Similarly, <xref linkend="guc-hot-standby-feedback"/> on its own, without
948+
also using a replication slot, provides protection against relevant rows
949+
being removed by vacuum, but provides no protection during any time period
950+
when the standby is not connected. Replication slots overcome these
951+
disadvantages.
953952
</para>
954953
<sect3 id="streaming-replication-slots-manipulation">
955954
<title>Querying and Manipulating Replication Slots</title>
@@ -1910,17 +1909,6 @@ synchronous_standby_names = 'ANY 2 (s1, s2, s3)'
19101909
by newly-arrived streaming WAL entries after reconnection.
19111910
</para>
19121911

1913-
<para>
1914-
Another option is to increase <xref linkend="guc-vacuum-defer-cleanup-age"/>
1915-
on the primary server, so that dead rows will not be cleaned up as quickly
1916-
as they normally would be. This will allow more time for queries to
1917-
execute before they are canceled on the standby, without having to set
1918-
a high <varname>max_standby_streaming_delay</varname>. However it is
1919-
difficult to guarantee any specific execution-time window with this
1920-
approach, since <varname>vacuum_defer_cleanup_age</varname> is measured in
1921-
transactions executed on the primary server.
1922-
</para>
1923-
19241912
<para>
19251913
The number of query cancels and the reason for them can be viewed using
19261914
the <structname>pg_stat_database_conflicts</structname> system view on the standby
@@ -2257,8 +2245,7 @@ HINT: You can then restart the server after making the necessary configuration
22572245
</para>
22582246

22592247
<para>
2260-
On the primary, parameters <xref linkend="guc-wal-level"/> and
2261-
<xref linkend="guc-vacuum-defer-cleanup-age"/> can be used.
2248+
On the primary, the <xref linkend="guc-wal-level"/> parameter can be used.
22622249
<xref linkend="guc-max-standby-archive-delay"/> and
22632250
<xref linkend="guc-max-standby-streaming-delay"/> have no effect if set on
22642251
the primary.
@@ -2268,9 +2255,6 @@ HINT: You can then restart the server after making the necessary configuration
22682255
On the standby, parameters <xref linkend="guc-hot-standby"/>,
22692256
<xref linkend="guc-max-standby-archive-delay"/> and
22702257
<xref linkend="guc-max-standby-streaming-delay"/> can be used.
2271-
<xref linkend="guc-vacuum-defer-cleanup-age"/> has no effect
2272-
as long as the server remains in standby mode, though it will
2273-
become relevant if the standby becomes primary.
22742258
</para>
22752259
</sect2>
22762260

src/backend/storage/ipc/procarray.c

+8-97
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,6 @@ static inline void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId l
367367
static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid);
368368
static void MaintainLatestCompletedXid(TransactionId latestXid);
369369
static void MaintainLatestCompletedXidRecovery(TransactionId latestXid);
370-
static void TransactionIdRetreatSafely(TransactionId *xid,
371-
int retreat_by,
372-
FullTransactionId rel);
373370

374371
static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
375372
TransactionId xid);
@@ -1709,10 +1706,7 @@ TransactionIdIsActive(TransactionId xid)
17091706
* do about that --- data is only protected if the walsender runs continuously
17101707
* while queries are executed on the standby. (The Hot Standby code deals
17111708
* with such cases by failing standby queries that needed to access
1712-
* already-removed data, so there's no integrity bug.) The computed values
1713-
* are also adjusted with vacuum_defer_cleanup_age, so increasing that setting
1714-
* on the fly is another easy way to make horizons move backwards, with no
1715-
* consequences for data integrity.
1709+
* already-removed data, so there's no integrity bug.)
17161710
*
17171711
* Note: the approximate horizons (see definition of GlobalVisState) are
17181712
* updated by the computations done here. That's currently required for
@@ -1877,50 +1871,11 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
18771871
TransactionIdOlder(h->data_oldest_nonremovable, kaxmin);
18781872
/* temp relations cannot be accessed in recovery */
18791873
}
1880-
else
1881-
{
1882-
/*
1883-
* Compute the cutoff XID by subtracting vacuum_defer_cleanup_age.
1884-
*
1885-
* vacuum_defer_cleanup_age provides some additional "slop" for the
1886-
* benefit of hot standby queries on standby servers. This is quick
1887-
* and dirty, and perhaps not all that useful unless the primary has a
1888-
* predictable transaction rate, but it offers some protection when
1889-
* there's no walsender connection. Note that we are assuming
1890-
* vacuum_defer_cleanup_age isn't large enough to cause wraparound ---
1891-
* so guc.c should limit it to no more than the xidStopLimit threshold
1892-
* in varsup.c. Also note that we intentionally don't apply
1893-
* vacuum_defer_cleanup_age on standby servers.
1894-
*
1895-
* Need to use TransactionIdRetreatSafely() instead of open-coding the
1896-
* subtraction, to prevent creating an xid before
1897-
* FirstNormalTransactionId.
1898-
*/
1899-
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1900-
h->shared_oldest_nonremovable));
1901-
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1902-
h->data_oldest_nonremovable));
19031874

1904-
if (vacuum_defer_cleanup_age > 0)
1905-
{
1906-
TransactionIdRetreatSafely(&h->oldest_considered_running,
1907-
vacuum_defer_cleanup_age,
1908-
h->latest_completed);
1909-
TransactionIdRetreatSafely(&h->shared_oldest_nonremovable,
1910-
vacuum_defer_cleanup_age,
1911-
h->latest_completed);
1912-
TransactionIdRetreatSafely(&h->data_oldest_nonremovable,
1913-
vacuum_defer_cleanup_age,
1914-
h->latest_completed);
1915-
/* defer doesn't apply to temp relations */
1916-
1917-
1918-
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1919-
h->shared_oldest_nonremovable));
1920-
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1921-
h->data_oldest_nonremovable));
1922-
}
1923-
}
1875+
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
1876+
h->shared_oldest_nonremovable));
1877+
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
1878+
h->data_oldest_nonremovable));
19241879

19251880
/*
19261881
* Check whether there are replication slots requiring an older xmin.
@@ -1947,8 +1902,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
19471902
h->slot_catalog_xmin);
19481903

19491904
/*
1950-
* It's possible that slots / vacuum_defer_cleanup_age backed up the
1951-
* horizons further than oldest_considered_running. Fix.
1905+
* It's possible that slots backed up the horizons further than
1906+
* oldest_considered_running. Fix.
19521907
*/
19531908
h->oldest_considered_running =
19541909
TransactionIdOlder(h->oldest_considered_running,
@@ -2490,15 +2445,9 @@ GetSnapshotData(Snapshot snapshot)
24902445
*/
24912446
oldestfxid = FullXidRelativeTo(latest_completed, oldestxid);
24922447

2493-
/* apply vacuum_defer_cleanup_age */
2494-
def_vis_xid_data = xmin;
2495-
TransactionIdRetreatSafely(&def_vis_xid_data,
2496-
vacuum_defer_cleanup_age,
2497-
oldestfxid);
2498-
24992448
/* Check whether there's a replication slot requiring an older xmin. */
25002449
def_vis_xid_data =
2501-
TransactionIdOlder(def_vis_xid_data, replication_slot_xmin);
2450+
TransactionIdOlder(xmin, replication_slot_xmin);
25022451

25032452
/*
25042453
* Rows in non-shared, non-catalog tables possibly could be vacuumed
@@ -4320,44 +4269,6 @@ GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)
43204269
return GlobalVisTestIsRemovableXid(state, xid);
43214270
}
43224271

4323-
/*
4324-
* Safely retract *xid by retreat_by, store the result in *xid.
4325-
*
4326-
* Need to be careful to prevent *xid from retreating below
4327-
* FirstNormalTransactionId during epoch 0. This is important to prevent
4328-
* generating xids that cannot be converted to a FullTransactionId without
4329-
* wrapping around.
4330-
*
4331-
* If retreat_by would lead to a too old xid, FirstNormalTransactionId is
4332-
* returned instead.
4333-
*/
4334-
static void
4335-
TransactionIdRetreatSafely(TransactionId *xid, int retreat_by, FullTransactionId rel)
4336-
{
4337-
TransactionId original_xid = *xid;
4338-
FullTransactionId fxid;
4339-
uint64 fxid_i;
4340-
4341-
Assert(TransactionIdIsNormal(original_xid));
4342-
Assert(retreat_by >= 0); /* relevant GUCs are stored as ints */
4343-
AssertTransactionIdInAllowableRange(original_xid);
4344-
4345-
if (retreat_by == 0)
4346-
return;
4347-
4348-
fxid = FullXidRelativeTo(rel, original_xid);
4349-
fxid_i = U64FromFullTransactionId(fxid);
4350-
4351-
if ((fxid_i - FirstNormalTransactionId) <= retreat_by)
4352-
*xid = FirstNormalTransactionId;
4353-
else
4354-
{
4355-
*xid = TransactionIdRetreatedBy(original_xid, retreat_by);
4356-
Assert(TransactionIdIsNormal(*xid));
4357-
Assert(NormalTransactionIdPrecedes(*xid, original_xid));
4358-
}
4359-
}
4360-
43614272
/*
43624273
* Convert a 32 bit transaction id into 64 bit transaction id, by assuming it
43634274
* is within MaxTransactionId / 2 of XidFromFullTransactionId(rel).

src/backend/storage/ipc/standby.c

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include "utils/timestamp.h"
3939

4040
/* User-settable GUC parameters */
41-
int vacuum_defer_cleanup_age;
4241
int max_standby_archive_delay = 30 * 1000;
4342
int max_standby_streaming_delay = 30 * 1000;
4443
bool log_recovery_conflict_waits = false;

src/backend/utils/misc/guc_tables.c

-9
Original file line numberDiff line numberDiff line change
@@ -2576,15 +2576,6 @@ struct config_int ConfigureNamesInt[] =
25762576
NULL, NULL, NULL
25772577
},
25782578

2579-
{
2580-
{"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_PRIMARY,
2581-
gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
2582-
NULL
2583-
},
2584-
&vacuum_defer_cleanup_age,
2585-
0, 0, 1000000, /* see ComputeXidHorizons */
2586-
NULL, NULL, NULL
2587-
},
25882579
{
25892580
{"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
25902581
gettext_noop("Age at which VACUUM should trigger failsafe to avoid a wraparound outage."),

src/backend/utils/misc/postgresql.conf.sample

-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,6 @@
329329
# method to choose sync standbys, number of sync standbys,
330330
# and comma-separated list of application_name
331331
# from standby(s); '*' = all
332-
#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed
333332

334333
# - Standby Servers -
335334

src/bin/pg_upgrade/server.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -234,17 +234,14 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
234234
* we only modify the new cluster, so only use it there. If there is a
235235
* crash, the new cluster has to be recreated anyway. fsync=off is a big
236236
* win on ext4.
237-
*
238-
* Force vacuum_defer_cleanup_age to 0 on the new cluster, so that
239-
* vacuumdb --freeze actually freezes the tuples.
240237
*/
241238
snprintf(cmd, sizeof(cmd),
242239
"\"%s/pg_ctl\" -w -l \"%s/%s\" -D \"%s\" -o \"-p %d -b%s %s%s\" start",
243240
cluster->bindir,
244241
log_opts.logdir,
245242
SERVER_LOG_FILE, cluster->pgconfig, cluster->port,
246243
(cluster == &new_cluster) ?
247-
" -c synchronous_commit=off -c fsync=off -c full_page_writes=off -c vacuum_defer_cleanup_age=0" : "",
244+
" -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "",
248245
cluster->pgopts ? cluster->pgopts : "", socket_string);
249246

250247
/*

src/include/storage/standby.h

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "storage/standbydefs.h"
2222

2323
/* User-settable GUC parameters */
24-
extern PGDLLIMPORT int vacuum_defer_cleanup_age;
2524
extern PGDLLIMPORT int max_standby_archive_delay;
2625
extern PGDLLIMPORT int max_standby_streaming_delay;
2726
extern PGDLLIMPORT bool log_recovery_conflict_waits;

0 commit comments

Comments
 (0)