mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
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 be504a3e97
. 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 <daniel@yesql.se>
Reviewed-by: Justin Pryzby <pryzby@telsasoft.com>
Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/20230317230930.nhsgk3qfk7f4axls@awork3.anarazel.de
This commit is contained in:
@ -367,9 +367,6 @@ static inline void ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId l
|
||||
static void ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid);
|
||||
static void MaintainLatestCompletedXid(TransactionId latestXid);
|
||||
static void MaintainLatestCompletedXidRecovery(TransactionId latestXid);
|
||||
static void TransactionIdRetreatSafely(TransactionId *xid,
|
||||
int retreat_by,
|
||||
FullTransactionId rel);
|
||||
|
||||
static inline FullTransactionId FullXidRelativeTo(FullTransactionId rel,
|
||||
TransactionId xid);
|
||||
@ -1709,10 +1706,7 @@ TransactionIdIsActive(TransactionId xid)
|
||||
* do about that --- data is only protected if the walsender runs continuously
|
||||
* while queries are executed on the standby. (The Hot Standby code deals
|
||||
* with such cases by failing standby queries that needed to access
|
||||
* already-removed data, so there's no integrity bug.) The computed values
|
||||
* are also adjusted with vacuum_defer_cleanup_age, so increasing that setting
|
||||
* on the fly is another easy way to make horizons move backwards, with no
|
||||
* consequences for data integrity.
|
||||
* already-removed data, so there's no integrity bug.)
|
||||
*
|
||||
* Note: the approximate horizons (see definition of GlobalVisState) are
|
||||
* updated by the computations done here. That's currently required for
|
||||
@ -1877,50 +1871,11 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
TransactionIdOlder(h->data_oldest_nonremovable, kaxmin);
|
||||
/* temp relations cannot be accessed in recovery */
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Compute the cutoff XID by subtracting vacuum_defer_cleanup_age.
|
||||
*
|
||||
* vacuum_defer_cleanup_age provides some additional "slop" for the
|
||||
* benefit of hot standby queries on standby servers. This is quick
|
||||
* and dirty, and perhaps not all that useful unless the primary has a
|
||||
* predictable transaction rate, but it offers some protection when
|
||||
* there's no walsender connection. Note that we are assuming
|
||||
* vacuum_defer_cleanup_age isn't large enough to cause wraparound ---
|
||||
* so guc.c should limit it to no more than the xidStopLimit threshold
|
||||
* in varsup.c. Also note that we intentionally don't apply
|
||||
* vacuum_defer_cleanup_age on standby servers.
|
||||
*
|
||||
* Need to use TransactionIdRetreatSafely() instead of open-coding the
|
||||
* subtraction, to prevent creating an xid before
|
||||
* FirstNormalTransactionId.
|
||||
*/
|
||||
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
|
||||
h->shared_oldest_nonremovable));
|
||||
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
|
||||
h->data_oldest_nonremovable));
|
||||
|
||||
if (vacuum_defer_cleanup_age > 0)
|
||||
{
|
||||
TransactionIdRetreatSafely(&h->oldest_considered_running,
|
||||
vacuum_defer_cleanup_age,
|
||||
h->latest_completed);
|
||||
TransactionIdRetreatSafely(&h->shared_oldest_nonremovable,
|
||||
vacuum_defer_cleanup_age,
|
||||
h->latest_completed);
|
||||
TransactionIdRetreatSafely(&h->data_oldest_nonremovable,
|
||||
vacuum_defer_cleanup_age,
|
||||
h->latest_completed);
|
||||
/* defer doesn't apply to temp relations */
|
||||
|
||||
|
||||
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
|
||||
h->shared_oldest_nonremovable));
|
||||
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
|
||||
h->data_oldest_nonremovable));
|
||||
}
|
||||
}
|
||||
Assert(TransactionIdPrecedesOrEquals(h->oldest_considered_running,
|
||||
h->shared_oldest_nonremovable));
|
||||
Assert(TransactionIdPrecedesOrEquals(h->shared_oldest_nonremovable,
|
||||
h->data_oldest_nonremovable));
|
||||
|
||||
/*
|
||||
* Check whether there are replication slots requiring an older xmin.
|
||||
@ -1947,8 +1902,8 @@ ComputeXidHorizons(ComputeXidHorizonsResult *h)
|
||||
h->slot_catalog_xmin);
|
||||
|
||||
/*
|
||||
* It's possible that slots / vacuum_defer_cleanup_age backed up the
|
||||
* horizons further than oldest_considered_running. Fix.
|
||||
* It's possible that slots backed up the horizons further than
|
||||
* oldest_considered_running. Fix.
|
||||
*/
|
||||
h->oldest_considered_running =
|
||||
TransactionIdOlder(h->oldest_considered_running,
|
||||
@ -2490,15 +2445,9 @@ GetSnapshotData(Snapshot snapshot)
|
||||
*/
|
||||
oldestfxid = FullXidRelativeTo(latest_completed, oldestxid);
|
||||
|
||||
/* apply vacuum_defer_cleanup_age */
|
||||
def_vis_xid_data = xmin;
|
||||
TransactionIdRetreatSafely(&def_vis_xid_data,
|
||||
vacuum_defer_cleanup_age,
|
||||
oldestfxid);
|
||||
|
||||
/* Check whether there's a replication slot requiring an older xmin. */
|
||||
def_vis_xid_data =
|
||||
TransactionIdOlder(def_vis_xid_data, replication_slot_xmin);
|
||||
TransactionIdOlder(xmin, replication_slot_xmin);
|
||||
|
||||
/*
|
||||
* Rows in non-shared, non-catalog tables possibly could be vacuumed
|
||||
@ -4320,44 +4269,6 @@ GlobalVisCheckRemovableXid(Relation rel, TransactionId xid)
|
||||
return GlobalVisTestIsRemovableXid(state, xid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Safely retract *xid by retreat_by, store the result in *xid.
|
||||
*
|
||||
* Need to be careful to prevent *xid from retreating below
|
||||
* FirstNormalTransactionId during epoch 0. This is important to prevent
|
||||
* generating xids that cannot be converted to a FullTransactionId without
|
||||
* wrapping around.
|
||||
*
|
||||
* If retreat_by would lead to a too old xid, FirstNormalTransactionId is
|
||||
* returned instead.
|
||||
*/
|
||||
static void
|
||||
TransactionIdRetreatSafely(TransactionId *xid, int retreat_by, FullTransactionId rel)
|
||||
{
|
||||
TransactionId original_xid = *xid;
|
||||
FullTransactionId fxid;
|
||||
uint64 fxid_i;
|
||||
|
||||
Assert(TransactionIdIsNormal(original_xid));
|
||||
Assert(retreat_by >= 0); /* relevant GUCs are stored as ints */
|
||||
AssertTransactionIdInAllowableRange(original_xid);
|
||||
|
||||
if (retreat_by == 0)
|
||||
return;
|
||||
|
||||
fxid = FullXidRelativeTo(rel, original_xid);
|
||||
fxid_i = U64FromFullTransactionId(fxid);
|
||||
|
||||
if ((fxid_i - FirstNormalTransactionId) <= retreat_by)
|
||||
*xid = FirstNormalTransactionId;
|
||||
else
|
||||
{
|
||||
*xid = TransactionIdRetreatedBy(original_xid, retreat_by);
|
||||
Assert(TransactionIdIsNormal(*xid));
|
||||
Assert(NormalTransactionIdPrecedes(*xid, original_xid));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a 32 bit transaction id into 64 bit transaction id, by assuming it
|
||||
* is within MaxTransactionId / 2 of XidFromFullTransactionId(rel).
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "utils/timestamp.h"
|
||||
|
||||
/* User-settable GUC parameters */
|
||||
int vacuum_defer_cleanup_age;
|
||||
int max_standby_archive_delay = 30 * 1000;
|
||||
int max_standby_streaming_delay = 30 * 1000;
|
||||
bool log_recovery_conflict_waits = false;
|
||||
|
@ -2576,15 +2576,6 @@ struct config_int ConfigureNamesInt[] =
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
{"vacuum_defer_cleanup_age", PGC_SIGHUP, REPLICATION_PRIMARY,
|
||||
gettext_noop("Number of transactions by which VACUUM and HOT cleanup should be deferred, if any."),
|
||||
NULL
|
||||
},
|
||||
&vacuum_defer_cleanup_age,
|
||||
0, 0, 1000000, /* see ComputeXidHorizons */
|
||||
NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
{"vacuum_failsafe_age", PGC_USERSET, CLIENT_CONN_STATEMENT,
|
||||
gettext_noop("Age at which VACUUM should trigger failsafe to avoid a wraparound outage."),
|
||||
|
@ -329,7 +329,6 @@
|
||||
# method to choose sync standbys, number of sync standbys,
|
||||
# and comma-separated list of application_name
|
||||
# from standby(s); '*' = all
|
||||
#vacuum_defer_cleanup_age = 0 # number of xacts by which cleanup is delayed
|
||||
|
||||
# - Standby Servers -
|
||||
|
||||
|
@ -234,9 +234,6 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
|
||||
* we only modify the new cluster, so only use it there. If there is a
|
||||
* crash, the new cluster has to be recreated anyway. fsync=off is a big
|
||||
* win on ext4.
|
||||
*
|
||||
* Force vacuum_defer_cleanup_age to 0 on the new cluster, so that
|
||||
* vacuumdb --freeze actually freezes the tuples.
|
||||
*/
|
||||
snprintf(cmd, sizeof(cmd),
|
||||
"\"%s/pg_ctl\" -w -l \"%s/%s\" -D \"%s\" -o \"-p %d -b%s %s%s\" start",
|
||||
@ -244,7 +241,7 @@ start_postmaster(ClusterInfo *cluster, bool report_and_exit_on_error)
|
||||
log_opts.logdir,
|
||||
SERVER_LOG_FILE, cluster->pgconfig, cluster->port,
|
||||
(cluster == &new_cluster) ?
|
||||
" -c synchronous_commit=off -c fsync=off -c full_page_writes=off -c vacuum_defer_cleanup_age=0" : "",
|
||||
" -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "",
|
||||
cluster->pgopts ? cluster->pgopts : "", socket_string);
|
||||
|
||||
/*
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "storage/standbydefs.h"
|
||||
|
||||
/* User-settable GUC parameters */
|
||||
extern PGDLLIMPORT int vacuum_defer_cleanup_age;
|
||||
extern PGDLLIMPORT int max_standby_archive_delay;
|
||||
extern PGDLLIMPORT int max_standby_streaming_delay;
|
||||
extern PGDLLIMPORT bool log_recovery_conflict_waits;
|
||||
|
Reference in New Issue
Block a user