agora inbox for [email protected]
help / color / mirror / Atom feedRe: pg_stat_statements with query tree based normalization
800+ messages / 4 participants
[nested] [flat]
* Re: pg_stat_statements with query tree based normalization
@ 2011-12-07 01:19 Peter Geoghegan <[email protected]>
2011-12-07 14:13 ` Re: pg_stat_statements with query tree based normalization Marti Raudsepp <[email protected]>
2011-12-10 13:56 ` Re: pg_stat_statements with query tree based normalization Greg Smith <[email protected]>
0 siblings, 2 replies; 800+ messages in thread
From: Peter Geoghegan @ 2011-12-07 01:19 UTC (permalink / raw)
To: Greg Smith <[email protected]>; +Cc: pgsql-hackers
On 14 November 2011 04:42, Greg Smith <[email protected]> wrote:
> The approach Peter used adds a single integer to the Const structure in
> order to have enough information to substitute "?" in place of those.
> Adding and maintaining that is the only change outside of the extension
> made here, and that overhead is paid by everyone--not just consumers of this
> new code.
I've attempted to isolate that overhead, so far unsuccessfully. Attached are:
1. A simple python + psycopg2 script for repeatedly running a
succession of similar queries that explain would show as containing a
single "Result" node. They contain 300 Const integer nodes by
default, which are simply selected.
2. The results of running the script on Greg's server, which has CPU
frequency scaling disabled. That's an ODS spreadsheet. Out of
consideration of filesize, I've deleted the query column in each
sheet, which wasn't actually useful information.
The results are...taking the median value of each set of runs as
representative, my patch appears to run marginally faster than head.
Of course, there is no reason to believe that it should, and I'm
certain that the difference can be explained by noise, even though
I've naturally strived to minimise noise.
If someone could suggest a more telling test case, or even a
worst-case, that would be useful. This was just my first run at this.
I know that the overhead will also exist in code not well-exercised by
these queries, but I imagine that any real-world query that attempts
to exercise them all is going to add other costs that dwarf the
additional overhead and further muddy the waters.
I intend to work through the known issues with this patch in the next
couple of days.
--
Peter Geoghegan http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training and Services
Attachments:
[text/x-python] performance_test.py (3.0K, ../../CAEYLb_WX50qKziuc2BHejYDmDYnBqbgc0cWvrBtK9G5iGSqnxA@mail.gmail.com/2-performance_test.py)
download | inline:
#!/usr/bin/env python
# Performance test for pg_stat_statements normalization
# Peter Geoghegan
# This test is intended to isolate the overhead of additional
# infrastructure in the grammar and plan tree, which is used to
# add a field to Const nodes so that the corresponding lexeme's
# length is known from the query tree.
# It is intended to be run without pg_stat_statements, because
# the really pertinent issue is if these changes impose any
# noticeable overhead on Postgres users that don't use
# pg_stat_statements, and the degree thereof.
# For best results, run with CPU frequency scaling disabled.
import psycopg2
import random
import time
import csv
from optparse import OptionParser
# store results of a given run in a dedicated csv file
def serialize_to_file(times, filename):
wrt = csv.writer(open(filename, 'wb'), delimiter=',')
# mark median run for runs of this
# query (or if there is an even number of elements, near enough)
median_i = (len(times) + 1) / 2 - 1
for i, v in enumerate(times):
wrt.writerow([ v[0], time.ctime(v[1]), str(v[2]) + " seconds", '*' if i == median_i else 'n'])
def run_test(conn, num_its, num_const_nodes):
# A very unsympathetic query here is one with lots of
# Const nodes that explain shows as a single "Result" node.
# This is because parsing has a large overhead
# relative to planning and execution, and there is an unusually
# high number of Const nodes.
# Use psuedo-random numbers with a consistent seed value - numbers
# used are deterministic for absolute consistency, though I don't
# believe that to be significant, at least for now.
random.seed(55)
cur = conn.cursor()
times = []
for i in range(0, num_its):
# Generate new query with psuedo-random integer Const nodes
qry = "select "
for i in range(0, num_const_nodes):
n = random.randint(0, 10000000)
qry += str(n) + (", " if i != num_const_nodes - 1 else ";")
begin = time.time()
cur.execute(qry)
end = time.time()
elapsed = end - begin
times.append((qry, begin, elapsed))
# Sort values for reference, and to locate the median value
sort_vals = sorted(times, key=lambda tot_time: tot_time[2])
serialize_to_file(sort_vals, "test_results.csv")
def main():
parser = OptionParser(description="")
parser.add_option('-c', '--conninfo', type=str, help="libpq-style connection info string of database to connect to. "
"Can be omitted, in which case we get details from our environment. "
"You'll probably want to put this in double-quotes, like this: --conninfo \"hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres\". ", default="")
parser.add_option('-n', '--num_its', type=int, help="Number of iterations (times a query is executed)", default=5000)
parser.add_option('-s', '--num_const_nodes', type=int, help="Number of Const nodes that each query contains", default=300)
args = parser.parse_args()[0]
conn_str = args.conninfo
num_its = args.num_its
num_const_nodes = args.num_const_nodes
conn = psycopg2.connect(conn_str)
run_test(conn, num_its, num_const_nodes)
if __name__=="__main__":
main()
[application/vnd.oasis.opendocument.spreadsheet] field_addition_results.ods (30.2K, ../../CAEYLb_WX50qKziuc2BHejYDmDYnBqbgc0cWvrBtK9G5iGSqnxA@mail.gmail.com/3-field_addition_results.ods)
download
^ permalink raw reply [nested|flat] 800+ messages in thread
* Re: pg_stat_statements with query tree based normalization
2011-12-07 01:19 Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
@ 2011-12-07 14:13 ` Marti Raudsepp <[email protected]>
1 sibling, 0 replies; 800+ messages in thread
From: Marti Raudsepp @ 2011-12-07 14:13 UTC (permalink / raw)
To: Peter Geoghegan <[email protected]>; +Cc: Greg Smith <[email protected]>; pgsql-hackers
On Wed, Dec 7, 2011 at 03:19, Peter Geoghegan <[email protected]> wrote:
> The results are...taking the median value of each set of runs as
> representative, my patch appears to run marginally faster than head.
> Of course, there is no reason to believe that it should, and I'm
> certain that the difference can be explained by noise, even though
> I've naturally strived to minimise noise.
You should use the t-test to distinguish whether two data sets show a
consistent difference or whether it's just noise. Excel/OpenOffice
have the TTEST() macro for this purpose. For statistics doofuses like
me, just pick mode=2 and type=3 as that's the most conservative.
If the TTEST result is less than 0.05 then you have 95% certainty that
the two dataset are consistently different. If not, you need more
consistent data.
More information here:
http://www.gifted.uconn.edu/siegle/research/t-test/t-test.html
Regards,
Marti
^ permalink raw reply [nested|flat] 800+ messages in thread
* Re: pg_stat_statements with query tree based normalization
2011-12-07 01:19 Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
@ 2011-12-10 13:56 ` Greg Smith <[email protected]>
2011-12-11 01:52 ` Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
1 sibling, 1 reply; 800+ messages in thread
From: Greg Smith @ 2011-12-10 13:56 UTC (permalink / raw)
To: ; +Cc: pgsql-hackers
On 12/06/2011 08:19 PM, Peter Geoghegan wrote:
> I intend to work through the known issues with this patch in the next
> couple of days.
>
I heard about some bitrot creeping in here too, but it seems gone now; I
had no problem merging Peter's development branch against master. I've
attached a newer patch of the main code, which fixes most of the earlier
issues there were disclaimers about. The two test programs from
contrib/pg_stat_statements are attached as separate files for a cleaner
diff. Merged and rebased version now available from
https://github.com/greg2ndQuadrant/postgres/tree/pg_stat_statements_norm
too.
--
Greg Smith 2ndQuadrant US [email protected] Baltimore, MD
PostgreSQL Training, Services, and 24x7 Support www.2ndQuadrant.us
Attachments:
[text/x-patch] pg_stat_statements_norm_v5.patch (269.0K, ../../[email protected]/2-pg_stat_statements_norm_v5.patch)
download | inline diff:
diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c
index 8dc3054..72a030f 100644
*** a/contrib/pg_stat_statements/pg_stat_statements.c
--- b/contrib/pg_stat_statements/pg_stat_statements.c
***************
*** 10,15 ****
--- 10,25 ----
* an entry, one must hold the lock shared or exclusive (so the entry doesn't
* disappear!) and also take the entry's mutex spinlock.
*
+ * Statements go through a normalization process before being stored.
+ * Normalization is ignoring components of the query that don't normally
+ * differentiate it for the purposes of isolating poorly performing queries.
+ * For example, the statements 'SELECT * FROM t WHERE f=1' and
+ * 'SELECT * FROM t WHERE f=2' would both be considered equivalent after
+ * normalization. This is implemented by generating a series of integers
+ * from the query tree after the re-write stage, into a "query jumble". A
+ * query jumble is distinct from a straight serialization of the query tree in
+ * that Constants are canonicalized, and various extraneous information is
+ * ignored, such as the collation of Vars.
*
* Copyright (c) 2008-2011, PostgreSQL Global Development Group
*
***************
*** 27,38 ****
--- 37,51 ----
#include "funcapi.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
+ #include "optimizer/planner.h"
+ #include "parser/parsetree.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/spin.h"
#include "tcop/utility.h"
#include "utils/builtins.h"
+ #include "utils/memutils.h"
PG_MODULE_MAGIC;
*************** static const uint32 PGSS_FILE_HEADER = 0
*** 48,53 ****
--- 61,70 ----
#define USAGE_INIT (1.0) /* including initial planning */
#define USAGE_DECREASE_FACTOR (0.99) /* decreased every entry_dealloc */
#define USAGE_DEALLOC_PERCENT 5 /* free this % of entries at once */
+ #define JUMBLE_SIZE 1024 /* query serialization buffer size */
+ /* Magic values */
+ #define HASH_BUF (0xFA) /* buffer is a hash of query tree */
+ #define STR_BUF (0xEB) /* buffer is query string itself */
/*
* Hashtable key that defines the identity of a hashtable entry. The
*************** typedef struct pgssHashKey
*** 63,70 ****
Oid userid; /* user OID */
Oid dbid; /* database OID */
int encoding; /* query encoding */
! int query_len; /* # of valid bytes in query string */
! const char *query_ptr; /* query string proper */
} pgssHashKey;
/*
--- 80,86 ----
Oid userid; /* user OID */
Oid dbid; /* database OID */
int encoding; /* query encoding */
! char jumble[JUMBLE_SIZE]; /* Integers from a query tree */
} pgssHashKey;
/*
*************** typedef struct pgssEntry
*** 95,100 ****
--- 111,117 ----
{
pgssHashKey key; /* hash key of entry - MUST BE FIRST */
Counters counters; /* the statistics for this query */
+ int query_len; /* # of valid bytes in query string */
slock_t mutex; /* protects the counters only */
char query[1]; /* VARIABLE LENGTH ARRAY - MUST BE LAST */
/* Note: the allocated length of query[] is actually pgss->query_size */
*************** typedef struct pgssSharedState
*** 109,116 ****
int query_size; /* max query length in bytes */
} pgssSharedState;
! /*---- Local variables ----*/
/* Current nesting depth of ExecutorRun calls */
static int nested_level = 0;
--- 126,146 ----
int query_size; /* max query length in bytes */
} pgssSharedState;
! typedef struct pgssTokenOffset
! {
! int offset; /* token offset in query string in bytes */
! int len; /* length of token in bytes */
! } pgssTokenOffset;
+ /*---- Local variables ----*/
+ /* Jumble of last query tree seen by pgss_PlannerRun */
+ static char *last_jumble = NULL;
+ /* Ptr to buffer that represents position of normalized characters */
+ static pgssTokenOffset *last_offsets = NULL;
+ /* Current Length of last_offsets buffer */
+ static size_t last_offset_buf_size = 10;
+ /* Current number of actual offsets stored in last_offsets */
+ static size_t last_offset_num = 0;
/* Current nesting depth of ExecutorRun calls */
static int nested_level = 0;
*************** static ExecutorRun_hook_type prev_Execut
*** 121,126 ****
--- 151,157 ----
static ExecutorFinish_hook_type prev_ExecutorFinish = NULL;
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
static ProcessUtility_hook_type prev_ProcessUtility = NULL;
+ static planner_hook_type prev_Planner = NULL;
/* Links to shared memory state */
static pgssSharedState *pgss = NULL;
*************** static int pgss_max; /* max # statemen
*** 147,153 ****
static int pgss_track; /* tracking level */
static bool pgss_track_utility; /* whether to track utility commands */
static bool pgss_save; /* whether to save stats across shutdown */
!
#define pgss_enabled() \
(pgss_track == PGSS_TRACK_ALL || \
--- 178,184 ----
static int pgss_track; /* tracking level */
static bool pgss_track_utility; /* whether to track utility commands */
static bool pgss_save; /* whether to save stats across shutdown */
! static bool pgss_string_key; /* whether to always only hash query str */
#define pgss_enabled() \
(pgss_track == PGSS_TRACK_ALL || \
*************** PG_FUNCTION_INFO_V1(pg_stat_statements);
*** 166,171 ****
--- 197,212 ----
static void pgss_shmem_startup(void);
static void pgss_shmem_shutdown(int code, Datum arg);
+ static PlannedStmt *pgss_PlannerRun(Query *parse, int cursorOptions, ParamListInfo boundParams);
+ static int comp_offset(const void *a, const void *b);
+ static void JumbleQuery(Query *parse);
+ static bool AppendJumb(char* item, char jumble[], size_t size, size_t *i);
+ static bool PerformJumble(const Query *parse, size_t size, size_t *i);
+ static bool QualsNode(const OpExpr *node, size_t size, size_t *i, List *rtable);
+ static bool LeafNodes(const Node *arg, size_t size, size_t *i, List *rtable);
+ static bool LimitOffsetNode(const Node *node, size_t size, size_t *i, List *rtable);
+ static bool JoinExprNode(JoinExpr *node, size_t size, size_t *i, List *rtable);
+ static bool JoinExprNodeChild(const Node *node, size_t size, size_t *i, List *rtable);
static void pgss_ExecutorStart(QueryDesc *queryDesc, int eflags);
static void pgss_ExecutorRun(QueryDesc *queryDesc,
ScanDirection direction,
*************** static void pgss_ProcessUtility(Node *pa
*** 177,186 ****
DestReceiver *dest, char *completionTag);
static uint32 pgss_hash_fn(const void *key, Size keysize);
static int pgss_match_fn(const void *key1, const void *key2, Size keysize);
! static void pgss_store(const char *query, double total_time, uint64 rows,
! const BufferUsage *bufusage);
static Size pgss_memsize(void);
! static pgssEntry *entry_alloc(pgssHashKey *key);
static void entry_dealloc(void);
static void entry_reset(void);
--- 218,229 ----
DestReceiver *dest, char *completionTag);
static uint32 pgss_hash_fn(const void *key, Size keysize);
static int pgss_match_fn(const void *key1, const void *key2, Size keysize);
! static void pgss_store(const char *query, char jumble[],
! pgssTokenOffset offs[], int off_n,
! double total_time, uint64 rows,
! const BufferUsage *bufusage);
static Size pgss_memsize(void);
! static pgssEntry *entry_alloc(pgssHashKey *key, const char* query, int new_query_len);
static void entry_dealloc(void);
static void entry_reset(void);
*************** _PG_init(void)
*** 252,257 ****
--- 295,315 ----
NULL,
NULL);
+ /*
+ * Support legacy pg_stat_statements behavior, for compatibility with
+ * versions shipped with Postgres 8.4, 9.0 and 9.1
+ */
+ DefineCustomBoolVariable("pg_stat_statements.string_key",
+ "Differentiate queries based on query string alone.",
+ NULL,
+ &pgss_string_key,
+ false,
+ PGC_POSTMASTER,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+
EmitWarningsOnPlaceholders("pg_stat_statements");
/*
*************** _PG_init(void)
*** 262,267 ****
--- 320,332 ----
RequestAddinShmemSpace(pgss_memsize());
RequestAddinLWLocks(1);
+ /* Allocate a buffer to store selective serialization of the query tree
+ * for the purposes of query normalization.
+ */
+ last_jumble = MemoryContextAlloc(TopMemoryContext, JUMBLE_SIZE);
+ /* Allocate space for bookkeeping information for query str normalization */
+ last_offsets = MemoryContextAlloc(TopMemoryContext, last_offset_buf_size * sizeof(pgssTokenOffset));
+
/*
* Install hooks.
*/
*************** _PG_init(void)
*** 277,282 ****
--- 342,352 ----
ExecutorEnd_hook = pgss_ExecutorEnd;
prev_ProcessUtility = ProcessUtility_hook;
ProcessUtility_hook = pgss_ProcessUtility;
+ /*
+ * Install hooks for query normalization
+ */
+ prev_Planner = planner_hook;
+ planner_hook = pgss_PlannerRun;
}
/*
*************** _PG_fini(void)
*** 292,297 ****
--- 362,371 ----
ExecutorFinish_hook = prev_ExecutorFinish;
ExecutorEnd_hook = prev_ExecutorEnd;
ProcessUtility_hook = prev_ProcessUtility;
+ prev_Planner = planner_hook;
+
+ pfree(last_jumble);
+ pfree(last_offsets);
}
/*
*************** _PG_fini(void)
*** 300,306 ****
*/
static void
pgss_shmem_startup(void)
! {
bool found;
HASHCTL info;
FILE *file;
--- 374,380 ----
*/
static void
pgss_shmem_startup(void)
! {
bool found;
HASHCTL info;
FILE *file;
*************** pgss_shmem_startup(void)
*** 395,421 ****
if (!PG_VALID_BE_ENCODING(temp.key.encoding))
goto error;
/* Previous incarnation might have had a larger query_size */
! if (temp.key.query_len >= buffer_size)
{
! buffer = (char *) repalloc(buffer, temp.key.query_len + 1);
! buffer_size = temp.key.query_len + 1;
}
! if (fread(buffer, 1, temp.key.query_len, file) != temp.key.query_len)
goto error;
! buffer[temp.key.query_len] = '\0';
/* Clip to available length if needed */
! if (temp.key.query_len >= query_size)
! temp.key.query_len = pg_encoding_mbcliplen(temp.key.encoding,
buffer,
! temp.key.query_len,
query_size - 1);
- temp.key.query_ptr = buffer;
/* make the hashtable entry (discards old entries if too many) */
! entry = entry_alloc(&temp.key);
/* copy in the actual stats */
entry->counters = temp.counters;
--- 469,496 ----
if (!PG_VALID_BE_ENCODING(temp.key.encoding))
goto error;
+
/* Previous incarnation might have had a larger query_size */
! if (temp.query_len >= buffer_size)
{
! buffer = (char *) repalloc(buffer, temp.query_len + 1);
! buffer_size = temp.query_len + 1;
}
! if (fread(buffer, 1, temp.query_len, file) != temp.query_len)
goto error;
! buffer[temp.query_len] = '\0';
!
/* Clip to available length if needed */
! if (temp.query_len >= query_size)
! temp.query_len = pg_encoding_mbcliplen(temp.key.encoding,
buffer,
! temp.query_len,
query_size - 1);
/* make the hashtable entry (discards old entries if too many) */
! entry = entry_alloc(&temp.key, buffer, temp.query_len);
/* copy in the actual stats */
entry->counters = temp.counters;
*************** pgss_shmem_shutdown(int code, Datum arg)
*** 477,483 ****
hash_seq_init(&hash_seq, pgss_hash);
while ((entry = hash_seq_search(&hash_seq)) != NULL)
{
! int len = entry->key.query_len;
if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 ||
fwrite(entry->query, 1, len, file) != len)
--- 552,558 ----
hash_seq_init(&hash_seq, pgss_hash);
while ((entry = hash_seq_search(&hash_seq)) != NULL)
{
! int len = entry->query_len;
if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 ||
fwrite(entry->query, 1, len, file) != len)
*************** error:
*** 500,505 ****
--- 575,1391 ----
if (file)
FreeFile(file);
unlink(PGSS_DUMP_FILE);
+
+ }
+
+ /*
+ * pgss_PlannerRun: Planner plugin. Will selectively serialize the query tree
+ * for the purposes of query normalization if that's appropriate.
+ */
+ PlannedStmt *
+ pgss_PlannerRun(Query *parse, int cursorOptions, ParamListInfo boundParams)
+ {
+ if (!parse->utilityStmt && !pgss_string_key)
+ {
+ /*
+ * Only generate a jumble if we have no reason to hash the query string
+ * directly instead
+ */
+ JumbleQuery(parse);
+ }
+ /* Invoke the planner */
+ if (prev_Planner)
+ return prev_Planner(parse, cursorOptions, boundParams);
+ else
+ return standard_planner(parse, cursorOptions, boundParams);
+ }
+
+ /*
+ * comp_offset: Comparator for qsorting pgssTokenOffset values by their
+ * position in the original query string. Often when walking the query tree,
+ * Const tokens will be found in the same order as in the original query string,
+ * but this is certainly not guaranteed.
+ */
+ static int comp_offset(const void *a, const void *b)
+ {
+ int l = ((pgssTokenOffset*) a)->offset;
+ int r = ((pgssTokenOffset*) b)->offset;
+ if (l < r)
+ return -1;
+ else if (l > r)
+ return +1;
+ else
+ return 0;
+ }
+
+ /*
+ * JumbleQuery: Selectively serialize query tree, and store it until
+ * needed to hash the query "parse".
+ */
+ static void JumbleQuery(Query *parse)
+ {
+ /* State for this run of PerformJumble */
+ size_t i = 0;
+ last_offset_num = 0;
+ memset(last_jumble, 0, JUMBLE_SIZE);
+ last_jumble[++i] = HASH_BUF;
+ PerformJumble(parse, JUMBLE_SIZE, &i);
+ /* Sort offsets for query string normalization */
+ qsort(last_offsets, last_offset_num, sizeof(pgssTokenOffset), comp_offset);
+ }
+
+ /*
+ * AppendJumb: Append a value that is substantive to a given query to jumble,
+ * while incrementing the iterator.
+ */
+ static bool AppendJumb(char* item, char jumble[], size_t size, size_t *i)
+ {
+ Assert(item != NULL);
+ Assert(jumble != NULL);
+ Assert(i != NULL);
+
+ /*
+ * Copy the entire item to the buffer, or as much of it as possible to fill
+ * the buffer to capacity.
+ */
+ memcpy(jumble + *i, item, Min(*i >= JUMBLE_SIZE? 0:JUMBLE_SIZE - *i, size));
+
+ if (size + *i >= JUMBLE_SIZE)
+ {
+ /*
+ * While byte-for-byte, the jumble representation will often be a lot more
+ * compact than the query string, it's possible JUMBLE_SIZE has been set to
+ * a very small value. Besides, it's always possible to contrive a query
+ * where it won't be as compact, such as
+ * "select * from table_with_many_columns". Control is not expected to
+ * reach here most of the time, as this is considered an edge-case.
+ */
+ if (size + *i >= JUMBLE_SIZE * 5)
+ /* Give up completely, to avoid a possible stack overflow */
+ return false;
+ /*
+ * Don't give up yet...don't append any more, but keep walking the tree
+ * to find Const nodes to canonicalize. Having done all we can with the
+ * jumble, we must still concern ourselves with the normalized query
+ * str.
+ */
+ }
+ *i += size;
+ return true;
+ }
+
+ /*
+ * Wrapper around AppendJumb to encapsulate details of serialization
+ * of individual elements.
+ */
+ #define APP_JUMB(item) \
+ if (!AppendJumb((char*)&item, last_jumble, sizeof(item), i))\
+ return false;
+
+ /*
+ * Simple wrappers around functions so that they return upon reaching
+ * end of buffer
+ */
+ #define PERFORM_JUMBLE(item, size, i) \
+ if (!PerformJumble(item, size, i))\
+ return false;
+
+ #define QUALS_NODE(item, size, i, rtable) \
+ if (!QualsNode(item, size, i, rtable)) \
+ return false;
+
+ #define LEAF_NODES(item, size, i, rtable) \
+ if (!LeafNodes(item, size, i, rtable)) \
+ return false;
+
+ #define LIMIT_OFFSET_NODE(item, size, i, rtable) \
+ if (!LimitOffsetNode(item, size, i, rtable)) \
+ return false;
+
+ #define JOIN_EXPR_NODE(item, size, i, rtable) \
+ if (!JoinExprNode(item, size, i, rtable)) \
+ return false;
+
+ #define JOIN_EXPR_NODE_CHILD(item, size, i, rtable) \
+ if (!JoinExprNodeChild(item, size, i, rtable)) \
+ return false;
+
+ /*
+ * PerformJumble: Serialize the query tree "parse" and canonicalize
+ * constants, while simply skipping over others that are not essential to the
+ * query, such that it is usefully normalized, excluding things from the tree
+ * that are not essential to the query itself.
+ *
+ * A guiding principal as to whether two queries should be considered
+ * equivalent is whether whatever difference exists between the two queries
+ * could be expected to result in two different plans, assuming that all
+ * constants have the same selectivity estimate and excluding factors that are
+ * not essential to the query and the relations on which it operates. A
+ * non-obvious example of such a differentiator is a change in the definition
+ * of a view referenced by a query. We pointedly serialize the query tree
+ * *after* the rewriting stage, so entries in pg_stat_statements accurately
+ * represent discrete operations, while not having artifacts from external
+ * factors that are not essential to what the query actually does. Directly
+ * hashing plans would have the undesirable side-effect of potentially having
+ * totally external factors like planner cost constants differentiate a query,
+ * so that particular implementation was not chosen. Directly hashing the raw
+ * parse tree would prevent us from benefiting from the parser's own
+ * normalization of queries in later stages, such as removing differences
+ * between equivalent syntax, so that implementation was avoided too.
+ *
+ * The last_jumble buffer, that this function scribbles on, can be hashed to
+ * uniquely identify a query that may use different constants in successive
+ * calls.
+ */
+ static bool PerformJumble(const Query *parse, size_t size, size_t *i)
+ {
+ ListCell *l;
+ /* table join tree (FROM and WHERE clauses) */
+ FromExpr *jt = (FromExpr *) parse->jointree;
+ /* # of result tuples to skip (int8 expr) */
+ FuncExpr *off = (FuncExpr *) parse->limitOffset;
+ /* # of result tuples to skip (int8 expr) */
+ FuncExpr *limcount = (FuncExpr *) parse->limitCount;
+
+ APP_JUMB(parse->resultRelation);
+
+ if (parse->intoClause)
+ {
+ IntoClause *ic = parse->intoClause;
+ RangeVar *rel = ic->rel;
+ APP_JUMB(ic->onCommit);
+ APP_JUMB(ic->skipData);
+ if (rel)
+ {
+ APP_JUMB(rel->relpersistence);
+ /* Bypass macro abstraction to supply size directly.
+ *
+ * Serialize schemaname, relname themselves - this is to be
+ * somewhat consistent with the behavior of utility statements like "create
+ * table".
+ */
+ if ( (rel->schemaname && !AppendJumb(rel->schemaname, last_jumble, strlen(rel->schemaname), i)) ||
+ (rel->relname && !AppendJumb(rel->relname, last_jumble, strlen(rel->relname), i) )
+ )
+ return false;
+ }
+ }
+
+ /* WITH list (of CommonTableExpr's) */
+ foreach(l, parse->cteList)
+ {
+ CommonTableExpr *cte = (CommonTableExpr *) lfirst(l);
+ Query *cteq = (Query*) cte->ctequery;
+ if (cteq)
+ PERFORM_JUMBLE(cteq, size, i);
+ }
+ if (jt)
+ {
+ if (jt->quals)
+ {
+ if (IsA(jt->quals, OpExpr))
+ {
+ QUALS_NODE((OpExpr*) jt->quals, size, i, parse->rtable);
+ }
+ else
+ {
+ LEAF_NODES((Node*) jt->quals, size, i, parse->rtable);
+ }
+ }
+ /* table join tree */
+ foreach(l, jt->fromlist)
+ {
+ Node* fr = lfirst(l);
+ if (IsA(fr, JoinExpr))
+ {
+ JOIN_EXPR_NODE((JoinExpr*) fr, size, i, parse->rtable);
+ }
+ else if (IsA(fr, RangeTblRef))
+ {
+ RangeTblRef *rtf = (RangeTblRef *) fr;
+ RangeTblEntry *rte = rt_fetch(rtf->rtindex, parse->rtable);
+ APP_JUMB(rte->relid);
+ APP_JUMB(rte->rtekind);
+ /* Subselection in where clause */
+ if (rte->subquery)
+ PERFORM_JUMBLE(rte->subquery, size, i);
+
+ /* Function call in where clause */
+ if (rte->funcexpr)
+ LEAF_NODES((Node*) rte->funcexpr, size, i, parse->rtable);
+ }
+ else
+ {
+ elog(ERROR, "unrecognized fromlist node type: %d",
+ (int) nodeTag(fr));
+ }
+ }
+ }
+ /*
+ * target list (of TargetEntry)
+ * columns returned by query
+ */
+ foreach(l, parse->targetList)
+ {
+ TargetEntry *tg = (TargetEntry *) lfirst(l);
+ Node *e = (Node*) tg->expr;
+ if (tg->ressortgroupref)
+ APP_JUMB(tg->ressortgroupref); /* nonzero if referenced by a sort/group - for ORDER BY */
+ APP_JUMB(tg->resno); /* column number for select */
+ /* Handle the various types of nodes in
+ * the select list of this query
+ */
+ LEAF_NODES(e, size, i, parse->rtable);
+ }
+ /* return-values list (of TargetEntry) */
+ foreach(l, parse->returningList)
+ {
+ TargetEntry *rt = (TargetEntry *) lfirst(l);
+ Expr *e = (Expr*) rt->expr;
+ /*
+ * Handle the various types of nodes in
+ * the select list of this query
+ */
+ if (IsA(e, Var)) /* table column */
+ {
+ Var *v = (Var*) e;
+ RangeTblEntry *rte = rt_fetch(v->varno, parse->rtable);
+ APP_JUMB(rte->relid);
+ APP_JUMB(v->varattno);
+ }
+ else
+ {
+ elog(ERROR, "unrecognized node type for returnlist node: %d",
+ (int) nodeTag(e));
+ }
+ }
+ /* a list of SortGroupClause's */
+ foreach(l, parse->groupClause)
+ {
+ SortGroupClause *gc = (SortGroupClause *) lfirst(l);
+ APP_JUMB(gc->tleSortGroupRef);
+ APP_JUMB(gc->nulls_first);
+ }
+
+ if (parse->havingQual)
+ {
+ if (IsA(parse->havingQual, OpExpr))
+ {
+ OpExpr *na = (OpExpr *) parse->havingQual;
+ QUALS_NODE(na, size, i, parse->rtable);
+ }
+ else
+ {
+ elog(ERROR, "unrecognized node type for havingclause node: %d",
+ (int) nodeTag(parse->havingQual));
+ }
+ }
+ foreach(l, parse->windowClause)
+ {
+ WindowClause *wc = (WindowClause *) lfirst(l);
+ ListCell *il;
+ APP_JUMB(wc->frameOptions);
+ foreach(il, wc->partitionClause) /* PARTITION BY list */
+ {
+ Node *n = (Node *) lfirst(il);
+ LEAF_NODES(n, size, i, parse->rtable);
+ }
+ foreach(il, wc->orderClause) /* ORDER BY list */
+ {
+ Node *n = (Node *) lfirst(il);
+ LEAF_NODES(n, size, i, parse->rtable);
+ }
+ }
+
+ foreach(l, parse->distinctClause)
+ {
+ SortGroupClause *dc = (SortGroupClause *) lfirst(l);
+ APP_JUMB(dc->tleSortGroupRef);
+ APP_JUMB(dc->nulls_first);
+ }
+
+ /* Don't look at parse->sortClause,
+ * because the value ressortgroupref is already
+ * serialized when we iterate through targetList
+ */
+
+ if (off)
+ LIMIT_OFFSET_NODE((Node*) off, size, i, parse->rtable);
+
+ if (limcount)
+ LIMIT_OFFSET_NODE((Node*) limcount, size, i, parse->rtable);
+
+ foreach(l, parse->rowMarks)
+ {
+ RowMarkClause *rc = (RowMarkClause *) lfirst(l);
+ APP_JUMB(rc->rti); /* range table index of target relation */
+ APP_JUMB(rc->forUpdate); /* true = FOR UPDATE, false = FOR SHARE */
+ APP_JUMB(rc->noWait); /* NOWAIT option */
+ APP_JUMB(rc->pushedDown); /* pushed down from higher query level? */
+ }
+
+ if (parse->setOperations)
+ {
+ /*
+ * set-operation tree if this is top
+ * level of a UNION/INTERSECT/EXCEPT query
+ */
+ SetOperationStmt *topop = (SetOperationStmt *) parse->setOperations;
+ APP_JUMB(topop->op);
+ APP_JUMB(topop->all);
+
+ /* leaf selects are RTE subselections */
+ foreach(l, parse->rtable)
+ {
+ RangeTblEntry *r = (RangeTblEntry *) lfirst(l);
+ if (r->subquery)
+ PERFORM_JUMBLE(r->subquery, size, i);
+ }
+ }
+ return true;
+ }
+
+ /*
+ * Perform selective serialization of "Quals" nodes when
+ * they're IsA(*, OpExpr)
+ */
+ static bool QualsNode(const OpExpr *node, size_t size, size_t *i, List *rtable)
+ {
+ ListCell *l;
+ APP_JUMB(node->opno);
+ foreach(l, node->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ return true;
+ }
+
+ /*
+ * LeafNodes: Selectively serialize a selection of parser/prim nodes that are
+ * frequently, though certainly not necesssarily leaf nodes, such as Vars
+ * (columns), constants and function calls
+ */
+ static bool LeafNodes(const Node *arg, size_t size, size_t *i, List *rtable)
+ {
+ ListCell *l;
+ if (IsA(arg, Const))
+ {
+ /*
+ * Serialize generic magic value to
+ * normalize constants
+ */
+ char magic = 0xC0;
+ Const *c = (Const *) arg;
+ APP_JUMB(magic);
+ /* Datatype of the constant is a
+ * differentiator
+ */
+ APP_JUMB(c->consttype);
+ /*
+ * Some Const nodes naturally don't have a location.
+ *
+ * Views that have constants in their
+ * definitions will have a tok_len of 0
+ */
+ if (c->location > 0 && c->tok_len > 0)
+ {
+ if (last_offset_num >= last_offset_buf_size)
+ {
+ last_offset_buf_size *= 2;
+ last_offsets = repalloc(last_offsets, last_offset_buf_size * sizeof(pgssTokenOffset));
+ }
+ last_offsets[last_offset_num].offset = c->location;
+ last_offsets[last_offset_num].len = c->tok_len;
+ last_offset_num++;
+ }
+ }
+ else if (IsA(arg, Var))
+ {
+ char magic = 0xFA;
+ Var *v = (Var *) arg;
+ RangeTblEntry *rte = rt_fetch(v->varno, rtable);
+ APP_JUMB(magic);
+ APP_JUMB(rte->relid);
+ APP_JUMB(v->varattno); /* column number of table */
+ }
+ else if (IsA(arg, Param))
+ {
+ Param *p = ((Param *) arg);
+ APP_JUMB(p->paramkind);
+ APP_JUMB(p->paramid);
+ }
+ else if (IsA(arg, RelabelType))
+ {
+ APP_JUMB(((RelabelType *) arg)->resulttype);
+ }
+ else if (IsA(arg, WindowFunc))
+ {
+ WindowFunc *wf = (WindowFunc *) arg;
+ APP_JUMB(wf->winfnoid);
+ foreach(l, wf->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, FuncExpr))
+ {
+ FuncExpr *f = (FuncExpr *) arg;
+ APP_JUMB(f->funcid);
+ foreach(l, f->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, OpExpr))
+ {
+ QUALS_NODE((OpExpr*) arg, size, i, rtable);
+ }
+ else if (IsA(arg, CoerceViaIO))
+ {
+ APP_JUMB(((CoerceViaIO*) arg)->coerceformat);
+ APP_JUMB(((CoerceViaIO*) arg)->resulttype);
+ }
+ else if (IsA(arg, Aggref))
+ {
+ Aggref *a = (Aggref *) arg;
+ APP_JUMB(a->aggfnoid);
+ foreach(l, a->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, SubLink))
+ {
+ SubLink *s = (SubLink*) arg;
+ APP_JUMB(s->subLinkType);
+ /* Serialize select-list subselect recursively */
+ if (s->subselect)
+ PERFORM_JUMBLE((Query*) s->subselect, size, i);
+ }
+ else if (IsA(arg, TargetEntry))
+ {
+ TargetEntry *rt = (TargetEntry *) arg;
+ Node *e = (Node*) rt->expr;
+ APP_JUMB(rt->resorigtbl); /* OID of column's source table */
+ APP_JUMB(rt->ressortgroupref); /* nonzero if referenced by a sort/group - for ORDER BY */
+ LEAF_NODES(e, size, i, rtable);
+ }
+ else if (IsA(arg, BoolExpr))
+ {
+ BoolExpr *be = (BoolExpr *) arg;
+ APP_JUMB(be->boolop);
+ foreach(l, be->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, NullTest))
+ {
+ NullTest *nt = (NullTest *) arg;
+ Node *arg = (Node *) nt->arg;
+ APP_JUMB(nt->nulltesttype); /* IS NULL, IS NOT NULL */
+ APP_JUMB(nt->argisrow); /* is input a composite type ? */
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ else if (IsA(arg, ArrayExpr))
+ {
+ ArrayExpr *ae = (ArrayExpr *) arg;
+ APP_JUMB(ae->array_typeid); /* type of expression result */
+ APP_JUMB(ae->element_typeid); /* common type of array elements */
+ foreach(l, ae->elements)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, CaseExpr))
+ {
+ CaseExpr *ce = (CaseExpr*) arg;
+ Assert(ce->casetype != InvalidOid);
+ APP_JUMB(ce->casetype);
+ foreach(l, ce->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ if (ce->arg)
+ LEAF_NODES((Node*) ce->arg, size, i, rtable);
+
+ if (ce->defresult)
+ {
+ /* Default result (ELSE clause)
+ * The ptr may be NULL, because no else clause
+ * was actually specified, and thus the value is
+ * equivalent to SQL ELSE NULL
+ */
+ LEAF_NODES((Node*) ce->defresult, size, i, rtable); /* the default result (ELSE clause) */
+ }
+ }
+ else if (IsA(arg, CaseTestExpr))
+ {
+ CaseTestExpr *ct = (CaseTestExpr*) arg;
+ APP_JUMB(ct->typeId);
+ }
+ else if (IsA(arg, CaseWhen))
+ {
+ CaseWhen *cw = (CaseWhen*) arg;
+ Node *res = (Node*) cw->result;
+ Node *exp = (Node*) cw->expr;
+ if (res)
+ LEAF_NODES(res, size, i, rtable);
+ if (exp)
+ LEAF_NODES(exp, size, i, rtable);
+ }
+ else if (IsA(arg, MinMaxExpr))
+ {
+ MinMaxExpr *cw = (MinMaxExpr*) arg;
+ APP_JUMB(cw->minmaxtype);
+ APP_JUMB(cw->op);
+ foreach(l, cw->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, ScalarArrayOpExpr))
+ {
+ ScalarArrayOpExpr *sa = (ScalarArrayOpExpr*) arg;
+ APP_JUMB(sa->opfuncid);
+ APP_JUMB(sa->useOr);
+ foreach(l, sa->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, CoalesceExpr))
+ {
+ CoalesceExpr *ca = (CoalesceExpr*) arg;
+ foreach(l, ca->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, ArrayCoerceExpr))
+ {
+ ArrayCoerceExpr *ac = (ArrayCoerceExpr *) arg;
+ LEAF_NODES((Node*) ac->arg, size, i, rtable);
+ }
+ else if (IsA(arg, WindowClause))
+ {
+ WindowClause *wc = (WindowClause*) arg;
+ foreach(l, wc->partitionClause)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ foreach(l, wc->orderClause)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, SortGroupClause))
+ {
+ SortGroupClause *sgc = (SortGroupClause*) arg;
+ APP_JUMB(sgc->tleSortGroupRef);
+ APP_JUMB(sgc->nulls_first);
+ }
+ else if (IsA(arg, Integer) ||
+ IsA(arg, Float) ||
+ IsA(arg, String) ||
+ IsA(arg, BitString) ||
+ IsA(arg, Null)
+ )
+ {
+ /* It is not necessary to
+ * serialize integral values
+ */
+ }
+ else if (IsA(arg, BooleanTest))
+ {
+ BooleanTest *bt = (BooleanTest *) arg;
+ APP_JUMB(bt->booltesttype);
+ LEAF_NODES((Node*) bt->arg, size, i, rtable);
+ }
+ else if (IsA(arg, ArrayRef))
+ {
+ ArrayRef *ar = (ArrayRef*) arg;
+ APP_JUMB(ar->refarraytype);
+ foreach(l, ar->refupperindexpr)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ foreach(l, ar->reflowerindexpr)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, NullIfExpr))
+ {
+ /* NullIfExpr is just a typedef for OpExpr */
+ QUALS_NODE((OpExpr*) arg, size, i, rtable);
+ }
+ else if (IsA(arg, RowExpr))
+ {
+ RowExpr *re = (RowExpr*) arg;
+ APP_JUMB(re->row_format);
+ foreach(l, re->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+
+ }
+ else if (IsA(arg, XmlExpr))
+ {
+ XmlExpr *xml = (XmlExpr*) arg;
+ APP_JUMB(xml->op);
+ foreach(l, xml->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ foreach(l, xml->named_args) /* non-XML expressions for xml_attributes */
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ foreach(l, xml->arg_names) /* parallel list of Value strings */
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(arg, RowCompareExpr))
+ {
+ RowCompareExpr *rc = (RowCompareExpr*) arg;
+ foreach(l, rc->largs)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ foreach(l, rc->rargs)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else
+ {
+ elog(ERROR, "unrecognized node type for LeafNodes node: %d",
+ (int) nodeTag(arg));
+ }
+ return true;
+ }
+
+ /*
+ * Perform selective serialization of limit or offset nodes
+ */
+ static bool LimitOffsetNode(const Node *node, size_t size, size_t *i, List *rtable)
+ {
+ ListCell *l;
+ if (IsA(node, FuncExpr))
+ {
+ foreach(l, ((FuncExpr*) node)->args)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(node, Const))
+ {
+ /* This should be a differentiator, as it results in the addition of a limit node */
+ char magic = 0xEA;
+ APP_JUMB(magic);
+ }
+ else
+ {
+ /* Fall back on leaf node representation */
+ LEAF_NODES(node, size, i, rtable);
+ }
+ return true;
+ }
+
+ /*
+ * JoinExprNode: Perform selective serialization of JoinExpr nodes
+ */
+ static bool JoinExprNode(JoinExpr *node, size_t size, size_t *i, List *rtable)
+ {
+ Node *larg = node->larg; /* left subtree */
+ Node *rarg = node->rarg; /* right subtree */
+ ListCell *l;
+
+ Assert( IsA(node, JoinExpr));
+
+ APP_JUMB(node->jointype);
+ APP_JUMB(node->isNatural);
+
+ if (node->quals)
+ {
+ if ( IsA(node, OpExpr))
+ {
+ QUALS_NODE((OpExpr*) node->quals, size, i, rtable);
+ }
+ else
+ {
+ LEAF_NODES((Node*) node->quals, size, i, rtable);
+ }
+
+ }
+ foreach(l, node->usingClause) /* USING clause, if any (list of String) */
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ if (larg)
+ JOIN_EXPR_NODE_CHILD(larg, size, i, rtable);
+ if (rarg)
+ JOIN_EXPR_NODE_CHILD(rarg, size, i, rtable);
+
+ return true;
+ }
+
+ /*
+ * JoinExprNodeChild: Serialize children of the JoinExpr node
+ */
+ static bool JoinExprNodeChild(const Node *node, size_t size, size_t *i, List *rtable)
+ {
+ if (IsA(node, RangeTblRef))
+ {
+ RangeTblRef *rt = (RangeTblRef*) node;
+ RangeTblEntry *rte = rt_fetch(rt->rtindex, rtable);
+ ListCell *l;
+
+ APP_JUMB(rte->relid);
+ APP_JUMB(rte->jointype);
+
+ if (rte->subquery)
+ PERFORM_JUMBLE((Query*) rte->subquery, size, i);
+
+ foreach(l, rte->joinaliasvars)
+ {
+ Node *arg = (Node *) lfirst(l);
+ LEAF_NODES(arg, size, i, rtable);
+ }
+ }
+ else if (IsA(node, JoinExpr))
+ {
+ JOIN_EXPR_NODE((JoinExpr*) node, size, i, rtable);
+ }
+ else
+ {
+ LEAF_NODES(node, size, i, rtable);
+ }
+ return true;
}
/*
*************** pgss_ExecutorEnd(QueryDesc *queryDesc)
*** 591,600 ****
--- 1477,1527 ----
*/
InstrEndLoop(queryDesc->totaltime);
+ if (queryDesc->params || queryDesc->utilitystmt || pgss_string_key)
+ {
+ /*
+ * This query was paramaterized or is a utility statement, or
+ * pg_stat_statements is in legacy pgss_string_key mode - hash the
+ * query string, as the last call to pgss_PlannerRun won't have
+ * hashed the tree of this particular query - it may have skipped
+ * hashing, or there may not have even been a call corresponding to
+ * a call to this call of pgss_ExecutorEnd.
+ *
+ * If we're dealing with a parameterized query, the query string
+ * is the original query string anyway, so there is no need to
+ * worry about its stability.
+ *
+ * The fact that constants in the prepared query won't be
+ * canonicalized is clearly a feature rather than a bug, as the
+ * user evidently considers such constant essential to the query, or
+ * they'd have paramaterized them.
+ */
+ memset(last_jumble, 0, JUMBLE_SIZE);
+ last_jumble[0] = STR_BUF;
+ memcpy(last_jumble + 1, queryDesc->sourceText,
+ Min(JUMBLE_SIZE - 1, strlen(queryDesc->sourceText) )
+ );
+ }
+ /*
+ * There is an assumption that last_* variables were set by a prior,
+ * corresponding call to pgss_PlannerRun within this backend (provided
+ * that we jumbled the query tree with the intention of hashing it - that
+ * won't be the case if the jumble is actually just a STR_BUF copy of
+ * the query string).
+ */
pgss_store(queryDesc->sourceText,
+ last_jumble,
+ last_offsets,
+ last_offset_num,
queryDesc->totaltime->total,
queryDesc->estate->es_processed,
&queryDesc->totaltime->bufusage);
+
+ if (last_offset_buf_size > 10)
+ {
+ last_offset_buf_size = 10;
+ last_offsets = repalloc(last_offsets, last_offset_buf_size * sizeof(pgssTokenOffset));
+ }
}
if (prev_ExecutorEnd)
*************** pgss_ProcessUtility(Node *parsetree, con
*** 665,671 ****
bufusage.temp_blks_written =
pgBufferUsage.temp_blks_written - bufusage.temp_blks_written;
! pgss_store(queryString, INSTR_TIME_GET_DOUBLE(duration), rows,
&bufusage);
}
else
--- 1592,1605 ----
bufusage.temp_blks_written =
pgBufferUsage.temp_blks_written - bufusage.temp_blks_written;
! /* In the case of utility statements, hash the query string directly */
! memset(last_jumble, 0, JUMBLE_SIZE);
! last_jumble[0] = STR_BUF;
! memcpy(last_jumble + 1, queryString,
! Min(JUMBLE_SIZE - 1, strlen(queryString) )
! );
!
! pgss_store(queryString, last_jumble, NULL, 0, INSTR_TIME_GET_DOUBLE(duration), rows,
&bufusage);
}
else
*************** pgss_hash_fn(const void *key, Size keysi
*** 690,697 ****
/* we don't bother to include encoding in the hash */
return hash_uint32((uint32) k->userid) ^
hash_uint32((uint32) k->dbid) ^
! DatumGetUInt32(hash_any((const unsigned char *) k->query_ptr,
! k->query_len));
}
/*
--- 1624,1630 ----
/* we don't bother to include encoding in the hash */
return hash_uint32((uint32) k->userid) ^
hash_uint32((uint32) k->dbid) ^
! DatumGetUInt32(hash_any((const unsigned char* ) k->jumble, JUMBLE_SIZE) );
}
/*
*************** pgss_match_fn(const void *key1, const vo
*** 706,713 ****
if (k1->userid == k2->userid &&
k1->dbid == k2->dbid &&
k1->encoding == k2->encoding &&
! k1->query_len == k2->query_len &&
! memcmp(k1->query_ptr, k2->query_ptr, k1->query_len) == 0)
return 0;
else
return 1;
--- 1639,1645 ----
if (k1->userid == k2->userid &&
k1->dbid == k2->dbid &&
k1->encoding == k2->encoding &&
! memcmp(k1->jumble, k2->jumble, JUMBLE_SIZE) == 0)
return 0;
else
return 1;
*************** pgss_match_fn(const void *key1, const vo
*** 717,727 ****
* Store some statistics for a statement.
*/
static void
! pgss_store(const char *query, double total_time, uint64 rows,
! const BufferUsage *bufusage)
{
pgssHashKey key;
double usage;
pgssEntry *entry;
Assert(query != NULL);
--- 1649,1663 ----
* Store some statistics for a statement.
*/
static void
! pgss_store(const char *query, char jumble[],
! pgssTokenOffset offs[], int off_n,
! double total_time, uint64 rows,
! const BufferUsage *bufusage)
{
pgssHashKey key;
double usage;
+ int new_query_len = strlen(query);
+ char *norm_query = NULL;
pgssEntry *entry;
Assert(query != NULL);
*************** pgss_store(const char *query, double tot
*** 734,747 ****
key.userid = GetUserId();
key.dbid = MyDatabaseId;
key.encoding = GetDatabaseEncoding();
! key.query_len = strlen(query);
! if (key.query_len >= pgss->query_size)
! key.query_len = pg_encoding_mbcliplen(key.encoding,
query,
! key.query_len,
pgss->query_size - 1);
- key.query_ptr = query;
-
usage = USAGE_EXEC(duration);
/* Lookup the hash table entry with shared lock. */
--- 1670,1682 ----
key.userid = GetUserId();
key.dbid = MyDatabaseId;
key.encoding = GetDatabaseEncoding();
! memcpy(key.jumble, jumble, JUMBLE_SIZE);
!
! if (new_query_len >= pgss->query_size)
! new_query_len = pg_encoding_mbcliplen(key.encoding,
query,
! new_query_len,
pgss->query_size - 1);
usage = USAGE_EXEC(duration);
/* Lookup the hash table entry with shared lock. */
*************** pgss_store(const char *query, double tot
*** 750,759 ****
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
if (!entry)
{
! /* Must acquire exclusive lock to add a new entry. */
! LWLockRelease(pgss->lock);
! LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
! entry = entry_alloc(&key);
}
/* Grab the spinlock while updating the counters. */
--- 1685,1755 ----
entry = (pgssEntry *) hash_search(pgss_hash, &key, HASH_FIND, NULL);
if (!entry)
{
! /*
! * It is necessary to generate a normalized version of the query
! * string that will be used to represent it. It's important that
! * the user be presented with a stable representation of the query.
! *
! * Note that the representation seen by the user will only have
! * non-differentiating Const tokens swapped with '?' characters, and
! * this does not for example take account of the fact that alias names
! * could vary between successive calls of what is regarded as the same
! * query.
! */
! if (off_n > 0)
! {
! int i,
! last_off = 0,
! quer_it = 0,
! n_quer_it = 0,
! off = 0,
! tok_len = 0,
! len_to_wrt = 0,
! last_tok_len = 0;
!
! norm_query = palloc0(new_query_len + 1);
! for(i = 0; i < off_n; i++)
! {
! off = offs[i].offset;
! tok_len = offs[i].len;
! len_to_wrt = off - last_off;
! len_to_wrt -= last_tok_len;
! /*
! * Each iteration copies everything prior to the current
! * offset/token to be replaced, except bytes copied in
! * previous iterations
! */
! if (off + tok_len > new_query_len)
! break;
! memcpy(norm_query + n_quer_it, query + quer_it, len_to_wrt);
!
! n_quer_it += len_to_wrt;
! norm_query[n_quer_it++] = '?';
! quer_it += len_to_wrt + tok_len;
! last_off = off;
! last_tok_len = tok_len;
! }
! /* Finish off last piece of query string */
! memcpy(norm_query + n_quer_it, query + (off + tok_len),
! Min( strlen(query) - (off + tok_len),
! new_query_len - n_quer_it ) );
! /*
! * Must acquire exclusive lock to add a new entry.
! * Leave that until as late as possible.
! */
! LWLockRelease(pgss->lock);
! LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
!
! entry = entry_alloc(&key, norm_query, strlen(norm_query));
! }
! else
! {
! /* Acquire exclusive lock as required by entry_alloc() */
! LWLockRelease(pgss->lock);
! LWLockAcquire(pgss->lock, LW_EXCLUSIVE);
!
! entry = entry_alloc(&key, query, new_query_len);
! }
}
/* Grab the spinlock while updating the counters. */
*************** pgss_store(const char *query, double tot
*** 775,782 ****
e->counters.usage += usage;
SpinLockRelease(&e->mutex);
}
-
LWLockRelease(pgss->lock);
}
/*
--- 1771,1779 ----
e->counters.usage += usage;
SpinLockRelease(&e->mutex);
}
LWLockRelease(pgss->lock);
+ if (norm_query)
+ pfree(norm_query);
}
/*
*************** pg_stat_statements(PG_FUNCTION_ARGS)
*** 857,869 ****
values[i++] = ObjectIdGetDatum(entry->key.userid);
values[i++] = ObjectIdGetDatum(entry->key.dbid);
if (is_superuser || entry->key.userid == userid)
{
char *qstr;
qstr = (char *)
pg_do_encoding_conversion((unsigned char *) entry->query,
! entry->key.query_len,
entry->key.encoding,
GetDatabaseEncoding());
values[i++] = CStringGetTextDatum(qstr);
--- 1854,1875 ----
values[i++] = ObjectIdGetDatum(entry->key.userid);
values[i++] = ObjectIdGetDatum(entry->key.dbid);
+ /* copy counters to a local variable to keep locking time short */
+ {
+ volatile pgssEntry *e = (volatile pgssEntry *) entry;
+
+ SpinLockAcquire(&e->mutex);
+ tmp = e->counters;
+ SpinLockRelease(&e->mutex);
+ }
+
if (is_superuser || entry->key.userid == userid)
{
char *qstr;
qstr = (char *)
pg_do_encoding_conversion((unsigned char *) entry->query,
! entry->query_len,
entry->key.encoding,
GetDatabaseEncoding());
values[i++] = CStringGetTextDatum(qstr);
*************** pg_stat_statements(PG_FUNCTION_ARGS)
*** 873,887 ****
else
values[i++] = CStringGetTextDatum("<insufficient privilege>");
- /* copy counters to a local variable to keep locking time short */
- {
- volatile pgssEntry *e = (volatile pgssEntry *) entry;
-
- SpinLockAcquire(&e->mutex);
- tmp = e->counters;
- SpinLockRelease(&e->mutex);
- }
-
values[i++] = Int64GetDatumFast(tmp.calls);
values[i++] = Float8GetDatumFast(tmp.total_time);
values[i++] = Int64GetDatumFast(tmp.rows);
--- 1879,1884 ----
*************** pgss_memsize(void)
*** 933,946 ****
* have made the entry while we waited to get exclusive lock.
*/
static pgssEntry *
! entry_alloc(pgssHashKey *key)
{
pgssEntry *entry;
bool found;
- /* Caller must have clipped query properly */
- Assert(key->query_len < pgss->query_size);
-
/* Make space if needed */
while (hash_get_num_entries(pgss_hash) >= pgss_max)
entry_dealloc();
--- 1930,1940 ----
* have made the entry while we waited to get exclusive lock.
*/
static pgssEntry *
! entry_alloc(pgssHashKey *key, const char* query, int new_query_len)
{
pgssEntry *entry;
bool found;
/* Make space if needed */
while (hash_get_num_entries(pgss_hash) >= pgss_max)
entry_dealloc();
*************** entry_alloc(pgssHashKey *key)
*** 950,968 ****
if (!found)
{
/* New entry, initialize it */
- /* dynahash tried to copy the key for us, but must fix query_ptr */
- entry->key.query_ptr = entry->query;
/* reset the statistics */
memset(&entry->counters, 0, sizeof(Counters));
entry->counters.usage = USAGE_INIT;
/* re-initialize the mutex each time ... we assume no one using it */
SpinLockInit(&entry->mutex);
/* ... and don't forget the query text */
! memcpy(entry->query, key->query_ptr, key->query_len);
! entry->query[key->query_len] = '\0';
}
return entry;
}
--- 1944,1964 ----
if (!found)
{
+ entry->query_len = new_query_len;
+ Assert(entry->query_len > 0);
/* New entry, initialize it */
/* reset the statistics */
memset(&entry->counters, 0, sizeof(Counters));
entry->counters.usage = USAGE_INIT;
/* re-initialize the mutex each time ... we assume no one using it */
SpinLockInit(&entry->mutex);
/* ... and don't forget the query text */
! memcpy(entry->query, query, entry->query_len);
! entry->query[entry->query_len] = '\0';
}
+ /* Caller must have clipped query properly */
+ Assert(entry->query_len < pgss->query_size);
return entry;
}
*************** entry_alloc(pgssHashKey *key)
*** 971,977 ****
* qsort comparator for sorting into increasing usage order
*/
static int
! entry_cmp(const void *lhs, const void *rhs)
{
double l_usage = (*(pgssEntry * const *) lhs)->counters.usage;
double r_usage = (*(pgssEntry * const *) rhs)->counters.usage;
--- 1967,1973 ----
* qsort comparator for sorting into increasing usage order
*/
static int
! entry_cmp_usage(const void *lhs, const void *rhs)
{
double l_usage = (*(pgssEntry * const *) lhs)->counters.usage;
double r_usage = (*(pgssEntry * const *) rhs)->counters.usage;
*************** entry_dealloc(void)
*** 1009,1015 ****
entry->counters.usage *= USAGE_DECREASE_FACTOR;
}
! qsort(entries, i, sizeof(pgssEntry *), entry_cmp);
nvictims = Max(10, i * USAGE_DEALLOC_PERCENT / 100);
nvictims = Min(nvictims, i);
--- 2005,2011 ----
entry->counters.usage *= USAGE_DECREASE_FACTOR;
}
! qsort(entries, i, sizeof(pgssEntry *), entry_cmp_usage);
nvictims = Max(10, i * USAGE_DEALLOC_PERCENT / 100);
nvictims = Min(nvictims, i);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index e11d896..ccd92d3 100644
*** a/src/backend/catalog/heap.c
--- b/src/backend/catalog/heap.c
*************** cookDefault(ParseState *pstate,
*** 2441,2447 ****
atttypid, atttypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 2441,2447 ----
atttypid, atttypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index a949215..e80d57f 100644
*** a/src/backend/commands/prepare.c
--- b/src/backend/commands/prepare.c
*************** EvaluateParams(PreparedStatement *pstmt,
*** 365,371 ****
expected_type_id, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (expr == NULL)
ereport(ERROR,
--- 365,371 ----
expected_type_id, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (expr == NULL)
ereport(ERROR,
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 1ee201c..f6b64d5 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
*************** ATExecAddColumn(List **wqueue, AlteredTa
*** 4493,4499 ****
typmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (defval == NULL) /* should not happen */
elog(ERROR, "failed to coerce base type to domain");
}
--- 4493,4499 ----
typmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (defval == NULL) /* should not happen */
elog(ERROR, "failed to coerce base type to domain");
}
*************** ATPrepAlterColumnType(List **wqueue,
*** 6987,6993 ****
targettype, targettypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (transform == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 6987,6993 ----
targettype, targettypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (transform == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** ATExecAlterColumnType(AlteredTableInfo *
*** 7154,7160 ****
targettype, targettypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (defaultexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 7154,7160 ----
targettype, targettypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (defaultexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 7178b52..c40a1bf 100644
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
*************** _copyAConst(const A_Const *from)
*** 2130,2135 ****
--- 2130,2136 ----
}
COPY_LOCATION_FIELD(location);
+ COPY_LOCATION_FIELD(tok_len);
return newnode;
}
*************** _copyTypeCast(const TypeCast *from)
*** 2284,2289 ****
--- 2285,2291 ----
COPY_NODE_FIELD(arg);
COPY_NODE_FIELD(typeName);
COPY_LOCATION_FIELD(location);
+ COPY_LOCATION_FIELD(tok_len);
return newnode;
}
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c3e0ee1..1569b7d 100644
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 65,71 ****
#include "utils/numeric.h"
#include "utils/xml.h"
-
/* Location tracking support --- simpler than bison's default */
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
--- 65,70 ----
*************** static void base_yyerror(YYLTYPE *yylloc
*** 109,123 ****
const char *msg);
static Node *makeColumnRef(char *colname, List *indirection,
int location, core_yyscan_t yyscanner);
! static Node *makeTypeCast(Node *arg, TypeName *typename, int location);
! static Node *makeStringConst(char *str, int location);
! static Node *makeStringConstCast(char *str, int location, TypeName *typename);
! static Node *makeIntConst(int val, int location);
! static Node *makeFloatConst(char *str, int location);
! static Node *makeBitStringConst(char *str, int location);
! static Node *makeNullAConst(int location);
! static Node *makeAConst(Value *v, int location);
! static Node *makeBoolAConst(bool state, int location);
static FuncCall *makeOverlaps(List *largs, List *rargs,
int location, core_yyscan_t yyscanner);
static void check_qualified_name(List *names, core_yyscan_t yyscanner);
--- 108,122 ----
const char *msg);
static Node *makeColumnRef(char *colname, List *indirection,
int location, core_yyscan_t yyscanner);
! static Node *makeTypeCast(Node *arg, TypeName *typename, int location, int length);
! static Node *makeStringConst(char *str, int location, int length);
! static Node *makeStringConstCast(char *str, int location, int length, TypeName *typename);
! static Node *makeIntConst(int val, int location, int length);
! static Node *makeFloatConst(char *str, int location, int length);
! static Node *makeBitStringConst(char *str, int location, int length);
! static Node *makeNullAConst(int location, int length);
! static Node *makeAConst(Value *v, int location, int length);
! static Node *makeBoolAConst(bool state, int location, int length);
static FuncCall *makeOverlaps(List *largs, List *rargs,
int location, core_yyscan_t yyscanner);
static void check_qualified_name(List *names, core_yyscan_t yyscanner);
*************** static void insertSelectOptions(SelectSt
*** 131,137 ****
WithClause *withClause,
core_yyscan_t yyscanner);
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
! static Node *doNegate(Node *n, int location);
static void doNegateFloat(Value *v);
static Node *makeAArrayExpr(List *elements, int location);
static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
--- 130,136 ----
WithClause *withClause,
core_yyscan_t yyscanner);
static Node *makeSetOp(SetOperation op, bool all, Node *larg, Node *rarg);
! static Node *doNegate(Node *n, int location, int length);
static void doNegateFloat(Value *v);
static Node *makeAArrayExpr(List *elements, int location);
static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args,
*************** AlterOptRoleElem:
*** 912,918 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized role option \"%s\"", $1),
! parser_errposition(@1)));
}
;
--- 911,917 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("unrecognized role option \"%s\"", $1),
! parser_errposition(@1.begins)));
}
;
*************** set_rest: /* Generic SET syntaxes: */
*** 1298,1304 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("current database cannot be changed"),
! parser_errposition(@2)));
$$ = NULL; /*not reached*/
}
| SCHEMA Sconst
--- 1297,1303 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("current database cannot be changed"),
! parser_errposition(@2.begins)));
$$ = NULL; /*not reached*/
}
| SCHEMA Sconst
*************** set_rest: /* Generic SET syntaxes: */
*** 1306,1312 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "search_path";
! n->args = list_make1(makeStringConst($2, @2));
$$ = n;
}
| NAMES opt_encoding
--- 1305,1311 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "search_path";
! n->args = list_make1(makeStringConst($2, @2.begins, @2.length));
$$ = n;
}
| NAMES opt_encoding
*************** set_rest: /* Generic SET syntaxes: */
*** 1315,1321 ****
n->kind = VAR_SET_VALUE;
n->name = "client_encoding";
if ($2 != NULL)
! n->args = list_make1(makeStringConst($2, @2));
else
n->kind = VAR_SET_DEFAULT;
$$ = n;
--- 1314,1320 ----
n->kind = VAR_SET_VALUE;
n->name = "client_encoding";
if ($2 != NULL)
! n->args = list_make1(makeStringConst($2, @2.begins, @2.length));
else
n->kind = VAR_SET_DEFAULT;
$$ = n;
*************** set_rest: /* Generic SET syntaxes: */
*** 1325,1331 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "role";
! n->args = list_make1(makeStringConst($2, @2));
$$ = n;
}
| SESSION AUTHORIZATION ColId_or_Sconst
--- 1324,1330 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "role";
! n->args = list_make1(makeStringConst($2, @2.begins, @2.length));
$$ = n;
}
| SESSION AUTHORIZATION ColId_or_Sconst
*************** set_rest: /* Generic SET syntaxes: */
*** 1333,1339 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "session_authorization";
! n->args = list_make1(makeStringConst($3, @3));
$$ = n;
}
| SESSION AUTHORIZATION DEFAULT
--- 1332,1338 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "session_authorization";
! n->args = list_make1(makeStringConst($3, @3.begins, @3.length));
$$ = n;
}
| SESSION AUTHORIZATION DEFAULT
*************** set_rest: /* Generic SET syntaxes: */
*** 1348,1354 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "xmloption";
! n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3));
$$ = n;
}
/* Special syntaxes invented by PostgreSQL: */
--- 1347,1353 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_VALUE;
n->name = "xmloption";
! n->args = list_make1(makeStringConst($3 == XMLOPTION_DOCUMENT ? "DOCUMENT" : "CONTENT", @3.begins, @3.length));
$$ = n;
}
/* Special syntaxes invented by PostgreSQL: */
*************** set_rest: /* Generic SET syntaxes: */
*** 1357,1363 ****
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_MULTI;
n->name = "TRANSACTION SNAPSHOT";
! n->args = list_make1(makeStringConst($3, @3));
$$ = n;
}
;
--- 1356,1362 ----
VariableSetStmt *n = makeNode(VariableSetStmt);
n->kind = VAR_SET_MULTI;
n->name = "TRANSACTION SNAPSHOT";
! n->args = list_make1(makeStringConst($3, @3.begins, @3.length));
$$ = n;
}
;
*************** var_list: var_value { $$ = list_m
*** 1375,1383 ****
;
var_value: opt_boolean_or_string
! { $$ = makeStringConst($1, @1); }
| NumericOnly
! { $$ = makeAConst($1, @1); }
;
iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
--- 1374,1382 ----
;
var_value: opt_boolean_or_string
! { $$ = makeStringConst($1, @1.begins, @1.length); }
| NumericOnly
! { $$ = makeAConst($1, @1.begins, @1.length); }
;
iso_level: READ UNCOMMITTED { $$ = "read uncommitted"; }
*************** opt_boolean_or_string:
*** 1409,1419 ****
zone_value:
Sconst
{
! $$ = makeStringConst($1, @1);
}
| IDENT
{
! $$ = makeStringConst($1, @1);
}
| ConstInterval Sconst opt_interval
{
--- 1408,1418 ----
zone_value:
Sconst
{
! $$ = makeStringConst($1, @1.begins, @1.length);
}
| IDENT
{
! $$ = makeStringConst($1, @1.begins, @1.length);
}
| ConstInterval Sconst opt_interval
{
*************** zone_value:
*** 1425,1434 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
! parser_errposition(@3)));
}
t->typmods = $3;
! $$ = makeStringConstCast($2, @2, t);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
--- 1424,1433 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
! parser_errposition(@3.begins)));
}
t->typmods = $3;
! $$ = makeStringConstCast($2, @2.begins, @2.length, t);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
*************** zone_value:
*** 1440,1459 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
! parser_errposition(@6)));
if (list_length($6) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1)));
! t->typmods = lappend($6, makeIntConst($3, @3));
}
else
! t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
! makeIntConst($3, @3));
! $$ = makeStringConstCast($5, @5, t);
}
! | NumericOnly { $$ = makeAConst($1, @1); }
| DEFAULT { $$ = NULL; }
| LOCAL { $$ = NULL; }
;
--- 1439,1458 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("time zone interval must be HOUR or HOUR TO MINUTE"),
! parser_errposition(@6.begins)));
if (list_length($6) != 1)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1.begins)));
! t->typmods = lappend($6, makeIntConst($3, @3.begins, @3.length));
}
else
! t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1, -1),
! makeIntConst($3, @3.begins, @3.length));
! $$ = makeStringConstCast($5, @5.begins, @5.length, t);
}
! | NumericOnly { $$ = makeAConst($1, @1.begins, @1.length); }
| DEFAULT { $$ = NULL; }
| LOCAL { $$ = NULL; }
;
*************** alter_table_cmd:
*** 1965,1971 ****
{
AlterTableCmd *n = makeNode(AlterTableCmd);
TypeName *def = makeTypeNameFromNameList($2);
! def->location = @2;
n->subtype = AT_AddOf;
n->def = (Node *) def;
$$ = (Node *)n;
--- 1964,1970 ----
{
AlterTableCmd *n = makeNode(AlterTableCmd);
TypeName *def = makeTypeNameFromNameList($2);
! def->location = @2.begins;
n->subtype = AT_AddOf;
n->def = (Node *) def;
$$ = (Node *)n;
*************** opt_collate_clause:
*** 2035,2041 ****
CollateClause *n = makeNode(CollateClause);
n->arg = NULL;
n->collname = $2;
! n->location = @1;
$$ = (Node *) n;
}
| /* EMPTY */ { $$ = NULL; }
--- 2034,2040 ----
CollateClause *n = makeNode(CollateClause);
n->arg = NULL;
n->collname = $2;
! n->location = @1.begins;
$$ = (Node *) n;
}
| /* EMPTY */ { $$ = NULL; }
*************** AlterCompositeTypeStmt:
*** 2094,2100 ****
AlterTableStmt *n = makeNode(AlterTableStmt);
/* can't use qualified_name, sigh */
! n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
n->cmds = $4;
n->relkind = OBJECT_TYPE;
$$ = (Node *)n;
--- 2093,2099 ----
AlterTableStmt *n = makeNode(AlterTableStmt);
/* can't use qualified_name, sigh */
! n->relation = makeRangeVarFromAnyName($3, @3.begins, yyscanner);
n->cmds = $4;
n->relkind = OBJECT_TYPE;
$$ = (Node *)n;
*************** CreateStmt: CREATE OptTemp TABLE qualifi
*** 2428,2434 ****
n->relation = $4;
n->tableElts = $7;
n->ofTypename = makeTypeNameFromNameList($6);
! n->ofTypename->location = @6;
n->constraints = NIL;
n->options = $8;
n->oncommit = $9;
--- 2427,2433 ----
n->relation = $4;
n->tableElts = $7;
n->ofTypename = makeTypeNameFromNameList($6);
! n->ofTypename->location = @6.begins;
n->constraints = NIL;
n->options = $8;
n->oncommit = $9;
*************** CreateStmt: CREATE OptTemp TABLE qualifi
*** 2444,2450 ****
n->relation = $7;
n->tableElts = $10;
n->ofTypename = makeTypeNameFromNameList($9);
! n->ofTypename->location = @9;
n->constraints = NIL;
n->options = $11;
n->oncommit = $12;
--- 2443,2449 ----
n->relation = $7;
n->tableElts = $10;
n->ofTypename = makeTypeNameFromNameList($9);
! n->ofTypename->location = @9.begins;
n->constraints = NIL;
n->options = $11;
n->oncommit = $12;
*************** ColConstraint:
*** 2564,2570 ****
Constraint *n = (Constraint *) $3;
Assert(IsA(n, Constraint));
n->conname = $2;
! n->location = @1;
$$ = (Node *) n;
}
| ColConstraintElem { $$ = $1; }
--- 2563,2569 ----
Constraint *n = (Constraint *) $3;
Assert(IsA(n, Constraint));
n->conname = $2;
! n->location = @1.begins;
$$ = (Node *) n;
}
| ColConstraintElem { $$ = $1; }
*************** ColConstraint:
*** 2579,2585 ****
CollateClause *n = makeNode(CollateClause);
n->arg = NULL;
n->collname = $2;
! n->location = @1;
$$ = (Node *) n;
}
;
--- 2578,2584 ----
CollateClause *n = makeNode(CollateClause);
n->arg = NULL;
n->collname = $2;
! n->location = @1.begins;
$$ = (Node *) n;
}
;
*************** ColConstraintElem:
*** 2604,2624 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_NOTNULL;
! n->location = @1;
$$ = (Node *)n;
}
| NULL_P
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_NULL;
! n->location = @1;
$$ = (Node *)n;
}
| UNIQUE opt_definition OptConsTableSpace
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1;
n->keys = NULL;
n->options = $2;
n->indexname = NULL;
--- 2603,2623 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_NOTNULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| NULL_P
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| UNIQUE opt_definition OptConsTableSpace
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1.begins;
n->keys = NULL;
n->options = $2;
n->indexname = NULL;
*************** ColConstraintElem:
*** 2629,2635 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1;
n->keys = NULL;
n->options = $3;
n->indexname = NULL;
--- 2628,2634 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1.begins;
n->keys = NULL;
n->options = $3;
n->indexname = NULL;
*************** ColConstraintElem:
*** 2640,2646 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
! n->location = @1;
n->raw_expr = $3;
n->cooked_expr = NULL;
$$ = (Node *)n;
--- 2639,2645 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
! n->location = @1.begins;
n->raw_expr = $3;
n->cooked_expr = NULL;
$$ = (Node *)n;
*************** ColConstraintElem:
*** 2649,2655 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_DEFAULT;
! n->location = @1;
n->raw_expr = $2;
n->cooked_expr = NULL;
$$ = (Node *)n;
--- 2648,2654 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_DEFAULT;
! n->location = @1.begins;
n->raw_expr = $2;
n->cooked_expr = NULL;
$$ = (Node *)n;
*************** ColConstraintElem:
*** 2658,2664 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_FOREIGN;
! n->location = @1;
n->pktable = $2;
n->fk_attrs = NIL;
n->pk_attrs = $3;
--- 2657,2663 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_FOREIGN;
! n->location = @1.begins;
n->pktable = $2;
n->fk_attrs = NIL;
n->pk_attrs = $3;
*************** ConstraintAttr:
*** 2691,2718 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_DEFERRABLE;
! n->location = @1;
$$ = (Node *)n;
}
| NOT DEFERRABLE
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_NOT_DEFERRABLE;
! n->location = @1;
$$ = (Node *)n;
}
| INITIALLY DEFERRED
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_DEFERRED;
! n->location = @1;
$$ = (Node *)n;
}
| INITIALLY IMMEDIATE
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_IMMEDIATE;
! n->location = @1;
$$ = (Node *)n;
}
;
--- 2690,2717 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_DEFERRABLE;
! n->location = @1.begins;
$$ = (Node *)n;
}
| NOT DEFERRABLE
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_NOT_DEFERRABLE;
! n->location = @1.begins;
$$ = (Node *)n;
}
| INITIALLY DEFERRED
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_DEFERRED;
! n->location = @1.begins;
$$ = (Node *)n;
}
| INITIALLY IMMEDIATE
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_ATTR_IMMEDIATE;
! n->location = @1.begins;
$$ = (Node *)n;
}
;
*************** TableConstraint:
*** 2762,2768 ****
Constraint *n = (Constraint *) $3;
Assert(IsA(n, Constraint));
n->conname = $2;
! n->location = @1;
$$ = (Node *) n;
}
| ConstraintElem { $$ = $1; }
--- 2761,2767 ----
Constraint *n = (Constraint *) $3;
Assert(IsA(n, Constraint));
n->conname = $2;
! n->location = @1.begins;
$$ = (Node *) n;
}
| ConstraintElem { $$ = $1; }
*************** ConstraintElem:
*** 2773,2782 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
! n->location = @1;
n->raw_expr = $3;
n->cooked_expr = NULL;
! processCASbits($5, @5, "CHECK",
NULL, NULL, &n->skip_validation,
yyscanner);
n->initially_valid = !n->skip_validation;
--- 2772,2781 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
! n->location = @1.begins;
n->raw_expr = $3;
n->cooked_expr = NULL;
! processCASbits($5, @5.begins, "CHECK",
NULL, NULL, &n->skip_validation,
yyscanner);
n->initially_valid = !n->skip_validation;
*************** ConstraintElem:
*** 2787,2798 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1;
n->keys = $3;
n->options = $5;
n->indexname = NULL;
n->indexspace = $6;
! processCASbits($7, @7, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
--- 2786,2797 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1.begins;
n->keys = $3;
n->options = $5;
n->indexname = NULL;
n->indexspace = $6;
! processCASbits($7, @7.begins, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
*************** ConstraintElem:
*** 2801,2812 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1;
n->keys = NIL;
n->options = NIL;
n->indexname = $2;
n->indexspace = NULL;
! processCASbits($3, @3, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
--- 2800,2811 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
! n->location = @1.begins;
n->keys = NIL;
n->options = NIL;
n->indexname = $2;
n->indexspace = NULL;
! processCASbits($3, @3.begins, "UNIQUE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
*************** ConstraintElem:
*** 2816,2827 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1;
n->keys = $4;
n->options = $6;
n->indexname = NULL;
n->indexspace = $7;
! processCASbits($8, @8, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
--- 2815,2826 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1.begins;
n->keys = $4;
n->options = $6;
n->indexname = NULL;
n->indexspace = $7;
! processCASbits($8, @8.begins, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
*************** ConstraintElem:
*** 2830,2841 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1;
n->keys = NIL;
n->options = NIL;
n->indexname = $3;
n->indexspace = NULL;
! processCASbits($4, @4, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
--- 2829,2840 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
! n->location = @1.begins;
n->keys = NIL;
n->options = NIL;
n->indexname = $3;
n->indexspace = NULL;
! processCASbits($4, @4.begins, "PRIMARY KEY",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
*************** ConstraintElem:
*** 2846,2859 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_EXCLUSION;
! n->location = @1;
n->access_method = $2;
n->exclusions = $4;
n->options = $6;
n->indexname = NULL;
n->indexspace = $7;
n->where_clause = $8;
! processCASbits($9, @9, "EXCLUDE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
--- 2845,2858 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_EXCLUSION;
! n->location = @1.begins;
n->access_method = $2;
n->exclusions = $4;
n->options = $6;
n->indexname = NULL;
n->indexspace = $7;
n->where_clause = $8;
! processCASbits($9, @9.begins, "EXCLUDE",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
$$ = (Node *)n;
*************** ConstraintElem:
*** 2863,2876 ****
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_FOREIGN;
! n->location = @1;
n->pktable = $7;
n->fk_attrs = $4;
n->pk_attrs = $8;
n->fk_matchtype = $9;
n->fk_upd_action = (char) ($10 >> 8);
n->fk_del_action = (char) ($10 & 0xFF);
! processCASbits($11, @11, "FOREIGN KEY",
&n->deferrable, &n->initdeferred,
&n->skip_validation,
yyscanner);
--- 2862,2875 ----
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_FOREIGN;
! n->location = @1.begins;
n->pktable = $7;
n->fk_attrs = $4;
n->pk_attrs = $8;
n->fk_matchtype = $9;
n->fk_upd_action = (char) ($10 >> 8);
n->fk_del_action = (char) ($10 & 0xFF);
! processCASbits($11, @11.begins, "FOREIGN KEY",
&n->deferrable, &n->initdeferred,
&n->skip_validation,
yyscanner);
*************** key_match: MATCH FULL
*** 2904,2910 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"),
! parser_errposition(@1)));
$$ = FKCONSTR_MATCH_PARTIAL;
}
| MATCH SIMPLE
--- 2903,2909 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("MATCH PARTIAL not yet implemented"),
! parser_errposition(@1.begins)));
$$ = FKCONSTR_MATCH_PARTIAL;
}
| MATCH SIMPLE
*************** CreateTrigStmt:
*** 4029,4035 ****
n->columns = (List *) lsecond($6);
n->whenClause = $14;
n->isconstraint = TRUE;
! processCASbits($10, @10, "TRIGGER",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
n->constrrel = $9;
--- 4028,4034 ----
n->columns = (List *) lsecond($6);
n->whenClause = $14;
n->isconstraint = TRUE;
! processCASbits($10, @10.begins, "TRIGGER",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
n->constrrel = $9;
*************** ConstraintAttributeSpec:
*** 4150,4163 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
! parser_errposition(@2)));
/* generic message for other conflicts */
if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting constraint properties"),
! parser_errposition(@2)));
$$ = newspec;
}
;
--- 4149,4162 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("constraint declared INITIALLY DEFERRED must be DEFERRABLE"),
! parser_errposition(@2.begins)));
/* generic message for other conflicts */
if ((newspec & (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE)) == (CAS_NOT_DEFERRABLE | CAS_DEFERRABLE) ||
(newspec & (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED)) == (CAS_INITIALLY_IMMEDIATE | CAS_INITIALLY_DEFERRED))
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("conflicting constraint properties"),
! parser_errposition(@2.begins)));
$$ = newspec;
}
;
*************** CreateAssertStmt:
*** 4211,4217 ****
n->trigname = $3;
n->args = list_make1($6);
n->isconstraint = TRUE;
! processCASbits($8, @8, "ASSERTION",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
--- 4210,4216 ----
n->trigname = $3;
n->args = list_make1($6);
n->isconstraint = TRUE;
! processCASbits($8, @8.begins, "ASSERTION",
&n->deferrable, &n->initdeferred, NULL,
yyscanner);
*************** DefineStmt:
*** 4304,4310 ****
CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
/* can't use qualified_name, sigh */
! n->typevar = makeRangeVarFromAnyName($3, @3, yyscanner);
n->coldeflist = $6;
$$ = (Node *)n;
}
--- 4303,4309 ----
CompositeTypeStmt *n = makeNode(CompositeTypeStmt);
/* can't use qualified_name, sigh */
! n->typevar = makeRangeVarFromAnyName($3, @3.begins, yyscanner);
n->coldeflist = $6;
$$ = (Node *)n;
}
*************** opt_recheck: RECHECK
*** 4578,4584 ****
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RECHECK is no longer required"),
errhint("Update your data type."),
! parser_errposition(@1)));
$$ = TRUE;
}
| /*EMPTY*/ { $$ = FALSE; }
--- 4577,4583 ----
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RECHECK is no longer required"),
errhint("Update your data type."),
! parser_errposition(@1.begins)));
$$ = TRUE;
}
| /*EMPTY*/ { $$ = FALSE; }
*************** CreateFunctionStmt:
*** 5826,5832 ****
n->funcname = $4;
n->parameters = mergeTableFuncParameters($5, $9);
n->returnType = TableFuncTypeName($9);
! n->returnType->location = @7;
n->options = $11;
n->withClause = $12;
$$ = (Node *)n;
--- 5825,5831 ----
n->funcname = $4;
n->parameters = mergeTableFuncParameters($5, $9);
n->returnType = TableFuncTypeName($9);
! n->returnType->location = @7.begins;
n->options = $11;
n->withClause = $12;
$$ = (Node *)n;
*************** func_type: Typename { $$ = $1; }
*** 5967,5980 ****
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->pct_type = true;
! $$->location = @1;
}
| SETOF type_function_name attrs '%' TYPE_P
{
$$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
$$->pct_type = true;
$$->setof = TRUE;
! $$->location = @2;
}
;
--- 5966,5979 ----
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->pct_type = true;
! $$->location = @1.begins;
}
| SETOF type_function_name attrs '%' TYPE_P
{
$$ = makeTypeNameFromNameList(lcons(makeString($2), $3));
$$->pct_type = true;
$$->setof = TRUE;
! $$->location = @2.begins;
}
;
*************** oper_argtypes:
*** 6231,6237 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing argument"),
errhint("Use NONE to denote the missing argument of a unary operator."),
! parser_errposition(@3)));
}
| '(' Typename ',' Typename ')'
{ $$ = list_make2($2, $4); }
--- 6230,6236 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing argument"),
errhint("Use NONE to denote the missing argument of a unary operator."),
! parser_errposition(@3.begins)));
}
| '(' Typename ',' Typename ')'
{ $$ = list_make2($2, $4); }
*************** RenameStmt: ALTER AGGREGATE func_name ag
*** 6662,6668 ****
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_ATTRIBUTE;
n->relationType = OBJECT_TYPE;
! n->relation = makeRangeVarFromAnyName($3, @3, yyscanner);
n->subname = $6;
n->newname = $8;
n->behavior = $9;
--- 6661,6667 ----
RenameStmt *n = makeNode(RenameStmt);
n->renameType = OBJECT_ATTRIBUTE;
n->relationType = OBJECT_TYPE;
! n->relation = makeRangeVarFromAnyName($3, @3.begins, yyscanner);
n->subname = $6;
n->newname = $8;
n->behavior = $9;
*************** opt_transaction: WORK {}
*** 7257,7275 ****
transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = makeDefElem("transaction_isolation",
! makeStringConst($3, @3)); }
| READ ONLY
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(TRUE, @1)); }
| READ WRITE
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(FALSE, @1)); }
| DEFERRABLE
{ $$ = makeDefElem("transaction_deferrable",
! makeIntConst(TRUE, @1)); }
| NOT DEFERRABLE
{ $$ = makeDefElem("transaction_deferrable",
! makeIntConst(FALSE, @1)); }
;
/* Syntax with commas is SQL-spec, without commas is Postgres historical */
--- 7256,7274 ----
transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = makeDefElem("transaction_isolation",
! makeStringConst($3, @3.begins, @3.length)); }
| READ ONLY
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(TRUE, @1.begins, @1.length)); }
| READ WRITE
{ $$ = makeDefElem("transaction_read_only",
! makeIntConst(FALSE, @1.begins, @1.length)); }
| DEFERRABLE
{ $$ = makeDefElem("transaction_deferrable",
! makeIntConst(TRUE, @1.begins, @1.length)); }
| NOT DEFERRABLE
{ $$ = makeDefElem("transaction_deferrable",
! makeIntConst(FALSE, @1.begins, @1.length)); }
;
/* Syntax with commas is SQL-spec, without commas is Postgres historical */
*************** insert_column_item:
*** 8116,8122 ****
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL;
! $$->location = @1;
}
;
--- 8115,8121 ----
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL;
! $$->location = @1.begins;
}
;
*************** multiple_set_clause:
*** 8246,8252 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("number of columns does not match number of values"),
! parser_errposition(@1)));
forboth(col_cell, $2, val_cell, $5)
{
ResTarget *res_col = (ResTarget *) lfirst(col_cell);
--- 8245,8251 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("number of columns does not match number of values"),
! parser_errposition(@1.begins)));
forboth(col_cell, $2, val_cell, $5)
{
ResTarget *res_col = (ResTarget *) lfirst(col_cell);
*************** set_target:
*** 8266,8272 ****
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL; /* upper production sets this */
! $$->location = @1;
}
;
--- 8265,8271 ----
$$->name = $1;
$$->indirection = check_indirection($2, yyscanner);
$$->val = NULL; /* upper production sets this */
! $$->location = @1.begins;
}
;
*************** with_clause:
*** 8523,8536 ****
$$ = makeNode(WithClause);
$$->ctes = $2;
$$->recursive = false;
! $$->location = @1;
}
| WITH RECURSIVE cte_list
{
$$ = makeNode(WithClause);
$$->ctes = $3;
$$->recursive = true;
! $$->location = @1;
}
;
--- 8522,8535 ----
$$ = makeNode(WithClause);
$$->ctes = $2;
$$->recursive = false;
! $$->location = @1.begins;
}
| WITH RECURSIVE cte_list
{
$$ = makeNode(WithClause);
$$->ctes = $3;
$$->recursive = true;
! $$->location = @1.begins;
}
;
*************** common_table_expr: name opt_name_list A
*** 8545,8551 ****
n->ctename = $1;
n->aliascolnames = $2;
n->ctequery = $5;
! n->location = @1;
$$ = (Node *) n;
}
;
--- 8544,8550 ----
n->ctename = $1;
n->aliascolnames = $2;
n->ctequery = $5;
! n->location = @1.begins;
$$ = (Node *) n;
}
;
*************** sortby: a_expr USING qual_all_Op opt_nu
*** 8662,8668 ****
$$->sortby_dir = SORTBY_USING;
$$->sortby_nulls = $4;
$$->useOp = $3;
! $$->location = @3;
}
| a_expr opt_asc_desc opt_nulls_order
{
--- 8661,8667 ----
$$->sortby_dir = SORTBY_USING;
$$->sortby_nulls = $4;
$$->useOp = $3;
! $$->location = @3.begins;
}
| a_expr opt_asc_desc opt_nulls_order
{
*************** limit_clause:
*** 8698,8704 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("LIMIT #,# syntax is not supported"),
errhint("Use separate LIMIT and OFFSET clauses."),
! parser_errposition(@1)));
}
/* SQL:2008 syntax */
| FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY
--- 8697,8703 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("LIMIT #,# syntax is not supported"),
errhint("Use separate LIMIT and OFFSET clauses."),
! parser_errposition(@1.begins)));
}
/* SQL:2008 syntax */
| FETCH first_or_next opt_select_fetch_first_value row_or_rows ONLY
*************** select_limit_value:
*** 8718,8724 ****
| ALL
{
/* LIMIT ALL is represented as a NULL constant */
! $$ = makeNullAConst(@1);
}
;
--- 8717,8723 ----
| ALL
{
/* LIMIT ALL is represented as a NULL constant */
! $$ = makeNullAConst(@1.begins, @1.length);
}
;
*************** select_offset_value:
*** 8733,8741 ****
* default to 1.
*/
opt_select_fetch_first_value:
! SignedIconst { $$ = makeIntConst($1, @1); }
| '(' a_expr ')' { $$ = $2; }
! | /*EMPTY*/ { $$ = makeIntConst(1, -1); }
;
/*
--- 8732,8740 ----
* default to 1.
*/
opt_select_fetch_first_value:
! SignedIconst { $$ = makeIntConst($1, @1.begins, @1.length); }
| '(' a_expr ')' { $$ = $2; }
! | /*EMPTY*/ { $$ = makeIntConst(1, -1, -1); }
;
/*
*************** table_ref: relation_expr
*** 8917,8929 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("VALUES in FROM must have an alias"),
errhint("For example, FROM (VALUES ...) [AS] foo."),
! parser_errposition(@1)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("subquery in FROM must have an alias"),
errhint("For example, FROM (SELECT ...) [AS] foo."),
! parser_errposition(@1)));
$$ = NULL;
}
| select_with_parens alias_clause
--- 8916,8928 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("VALUES in FROM must have an alias"),
errhint("For example, FROM (VALUES ...) [AS] foo."),
! parser_errposition(@1.begins)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("subquery in FROM must have an alias"),
errhint("For example, FROM (SELECT ...) [AS] foo."),
! parser_errposition(@1.begins)));
$$ = NULL;
}
| select_with_parens alias_clause
*************** SimpleTypename:
*** 9283,9294 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1)));
! $$->typmods = lappend($5, makeIntConst($3, @3));
}
else
! $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
! makeIntConst($3, @3));
}
;
--- 9282,9293 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1.begins)));
! $$->typmods = lappend($5, makeIntConst($3, @3.begins, @3.length));
}
else
! $$->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1, -1),
! makeIntConst($3, @3.begins, @3.length));
}
;
*************** GenericType:
*** 9322,9334 ****
{
$$ = makeTypeName($1);
$$->typmods = $2;
! $$->location = @1;
}
| type_function_name attrs opt_type_modifiers
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->typmods = $3;
! $$->location = @1;
}
;
--- 9321,9333 ----
{
$$ = makeTypeName($1);
$$->typmods = $2;
! $$->location = @1.begins;
}
| type_function_name attrs opt_type_modifiers
{
$$ = makeTypeNameFromNameList(lcons(makeString($1), $2));
$$->typmods = $3;
! $$->location = @1.begins;
}
;
*************** opt_type_modifiers: '(' expr_list ')'
*** 9342,9401 ****
Numeric: INT_P
{
$$ = SystemTypeName("int4");
! $$->location = @1;
}
| INTEGER
{
$$ = SystemTypeName("int4");
! $$->location = @1;
}
| SMALLINT
{
$$ = SystemTypeName("int2");
! $$->location = @1;
}
| BIGINT
{
$$ = SystemTypeName("int8");
! $$->location = @1;
}
| REAL
{
$$ = SystemTypeName("float4");
! $$->location = @1;
}
| FLOAT_P opt_float
{
$$ = $2;
! $$->location = @1;
}
| DOUBLE_P PRECISION
{
$$ = SystemTypeName("float8");
! $$->location = @1;
}
| DECIMAL_P opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1;
}
| DEC opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1;
}
| NUMERIC opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1;
}
| BOOLEAN_P
{
$$ = SystemTypeName("bool");
! $$->location = @1;
}
;
--- 9341,9400 ----
Numeric: INT_P
{
$$ = SystemTypeName("int4");
! $$->location = @1.begins;
}
| INTEGER
{
$$ = SystemTypeName("int4");
! $$->location = @1.begins;
}
| SMALLINT
{
$$ = SystemTypeName("int2");
! $$->location = @1.begins;
}
| BIGINT
{
$$ = SystemTypeName("int8");
! $$->location = @1.begins;
}
| REAL
{
$$ = SystemTypeName("float4");
! $$->location = @1.begins;
}
| FLOAT_P opt_float
{
$$ = $2;
! $$->location = @1.begins;
}
| DOUBLE_P PRECISION
{
$$ = SystemTypeName("float8");
! $$->location = @1.begins;
}
| DECIMAL_P opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1.begins;
}
| DEC opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1.begins;
}
| NUMERIC opt_type_modifiers
{
$$ = SystemTypeName("numeric");
$$->typmods = $2;
! $$->location = @1.begins;
}
| BOOLEAN_P
{
$$ = SystemTypeName("bool");
! $$->location = @1.begins;
}
;
*************** opt_float: '(' Iconst ')'
*** 9409,9415 ****
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("precision for type float must be at least 1 bit"),
! parser_errposition(@2)));
else if ($2 <= 24)
$$ = SystemTypeName("float4");
else if ($2 <= 53)
--- 9408,9414 ----
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("precision for type float must be at least 1 bit"),
! parser_errposition(@2.begins)));
else if ($2 <= 24)
$$ = SystemTypeName("float4");
else if ($2 <= 53)
*************** opt_float: '(' Iconst ')'
*** 9418,9424 ****
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("precision for type float must be less than 54 bits"),
! parser_errposition(@2)));
}
| /*EMPTY*/
{
--- 9417,9423 ----
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("precision for type float must be less than 54 bits"),
! parser_errposition(@2.begins)));
}
| /*EMPTY*/
{
*************** BitWithLength:
*** 9461,9467 ****
typname = $2 ? "varbit" : "bit";
$$ = SystemTypeName(typname);
$$->typmods = $4;
! $$->location = @1;
}
;
--- 9460,9466 ----
typname = $2 ? "varbit" : "bit";
$$ = SystemTypeName(typname);
$$->typmods = $4;
! $$->location = @1.begins;
}
;
*************** BitWithoutLength:
*** 9476,9484 ****
else
{
$$ = SystemTypeName("bit");
! $$->typmods = list_make1(makeIntConst(1, -1));
}
! $$->location = @1;
}
;
--- 9475,9483 ----
else
{
$$ = SystemTypeName("bit");
! $$->typmods = list_make1(makeIntConst(1, -1, -1));
}
! $$->location = @1.begins;
}
;
*************** CharacterWithLength: character '(' Icon
*** 9528,9535 ****
}
$$ = SystemTypeName($1);
! $$->typmods = list_make1(makeIntConst($3, @3));
! $$->location = @1;
}
;
--- 9527,9534 ----
}
$$ = SystemTypeName($1);
! $$->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$->location = @1.begins;
}
;
*************** CharacterWithoutLength: character opt_c
*** 9550,9558 ****
/* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0)
! $$->typmods = list_make1(makeIntConst(1, -1));
! $$->location = @1;
}
;
--- 9549,9557 ----
/* char defaults to char(1), varchar to no limit */
if (strcmp($1, "bpchar") == 0)
! $$->typmods = list_make1(makeIntConst(1, -1, -1));
! $$->location = @1.begins;
}
;
*************** ConstDatetime:
*** 9590,9597 ****
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->typmods = list_make1(makeIntConst($3, @3));
! $$->location = @1;
}
| TIMESTAMP opt_timezone
{
--- 9589,9596 ----
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$->location = @1.begins;
}
| TIMESTAMP opt_timezone
{
*************** ConstDatetime:
*** 9599,9605 ****
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->location = @1;
}
| TIME '(' Iconst ')' opt_timezone
{
--- 9598,9604 ----
$$ = SystemTypeName("timestamptz");
else
$$ = SystemTypeName("timestamp");
! $$->location = @1.begins;
}
| TIME '(' Iconst ')' opt_timezone
{
*************** ConstDatetime:
*** 9607,9614 ****
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->typmods = list_make1(makeIntConst($3, @3));
! $$->location = @1;
}
| TIME opt_timezone
{
--- 9606,9613 ----
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$->location = @1.begins;
}
| TIME opt_timezone
{
*************** ConstDatetime:
*** 9616,9622 ****
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->location = @1;
}
;
--- 9615,9621 ----
$$ = SystemTypeName("timetz");
else
$$ = SystemTypeName("time");
! $$->location = @1.begins;
}
;
*************** ConstInterval:
*** 9624,9630 ****
INTERVAL
{
$$ = SystemTypeName("interval");
! $$->location = @1;
}
;
--- 9623,9629 ----
INTERVAL
{
$$ = SystemTypeName("interval");
! $$->location = @1.begins;
}
;
*************** opt_timezone:
*** 9636,9667 ****
opt_interval:
YEAR_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1)); }
| MONTH_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1)); }
| DAY_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1)); }
| HOUR_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1)); }
| MINUTE_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1)); }
| interval_second
{ $$ = $1; }
| YEAR_P TO MONTH_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR) |
! INTERVAL_MASK(MONTH), @1));
}
| DAY_P TO HOUR_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
! INTERVAL_MASK(HOUR), @1));
}
| DAY_P TO MINUTE_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
INTERVAL_MASK(HOUR) |
! INTERVAL_MASK(MINUTE), @1));
}
| DAY_P TO interval_second
{
--- 9635,9666 ----
opt_interval:
YEAR_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR), @1.begins, @1.length)); }
| MONTH_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(MONTH), @1.begins, @1.length)); }
| DAY_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(DAY), @1.begins, @1.length)); }
| HOUR_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR), @1.begins, @1.length)); }
| MINUTE_P
! { $$ = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), @1.begins, @1.length)); }
| interval_second
{ $$ = $1; }
| YEAR_P TO MONTH_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(YEAR) |
! INTERVAL_MASK(MONTH), @1.begins, @1.length));
}
| DAY_P TO HOUR_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
! INTERVAL_MASK(HOUR), @1.begins, @1.length));
}
| DAY_P TO MINUTE_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(DAY) |
INTERVAL_MASK(HOUR) |
! INTERVAL_MASK(MINUTE), @1.begins, @1.length));
}
| DAY_P TO interval_second
{
*************** opt_interval:
*** 9669,9693 ****
linitial($$) = makeIntConst(INTERVAL_MASK(DAY) |
INTERVAL_MASK(HOUR) |
INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1);
}
| HOUR_P TO MINUTE_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR) |
! INTERVAL_MASK(MINUTE), @1));
}
| HOUR_P TO interval_second
{
$$ = $3;
linitial($$) = makeIntConst(INTERVAL_MASK(HOUR) |
INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1);
}
| MINUTE_P TO interval_second
{
$$ = $3;
linitial($$) = makeIntConst(INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1);
}
| /*EMPTY*/
{ $$ = NIL; }
--- 9668,9692 ----
linitial($$) = makeIntConst(INTERVAL_MASK(DAY) |
INTERVAL_MASK(HOUR) |
INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1.begins, @1.length);
}
| HOUR_P TO MINUTE_P
{
$$ = list_make1(makeIntConst(INTERVAL_MASK(HOUR) |
! INTERVAL_MASK(MINUTE), @1.begins, @1.length));
}
| HOUR_P TO interval_second
{
$$ = $3;
linitial($$) = makeIntConst(INTERVAL_MASK(HOUR) |
INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1.begins, @1.length);
}
| MINUTE_P TO interval_second
{
$$ = $3;
linitial($$) = makeIntConst(INTERVAL_MASK(MINUTE) |
! INTERVAL_MASK(SECOND), @1.begins, @1.length);
}
| /*EMPTY*/
{ $$ = NIL; }
*************** opt_interval:
*** 9696,9707 ****
interval_second:
SECOND_P
{
! $$ = list_make1(makeIntConst(INTERVAL_MASK(SECOND), @1));
}
| SECOND_P '(' Iconst ')'
{
! $$ = list_make2(makeIntConst(INTERVAL_MASK(SECOND), @1),
! makeIntConst($3, @3));
}
;
--- 9695,9706 ----
interval_second:
SECOND_P
{
! $$ = list_make1(makeIntConst(INTERVAL_MASK(SECOND), @1.begins, @1.length));
}
| SECOND_P '(' Iconst ')'
{
! $$ = list_make2(makeIntConst(INTERVAL_MASK(SECOND), @1.begins, @1.length),
! makeIntConst($3, @3.begins, @3.length));
}
;
*************** interval_second:
*** 9730,9742 ****
*/
a_expr: c_expr { $$ = $1; }
| a_expr TYPECAST Typename
! { $$ = makeTypeCast($1, $3, @2); }
| a_expr COLLATE any_name
{
CollateClause *n = makeNode(CollateClause);
n->arg = $1;
n->collname = $3;
! n->location = @2;
$$ = (Node *) n;
}
| a_expr AT TIME ZONE a_expr %prec AT
--- 9729,9741 ----
*/
a_expr: c_expr { $$ = $1; }
| a_expr TYPECAST Typename
! { $$ = makeTypeCast($1, $3, @2.begins, @2.length); }
| a_expr COLLATE any_name
{
CollateClause *n = makeNode(CollateClause);
n->arg = $1;
n->collname = $3;
! n->location = @2.begins;
$$ = (Node *) n;
}
| a_expr AT TIME ZONE a_expr %prec AT
*************** a_expr: c_expr { $$ = $1; }
*** 9749,9755 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
$$ = (Node *) n;
}
/*
--- 9748,9754 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
$$ = (Node *) n;
}
/*
*************** a_expr: c_expr { $$ = $1; }
*** 9762,9805 ****
* also to b_expr and to the MathOp list above.
*/
| '+' a_expr %prec UMINUS
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
| '-' a_expr %prec UMINUS
! { $$ = doNegate($2, @1); }
| a_expr '+' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
| a_expr '-' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
| a_expr '*' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
| a_expr '/' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
| a_expr '%' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
| a_expr '^' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
| a_expr '<' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
| a_expr '>' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
| a_expr '=' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
| a_expr qual_Op a_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
| qual_Op a_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
| a_expr qual_Op %prec POSTFIXOP
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
| a_expr AND a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_AND, NIL, $1, $3, @2); }
| a_expr OR a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_OR, NIL, $1, $3, @2); }
| NOT a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, $2, @1); }
| a_expr LIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, $3, @2); }
| a_expr LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
--- 9761,9804 ----
* also to b_expr and to the MathOp list above.
*/
| '+' a_expr %prec UMINUS
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1.begins); }
| '-' a_expr %prec UMINUS
! { $$ = doNegate($2, @1.begins, @1.length); }
| a_expr '+' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2.begins); }
| a_expr '-' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2.begins); }
| a_expr '*' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2.begins); }
| a_expr '/' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2.begins); }
| a_expr '%' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2.begins); }
| a_expr '^' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2.begins); }
| a_expr '<' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2.begins); }
| a_expr '>' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2.begins); }
| a_expr '=' a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2.begins); }
| a_expr qual_Op a_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2.begins); }
| qual_Op a_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1.begins); }
| a_expr qual_Op %prec POSTFIXOP
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2.begins); }
| a_expr AND a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_AND, NIL, $1, $3, @2.begins); }
| a_expr OR a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_OR, NIL, $1, $3, @2.begins); }
| NOT a_expr
! { $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, $2, @1.begins); }
| a_expr LIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, $3, @2.begins); }
| a_expr LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
*************** a_expr: c_expr { $$ = $1; }
*** 9810,9820 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2);
}
| a_expr NOT LIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, $4, @2); }
| a_expr NOT LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
--- 9809,9819 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~", $1, (Node *) n, @2.begins);
}
| a_expr NOT LIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, $4, @2.begins); }
| a_expr NOT LIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
*************** a_expr: c_expr { $$ = $1; }
*** 9825,9835 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2);
}
| a_expr ILIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, $3, @2); }
| a_expr ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
--- 9824,9834 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~", $1, (Node *) n, @2.begins);
}
| a_expr ILIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, $3, @2.begins); }
| a_expr ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
*************** a_expr: c_expr { $$ = $1; }
*** 9840,9850 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2);
}
| a_expr NOT ILIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, $4, @2); }
| a_expr NOT ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
--- 9839,9849 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~~*", $1, (Node *) n, @2.begins);
}
| a_expr NOT ILIKE a_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, $4, @2.begins); }
| a_expr NOT ILIKE a_expr ESCAPE a_expr
{
FuncCall *n = makeNode(FuncCall);
*************** a_expr: c_expr { $$ = $1; }
*** 9855,9876 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2);
}
| a_expr SIMILAR TO a_expr %prec SIMILAR
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("similar_escape");
! n->args = list_make2($4, makeNullAConst(-1));
n->agg_order = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
}
| a_expr SIMILAR TO a_expr ESCAPE a_expr
{
--- 9854,9875 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~~*", $1, (Node *) n, @2.begins);
}
| a_expr SIMILAR TO a_expr %prec SIMILAR
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("similar_escape");
! n->args = list_make2($4, makeNullAConst(-1, -1));
n->agg_order = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2.begins);
}
| a_expr SIMILAR TO a_expr ESCAPE a_expr
{
*************** a_expr: c_expr { $$ = $1; }
*** 9882,9902 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2);
}
| a_expr NOT SIMILAR TO a_expr %prec SIMILAR
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("similar_escape");
! n->args = list_make2($5, makeNullAConst(-1));
n->agg_order = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
}
| a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
{
--- 9881,9901 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "~", $1, (Node *) n, @2.begins);
}
| a_expr NOT SIMILAR TO a_expr %prec SIMILAR
{
FuncCall *n = makeNode(FuncCall);
n->funcname = SystemFuncName("similar_escape");
! n->args = list_make2($5, makeNullAConst(-1, -1));
n->agg_order = NIL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2.begins);
}
| a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
{
*************** a_expr: c_expr { $$ = $1; }
*** 9908,9915 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2);
}
/* NullTest clause
--- 9907,9914 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @2.begins;
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "!~", $1, (Node *) n, @2.begins);
}
/* NullTest clause
*************** a_expr: c_expr { $$ = $1; }
*** 9951,9957 ****
}
| row OVERLAPS row
{
! $$ = (Node *)makeOverlaps($1, $3, @2, yyscanner);
}
| a_expr IS TRUE_P %prec IS
{
--- 9950,9956 ----
}
| row OVERLAPS row
{
! $$ = (Node *)makeOverlaps($1, $3, @2.begins, yyscanner);
}
| a_expr IS TRUE_P %prec IS
{
*************** a_expr: c_expr { $$ = $1; }
*** 9997,10019 ****
}
| a_expr IS DISTINCT FROM a_expr %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
}
| a_expr IS NOT DISTINCT FROM a_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
(Node *) makeSimpleA_Expr(AEXPR_DISTINCT,
! "=", $1, $6, @2),
! @2);
}
| a_expr IS OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
}
| a_expr IS NOT OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
}
/*
* Ideally we would not use hard-wired operators below but
--- 9996,10018 ----
}
| a_expr IS DISTINCT FROM a_expr %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2.begins);
}
| a_expr IS NOT DISTINCT FROM a_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
(Node *) makeSimpleA_Expr(AEXPR_DISTINCT,
! "=", $1, $6, @2.begins),
! @2.begins);
}
| a_expr IS OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2.begins);
}
| a_expr IS NOT OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2.begins);
}
/*
* Ideally we would not use hard-wired operators below but
*************** a_expr: c_expr { $$ = $1; }
*** 10024,10065 ****
| a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2),
! @2);
}
| a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2),
! @2);
}
| a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
(Node *) makeA_Expr(AEXPR_AND, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2),
! @2),
(Node *) makeA_Expr(AEXPR_AND, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $6, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $4, @2),
! @2),
! @2);
}
| a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
(Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2),
! @2),
(Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $7, @2),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $5, @2),
! @2),
! @2);
}
| a_expr IN_P in_expr
{
--- 10023,10065 ----
| a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2.begins),
! @2.begins);
}
| a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2.begins),
! @2.begins);
}
| a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_OR, NIL,
(Node *) makeA_Expr(AEXPR_AND, NIL,
!
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $4, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $6, @2.begins),
! @2.begins),
(Node *) makeA_Expr(AEXPR_AND, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">=", $1, $6, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<=", $1, $4, @2.begins),
! @2.begins),
! @2.begins);
}
| a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
{
$$ = (Node *) makeA_Expr(AEXPR_AND, NIL,
(Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $5, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $7, @2.begins),
! @2.begins),
(Node *) makeA_Expr(AEXPR_OR, NIL,
! (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $7, @2.begins),
! (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $5, @2.begins),
! @2.begins),
! @2.begins);
}
| a_expr IN_P in_expr
{
*************** a_expr: c_expr { $$ = $1; }
*** 10071,10083 ****
n->subLinkType = ANY_SUBLINK;
n->testexpr = $1;
n->operName = list_make1(makeString("="));
! n->location = @2;
$$ = (Node *)n;
}
else
{
/* generate scalar IN expression */
! $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3, @2);
}
}
| a_expr NOT IN_P in_expr
--- 10071,10083 ----
n->subLinkType = ANY_SUBLINK;
n->testexpr = $1;
n->operName = list_make1(makeString("="));
! n->location = @2.begins;
$$ = (Node *)n;
}
else
{
/* generate scalar IN expression */
! $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "=", $1, $3, @2.begins);
}
}
| a_expr NOT IN_P in_expr
*************** a_expr: c_expr { $$ = $1; }
*** 10091,10104 ****
n->subLinkType = ANY_SUBLINK;
n->testexpr = $1;
n->operName = list_make1(makeString("="));
! n->location = @3;
/* Stick a NOT on top */
! $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n, @2);
}
else
{
/* generate scalar NOT IN expression */
! $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4, @2);
}
}
| a_expr subquery_Op sub_type select_with_parens %prec Op
--- 10091,10104 ----
n->subLinkType = ANY_SUBLINK;
n->testexpr = $1;
n->operName = list_make1(makeString("="));
! n->location = @3.begins;
/* Stick a NOT on top */
! $$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL, (Node *) n, @2.begins);
}
else
{
/* generate scalar NOT IN expression */
! $$ = (Node *) makeSimpleA_Expr(AEXPR_IN, "<>", $1, $4, @2.begins);
}
}
| a_expr subquery_Op sub_type select_with_parens %prec Op
*************** a_expr: c_expr { $$ = $1; }
*** 10108,10122 ****
n->testexpr = $1;
n->operName = $2;
n->subselect = $4;
! n->location = @2;
$$ = (Node *)n;
}
| a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
{
if ($3 == ANY_SUBLINK)
! $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5, @2);
else
! $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5, @2);
}
| UNIQUE select_with_parens
{
--- 10108,10122 ----
n->testexpr = $1;
n->operName = $2;
n->subselect = $4;
! n->location = @2.begins;
$$ = (Node *)n;
}
| a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
{
if ($3 == ANY_SUBLINK)
! $$ = (Node *) makeA_Expr(AEXPR_OP_ANY, $2, $1, $5, @2.begins);
else
! $$ = (Node *) makeA_Expr(AEXPR_OP_ALL, $2, $1, $5, @2.begins);
}
| UNIQUE select_with_parens
{
*************** a_expr: c_expr { $$ = $1; }
*** 10132,10150 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("UNIQUE predicate is not yet implemented"),
! parser_errposition(@1)));
}
| a_expr IS DOCUMENT_P %prec IS
{
$$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2);
}
| a_expr IS NOT DOCUMENT_P %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2),
! @2);
}
;
--- 10132,10150 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("UNIQUE predicate is not yet implemented"),
! parser_errposition(@1.begins)));
}
| a_expr IS DOCUMENT_P %prec IS
{
$$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2.begins);
}
| a_expr IS NOT DOCUMENT_P %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2.begins),
! @2.begins);
}
;
*************** a_expr: c_expr { $$ = $1; }
*** 10160,10222 ****
b_expr: c_expr
{ $$ = $1; }
| b_expr TYPECAST Typename
! { $$ = makeTypeCast($1, $3, @2); }
| '+' b_expr %prec UMINUS
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1); }
| '-' b_expr %prec UMINUS
! { $$ = doNegate($2, @1); }
| b_expr '+' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2); }
| b_expr '-' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2); }
| b_expr '*' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2); }
| b_expr '/' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2); }
| b_expr '%' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2); }
| b_expr '^' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2); }
| b_expr '<' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2); }
| b_expr '>' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2); }
| b_expr '=' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2); }
| b_expr qual_Op b_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2); }
| qual_Op b_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1); }
| b_expr qual_Op %prec POSTFIXOP
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2); }
| b_expr IS DISTINCT FROM b_expr %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2);
}
| b_expr IS NOT DISTINCT FROM b_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,
! NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $6, @2), @2);
}
| b_expr IS OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2);
}
| b_expr IS NOT OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2);
}
| b_expr IS DOCUMENT_P %prec IS
{
$$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2);
}
| b_expr IS NOT DOCUMENT_P %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2),
! @2);
}
;
--- 10160,10222 ----
b_expr: c_expr
{ $$ = $1; }
| b_expr TYPECAST Typename
! { $$ = makeTypeCast($1, $3, @2.begins, @2.length); }
| '+' b_expr %prec UMINUS
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", NULL, $2, @1.begins); }
| '-' b_expr %prec UMINUS
! { $$ = doNegate($2, @1.begins, @1.length); }
| b_expr '+' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "+", $1, $3, @2.begins); }
| b_expr '-' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "-", $1, $3, @2.begins); }
| b_expr '*' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "*", $1, $3, @2.begins); }
| b_expr '/' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "/", $1, $3, @2.begins); }
| b_expr '%' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3, @2.begins); }
| b_expr '^' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "^", $1, $3, @2.begins); }
| b_expr '<' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "<", $1, $3, @2.begins); }
| b_expr '>' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, ">", $1, $3, @2.begins); }
| b_expr '=' b_expr
! { $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "=", $1, $3, @2.begins); }
| b_expr qual_Op b_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, $3, @2.begins); }
| qual_Op b_expr %prec Op
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $1, NULL, $2, @1.begins); }
| b_expr qual_Op %prec POSTFIXOP
! { $$ = (Node *) makeA_Expr(AEXPR_OP, $2, $1, NULL, @2.begins); }
| b_expr IS DISTINCT FROM b_expr %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $5, @2.begins);
}
| b_expr IS NOT DISTINCT FROM b_expr %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL,
! NULL, (Node *) makeSimpleA_Expr(AEXPR_DISTINCT, "=", $1, $6, @2.begins), @2.begins);
}
| b_expr IS OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "=", $1, (Node *) $5, @2.begins);
}
| b_expr IS NOT OF '(' type_list ')' %prec IS
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_OF, "<>", $1, (Node *) $6, @2.begins);
}
| b_expr IS DOCUMENT_P %prec IS
{
$$ = makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2.begins);
}
| b_expr IS NOT DOCUMENT_P %prec IS
{
$$ = (Node *) makeA_Expr(AEXPR_NOT, NIL, NULL,
makeXmlExpr(IS_DOCUMENT, NULL, NIL,
! list_make1($1), @2.begins),
! @2.begins);
}
;
*************** c_expr: columnref { $$ = $1; }
*** 10234,10240 ****
{
ParamRef *p = makeNode(ParamRef);
p->number = $1;
! p->location = @1;
if ($2)
{
A_Indirection *n = makeNode(A_Indirection);
--- 10234,10240 ----
{
ParamRef *p = makeNode(ParamRef);
p->number = $1;
! p->location = @1.begins;
if ($2)
{
A_Indirection *n = makeNode(A_Indirection);
*************** c_expr: columnref { $$ = $1; }
*** 10268,10274 ****
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $1;
! n->location = @1;
$$ = (Node *)n;
}
| EXISTS select_with_parens
--- 10268,10274 ----
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $1;
! n->location = @1.begins;
$$ = (Node *)n;
}
| EXISTS select_with_parens
*************** c_expr: columnref { $$ = $1; }
*** 10278,10284 ****
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $2;
! n->location = @1;
$$ = (Node *)n;
}
| ARRAY select_with_parens
--- 10278,10284 ----
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $2;
! n->location = @1.begins;
$$ = (Node *)n;
}
| ARRAY select_with_parens
*************** c_expr: columnref { $$ = $1; }
*** 10288,10294 ****
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $2;
! n->location = @1;
$$ = (Node *)n;
}
| ARRAY array_expr
--- 10288,10294 ----
n->testexpr = NULL;
n->operName = NIL;
n->subselect = $2;
! n->location = @1.begins;
$$ = (Node *)n;
}
| ARRAY array_expr
*************** c_expr: columnref { $$ = $1; }
*** 10296,10302 ****
A_ArrayExpr *n = (A_ArrayExpr *) $2;
Assert(IsA(n, A_ArrayExpr));
/* point outermost A_ArrayExpr to the ARRAY keyword */
! n->location = @1;
$$ = (Node *)n;
}
| row
--- 10296,10302 ----
A_ArrayExpr *n = (A_ArrayExpr *) $2;
Assert(IsA(n, A_ArrayExpr));
/* point outermost A_ArrayExpr to the ARRAY keyword */
! n->location = @1.begins;
$$ = (Node *)n;
}
| row
*************** c_expr: columnref { $$ = $1; }
*** 10304,10310 ****
RowExpr *r = makeNode(RowExpr);
r->args = $1;
r->row_typeid = InvalidOid; /* not analyzed yet */
! r->location = @1;
$$ = (Node *)r;
}
;
--- 10304,10310 ----
RowExpr *r = makeNode(RowExpr);
r->args = $1;
r->row_typeid = InvalidOid; /* not analyzed yet */
! r->location = @1.begins;
$$ = (Node *)r;
}
;
*************** func_expr: func_name '(' ')' over_clause
*** 10327,10333 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $4;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ')' over_clause
--- 10327,10333 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $4;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10340,10346 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' VARIADIC func_arg_expr ')' over_clause
--- 10340,10346 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' VARIADIC func_arg_expr ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10353,10359 ****
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $6;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ',' VARIADIC func_arg_expr ')' over_clause
--- 10353,10359 ----
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $6;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' func_arg_list ',' VARIADIC func_arg_expr ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10366,10372 ****
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $8;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' func_arg_list sort_clause ')' over_clause
--- 10366,10372 ----
n->agg_distinct = FALSE;
n->func_variadic = TRUE;
n->over = $8;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' func_arg_list sort_clause ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10379,10385 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $6;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' ALL func_arg_list opt_sort_clause ')' over_clause
--- 10379,10385 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $6;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' ALL func_arg_list opt_sort_clause ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10396,10402 ****
*/
n->func_variadic = FALSE;
n->over = $7;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' DISTINCT func_arg_list opt_sort_clause ')' over_clause
--- 10396,10402 ----
*/
n->func_variadic = FALSE;
n->over = $7;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' DISTINCT func_arg_list opt_sort_clause ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10409,10415 ****
n->agg_distinct = TRUE;
n->func_variadic = FALSE;
n->over = $7;
! n->location = @1;
$$ = (Node *)n;
}
| func_name '(' '*' ')' over_clause
--- 10409,10415 ----
n->agg_distinct = TRUE;
n->func_variadic = FALSE;
n->over = $7;
! n->location = @1.begins;
$$ = (Node *)n;
}
| func_name '(' '*' ')' over_clause
*************** func_expr: func_name '(' ')' over_clause
*** 10432,10438 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
! n->location = @1;
$$ = (Node *)n;
}
| CURRENT_DATE
--- 10432,10438 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = $5;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CURRENT_DATE
*************** func_expr: func_name '(' ')' over_clause
*** 10453,10460 ****
* to rely on it.)
*/
Node *n;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("date"), -1);
}
| CURRENT_TIME
{
--- 10453,10460 ----
* to rely on it.)
*/
Node *n;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("date"), -1, -1);
}
| CURRENT_TIME
{
*************** func_expr: func_name '(' ')' over_clause
*** 10463,10470 ****
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("timetz"), -1);
}
| CURRENT_TIME '(' Iconst ')'
{
--- 10463,10470 ----
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("timetz"), -1, -1);
}
| CURRENT_TIME '(' Iconst ')'
{
*************** func_expr: func_name '(' ')' over_clause
*** 10474,10483 ****
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
d = SystemTypeName("timetz");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = makeTypeCast(n, d, -1);
}
| CURRENT_TIMESTAMP
{
--- 10474,10483 ----
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
d = SystemTypeName("timetz");
! d->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$ = makeTypeCast(n, d, -1, -1);
}
| CURRENT_TIMESTAMP
{
*************** func_expr: func_name '(' ')' over_clause
*** 10493,10499 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| CURRENT_TIMESTAMP '(' Iconst ')'
--- 10493,10499 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CURRENT_TIMESTAMP '(' Iconst ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10504,10513 ****
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
d = SystemTypeName("timestamptz");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = makeTypeCast(n, d, -1);
}
| LOCALTIME
{
--- 10504,10513 ----
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
d = SystemTypeName("timestamptz");
! d->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$ = makeTypeCast(n, d, -1, -1);
}
| LOCALTIME
{
*************** func_expr: func_name '(' ')' over_clause
*** 10516,10523 ****
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
! $$ = makeTypeCast((Node *)n, SystemTypeName("time"), -1);
}
| LOCALTIME '(' Iconst ')'
{
--- 10516,10523 ----
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
! $$ = makeTypeCast((Node *)n, SystemTypeName("time"), -1, -1);
}
| LOCALTIME '(' Iconst ')'
{
*************** func_expr: func_name '(' ')' over_clause
*** 10527,10536 ****
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
d = SystemTypeName("time");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = makeTypeCast((Node *)n, d, -1);
}
| LOCALTIMESTAMP
{
--- 10527,10536 ----
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
d = SystemTypeName("time");
! d->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$ = makeTypeCast((Node *)n, d, -1, -1);
}
| LOCALTIMESTAMP
{
*************** func_expr: func_name '(' ')' over_clause
*** 10539,10546 ****
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("timestamp"), -1);
}
| LOCALTIMESTAMP '(' Iconst ')'
{
--- 10539,10546 ----
* See comments for CURRENT_DATE.
*/
Node *n;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
! $$ = makeTypeCast(n, SystemTypeName("timestamp"), -1, -1);
}
| LOCALTIMESTAMP '(' Iconst ')'
{
*************** func_expr: func_name '(' ')' over_clause
*** 10550,10559 ****
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1, SystemTypeName("text"));
d = SystemTypeName("timestamp");
! d->typmods = list_make1(makeIntConst($3, @3));
! $$ = makeTypeCast(n, d, -1);
}
| CURRENT_ROLE
{
--- 10550,10559 ----
*/
Node *n;
TypeName *d;
! n = makeStringConstCast("now", @1.begins, @1.length, SystemTypeName("text"));
d = SystemTypeName("timestamp");
! d->typmods = list_make1(makeIntConst($3, @3.begins, @3.length));
! $$ = makeTypeCast(n, d, -1, -1);
}
| CURRENT_ROLE
{
*************** func_expr: func_name '(' ')' over_clause
*** 10565,10571 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| CURRENT_USER
--- 10565,10571 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CURRENT_USER
*************** func_expr: func_name '(' ')' over_clause
*** 10578,10584 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| SESSION_USER
--- 10578,10584 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| SESSION_USER
*************** func_expr: func_name '(' ')' over_clause
*** 10591,10597 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| USER
--- 10591,10597 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| USER
*************** func_expr: func_name '(' ')' over_clause
*** 10604,10610 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| CURRENT_CATALOG
--- 10604,10610 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CURRENT_CATALOG
*************** func_expr: func_name '(' ')' over_clause
*** 10617,10623 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| CURRENT_SCHEMA
--- 10617,10623 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CURRENT_SCHEMA
*************** func_expr: func_name '(' ')' over_clause
*** 10630,10640 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| CAST '(' a_expr AS Typename ')'
! { $$ = makeTypeCast($3, $5, @1); }
| EXTRACT '(' extract_list ')'
{
FuncCall *n = makeNode(FuncCall);
--- 10630,10640 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| CAST '(' a_expr AS Typename ')'
! { $$ = makeTypeCast($3, $5, @1.begins, @1.length); }
| EXTRACT '(' extract_list ')'
{
FuncCall *n = makeNode(FuncCall);
*************** func_expr: func_name '(' ')' over_clause
*** 10645,10651 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| OVERLAY '(' overlay_list ')'
--- 10645,10651 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| OVERLAY '(' overlay_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10663,10669 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| POSITION '(' position_list ')'
--- 10663,10669 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| POSITION '(' position_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10677,10683 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| SUBSTRING '(' substr_list ')'
--- 10677,10683 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| SUBSTRING '(' substr_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10693,10699 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| TREAT '(' a_expr AS Typename ')'
--- 10693,10699 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| TREAT '(' a_expr AS Typename ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10715,10721 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' BOTH trim_list ')'
--- 10715,10721 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| TRIM '(' BOTH trim_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10731,10737 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' LEADING trim_list ')'
--- 10731,10737 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| TRIM '(' LEADING trim_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10744,10750 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' TRAILING trim_list ')'
--- 10744,10750 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| TRIM '(' TRAILING trim_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10757,10763 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| TRIM '(' trim_list ')'
--- 10757,10763 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| TRIM '(' trim_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10770,10787 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| NULLIF '(' a_expr ',' a_expr ')'
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5, @1);
}
| COALESCE '(' expr_list ')'
{
CoalesceExpr *c = makeNode(CoalesceExpr);
c->args = $3;
! c->location = @1;
$$ = (Node *)c;
}
| GREATEST '(' expr_list ')'
--- 10770,10787 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| NULLIF '(' a_expr ',' a_expr ')'
{
! $$ = (Node *) makeSimpleA_Expr(AEXPR_NULLIF, "=", $3, $5, @1.begins);
}
| COALESCE '(' expr_list ')'
{
CoalesceExpr *c = makeNode(CoalesceExpr);
c->args = $3;
! c->location = @1.begins;
$$ = (Node *)c;
}
| GREATEST '(' expr_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10789,10795 ****
MinMaxExpr *v = makeNode(MinMaxExpr);
v->args = $3;
v->op = IS_GREATEST;
! v->location = @1;
$$ = (Node *)v;
}
| LEAST '(' expr_list ')'
--- 10789,10795 ----
MinMaxExpr *v = makeNode(MinMaxExpr);
v->args = $3;
v->op = IS_GREATEST;
! v->location = @1.begins;
$$ = (Node *)v;
}
| LEAST '(' expr_list ')'
*************** func_expr: func_name '(' ')' over_clause
*** 10797,10824 ****
MinMaxExpr *v = makeNode(MinMaxExpr);
v->args = $3;
v->op = IS_LEAST;
! v->location = @1;
$$ = (Node *)v;
}
| XMLCONCAT '(' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3, @1);
}
| XMLELEMENT '(' NAME_P ColLabel ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL, @1);
}
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL, @1);
}
| XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6, @1);
}
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8, @1);
}
| XMLEXISTS '(' c_expr xmlexists_argument ')'
{
--- 10797,10824 ----
MinMaxExpr *v = makeNode(MinMaxExpr);
v->args = $3;
v->op = IS_LEAST;
! v->location = @1.begins;
$$ = (Node *)v;
}
| XMLCONCAT '(' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLCONCAT, NULL, NIL, $3, @1.begins);
}
| XMLELEMENT '(' NAME_P ColLabel ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, NIL, @1.begins);
}
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, NIL, @1.begins);
}
| XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, NIL, $6, @1.begins);
}
| XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
{
! $$ = makeXmlExpr(IS_XMLELEMENT, $4, $6, $8, @1.begins);
}
| XMLEXISTS '(' c_expr xmlexists_argument ')'
{
*************** func_expr: func_name '(' ')' over_clause
*** 10832,10865 ****
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1;
$$ = (Node *)n;
}
| XMLFOREST '(' xml_attribute_list ')'
{
! $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1);
}
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
{
XmlExpr *x = (XmlExpr *)
makeXmlExpr(IS_XMLPARSE, NULL, NIL,
! list_make2($4, makeBoolAConst($5, -1)),
! @1);
x->xmloption = $3;
$$ = (Node *)x;
}
| XMLPI '(' NAME_P ColLabel ')'
{
! $$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL, @1);
}
| XMLPI '(' NAME_P ColLabel ',' a_expr ')'
{
! $$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6), @1);
}
| XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
{
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
! list_make3($3, $5, $6), @1);
}
| XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename ')'
{
--- 10832,10865 ----
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
! n->location = @1.begins;
$$ = (Node *)n;
}
| XMLFOREST '(' xml_attribute_list ')'
{
! $$ = makeXmlExpr(IS_XMLFOREST, NULL, $3, NIL, @1.begins);
}
| XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
{
XmlExpr *x = (XmlExpr *)
makeXmlExpr(IS_XMLPARSE, NULL, NIL,
! list_make2($4, makeBoolAConst($5, -1, -1)),
! @1.begins);
x->xmloption = $3;
$$ = (Node *)x;
}
| XMLPI '(' NAME_P ColLabel ')'
{
! $$ = makeXmlExpr(IS_XMLPI, $4, NULL, NIL, @1.begins);
}
| XMLPI '(' NAME_P ColLabel ',' a_expr ')'
{
! $$ = makeXmlExpr(IS_XMLPI, $4, NULL, list_make1($6), @1.begins);
}
| XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone ')'
{
$$ = makeXmlExpr(IS_XMLROOT, NULL, NIL,
! list_make3($3, $5, $6), @1.begins);
}
| XMLSERIALIZE '(' document_or_content a_expr AS SimpleTypename ')'
{
*************** func_expr: func_name '(' ')' over_clause
*** 10867,10873 ****
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
! n->location = @1;
$$ = (Node *)n;
}
;
--- 10867,10873 ----
n->xmloption = $3;
n->expr = $4;
n->typeName = $6;
! n->location = @1.begins;
$$ = (Node *)n;
}
;
*************** func_expr: func_name '(' ')' over_clause
*** 10878,10894 ****
xml_root_version: VERSION_P a_expr
{ $$ = $2; }
| VERSION_P NO VALUE_P
! { $$ = makeNullAConst(-1); }
;
opt_xml_root_standalone: ',' STANDALONE_P YES_P
! { $$ = makeIntConst(XML_STANDALONE_YES, -1); }
| ',' STANDALONE_P NO
! { $$ = makeIntConst(XML_STANDALONE_NO, -1); }
| ',' STANDALONE_P NO VALUE_P
! { $$ = makeIntConst(XML_STANDALONE_NO_VALUE, -1); }
| /*EMPTY*/
! { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1); }
;
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
--- 10878,10894 ----
xml_root_version: VERSION_P a_expr
{ $$ = $2; }
| VERSION_P NO VALUE_P
! { $$ = makeNullAConst(-1, -1); }
;
opt_xml_root_standalone: ',' STANDALONE_P YES_P
! { $$ = makeIntConst(XML_STANDALONE_YES, -1, -1); }
| ',' STANDALONE_P NO
! { $$ = makeIntConst(XML_STANDALONE_NO, -1, -1); }
| ',' STANDALONE_P NO VALUE_P
! { $$ = makeIntConst(XML_STANDALONE_NO_VALUE, -1, -1); }
| /*EMPTY*/
! { $$ = makeIntConst(XML_STANDALONE_OMITTED, -1, -1); }
;
xml_attributes: XMLATTRIBUTES '(' xml_attribute_list ')' { $$ = $3; }
*************** xml_attribute_el: a_expr AS ColLabel
*** 10904,10910 ****
$$->name = $3;
$$->indirection = NIL;
$$->val = (Node *) $1;
! $$->location = @1;
}
| a_expr
{
--- 10904,10910 ----
$$->name = $3;
$$->indirection = NIL;
$$->val = (Node *) $1;
! $$->location = @1.begins;
}
| a_expr
{
*************** xml_attribute_el: a_expr AS ColLabel
*** 10912,10918 ****
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *) $1;
! $$->location = @1;
}
;
--- 10912,10918 ----
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *) $1;
! $$->location = @1.begins;
}
;
*************** over_clause: OVER window_specification
*** 10981,10987 ****
n->frameOptions = FRAMEOPTION_DEFAULTS;
n->startOffset = NULL;
n->endOffset = NULL;
! n->location = @2;
$$ = n;
}
| /*EMPTY*/
--- 10981,10987 ----
n->frameOptions = FRAMEOPTION_DEFAULTS;
n->startOffset = NULL;
n->endOffset = NULL;
! n->location = @2.begins;
$$ = n;
}
| /*EMPTY*/
*************** window_specification: '(' opt_existing_w
*** 11000,11006 ****
n->frameOptions = $5->frameOptions;
n->startOffset = $5->startOffset;
n->endOffset = $5->endOffset;
! n->location = @1;
$$ = n;
}
;
--- 11000,11006 ----
n->frameOptions = $5->frameOptions;
n->startOffset = $5->startOffset;
n->endOffset = $5->endOffset;
! n->location = @1.begins;
$$ = n;
}
;
*************** opt_frame_clause:
*** 11040,11052 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RANGE PRECEDING is only supported with UNBOUNDED"),
! parser_errposition(@1)));
if (n->frameOptions & (FRAMEOPTION_START_VALUE_FOLLOWING |
FRAMEOPTION_END_VALUE_FOLLOWING))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RANGE FOLLOWING is only supported with UNBOUNDED"),
! parser_errposition(@1)));
$$ = n;
}
| ROWS frame_extent
--- 11040,11052 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RANGE PRECEDING is only supported with UNBOUNDED"),
! parser_errposition(@1.begins)));
if (n->frameOptions & (FRAMEOPTION_START_VALUE_FOLLOWING |
FRAMEOPTION_END_VALUE_FOLLOWING))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("RANGE FOLLOWING is only supported with UNBOUNDED"),
! parser_errposition(@1.begins)));
$$ = n;
}
| ROWS frame_extent
*************** frame_extent: frame_bound
*** 11073,11084 ****
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
! parser_errposition(@1)));
if (n->frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING)
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from following row cannot end with current row"),
! parser_errposition(@1)));
n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW;
$$ = n;
}
--- 11073,11084 ----
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
! parser_errposition(@1.begins)));
if (n->frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING)
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from following row cannot end with current row"),
! parser_errposition(@1.begins)));
n->frameOptions |= FRAMEOPTION_END_CURRENT_ROW;
$$ = n;
}
*************** frame_extent: frame_bound
*** 11096,11120 ****
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
! parser_errposition(@2)));
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame end cannot be UNBOUNDED PRECEDING"),
! parser_errposition(@4)));
if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) &&
(frameOptions & FRAMEOPTION_END_VALUE_PRECEDING))
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from current row cannot have preceding rows"),
! parser_errposition(@4)));
if ((frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING) &&
(frameOptions & (FRAMEOPTION_END_VALUE_PRECEDING |
FRAMEOPTION_END_CURRENT_ROW)))
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from following row cannot have preceding rows"),
! parser_errposition(@4)));
n1->frameOptions = frameOptions;
n1->endOffset = n2->startOffset;
$$ = n1;
--- 11096,11120 ----
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame start cannot be UNBOUNDED FOLLOWING"),
! parser_errposition(@2.begins)));
if (frameOptions & FRAMEOPTION_END_UNBOUNDED_PRECEDING)
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame end cannot be UNBOUNDED PRECEDING"),
! parser_errposition(@4.begins)));
if ((frameOptions & FRAMEOPTION_START_CURRENT_ROW) &&
(frameOptions & FRAMEOPTION_END_VALUE_PRECEDING))
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from current row cannot have preceding rows"),
! parser_errposition(@4.begins)));
if ((frameOptions & FRAMEOPTION_START_VALUE_FOLLOWING) &&
(frameOptions & (FRAMEOPTION_END_VALUE_PRECEDING |
FRAMEOPTION_END_CURRENT_ROW)))
ereport(ERROR,
(errcode(ERRCODE_WINDOWING_ERROR),
errmsg("frame starting from following row cannot have preceding rows"),
! parser_errposition(@4.begins)));
n1->frameOptions = frameOptions;
n1->endOffset = n2->startOffset;
$$ = n1;
*************** func_arg_expr: a_expr
*** 11272,11278 ****
na->name = $1;
na->arg = (Expr *) $3;
na->argnumber = -1; /* until determined */
! na->location = @1;
$$ = (Node *) na;
}
;
--- 11272,11278 ----
na->name = $1;
na->arg = (Expr *) $3;
na->argnumber = -1; /* until determined */
! na->location = @1.begins;
$$ = (Node *) na;
}
;
*************** type_list: Typename { $$ = list_m
*** 11283,11297 ****
array_expr: '[' expr_list ']'
{
! $$ = makeAArrayExpr($2, @1);
}
| '[' array_expr_list ']'
{
! $$ = makeAArrayExpr($2, @1);
}
| '[' ']'
{
! $$ = makeAArrayExpr(NIL, @1);
}
;
--- 11283,11297 ----
array_expr: '[' expr_list ']'
{
! $$ = makeAArrayExpr($2, @1.begins);
}
| '[' array_expr_list ']'
{
! $$ = makeAArrayExpr($2, @1.begins);
}
| '[' ']'
{
! $$ = makeAArrayExpr(NIL, @1.begins);
}
;
*************** array_expr_list: array_expr { $$ =
*** 11303,11309 ****
extract_list:
extract_arg FROM a_expr
{
! $$ = list_make2(makeStringConst($1, @1), $3);
}
| /*EMPTY*/ { $$ = NIL; }
;
--- 11303,11309 ----
extract_list:
extract_arg FROM a_expr
{
! $$ = list_make2(makeStringConst($1, @1.begins, @1.length), $3);
}
| /*EMPTY*/ { $$ = NIL; }
;
*************** substr_list:
*** 11388,11396 ****
* which it is likely to do if the second argument
* is unknown or doesn't have an implicit cast to int4.
*/
! $$ = list_make3($1, makeIntConst(1, -1),
makeTypeCast($2,
! SystemTypeName("int4"), -1));
}
| expr_list
{
--- 11388,11396 ----
* which it is likely to do if the second argument
* is unknown or doesn't have an implicit cast to int4.
*/
! $$ = list_make3($1, makeIntConst(1, -1, -1),
makeTypeCast($2,
! SystemTypeName("int4"), -1, -1));
}
| expr_list
{
*************** case_expr: CASE case_arg when_clause_lis
*** 11436,11442 ****
c->arg = (Expr *) $2;
c->args = $3;
c->defresult = (Expr *) $4;
! c->location = @1;
$$ = (Node *)c;
}
;
--- 11436,11442 ----
c->arg = (Expr *) $2;
c->args = $3;
c->defresult = (Expr *) $4;
! c->location = @1.begins;
$$ = (Node *)c;
}
;
*************** when_clause:
*** 11453,11459 ****
CaseWhen *w = makeNode(CaseWhen);
w->expr = (Expr *) $2;
w->result = (Expr *) $4;
! w->location = @1;
$$ = (Node *)w;
}
;
--- 11453,11459 ----
CaseWhen *w = makeNode(CaseWhen);
w->expr = (Expr *) $2;
w->result = (Expr *) $4;
! w->location = @1.begins;
$$ = (Node *)w;
}
;
*************** case_arg: a_expr { $$ = $1; }
*** 11469,11479 ****
columnref: ColId
{
! $$ = makeColumnRef($1, NIL, @1, yyscanner);
}
| ColId indirection
{
! $$ = makeColumnRef($1, $2, @1, yyscanner);
}
;
--- 11469,11479 ----
columnref: ColId
{
! $$ = makeColumnRef($1, NIL, @1.begins, yyscanner);
}
| ColId indirection
{
! $$ = makeColumnRef($1, $2, @1.begins, yyscanner);
}
;
*************** ctext_expr:
*** 11528,11534 ****
| DEFAULT
{
SetToDefault *n = makeNode(SetToDefault);
! n->location = @1;
$$ = (Node *) n;
}
;
--- 11528,11534 ----
| DEFAULT
{
SetToDefault *n = makeNode(SetToDefault);
! n->location = @1.begins;
$$ = (Node *) n;
}
;
*************** target_el: a_expr AS ColLabel
*** 11564,11570 ****
$$->name = $3;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1;
}
/*
* We support omitting AS only for column labels that aren't
--- 11564,11570 ----
$$->name = $3;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1.begins;
}
/*
* We support omitting AS only for column labels that aren't
*************** target_el: a_expr AS ColLabel
*** 11580,11586 ****
$$->name = $2;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1;
}
| a_expr
{
--- 11580,11586 ----
$$->name = $2;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1.begins;
}
| a_expr
{
*************** target_el: a_expr AS ColLabel
*** 11588,11606 ****
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1;
}
| '*'
{
ColumnRef *n = makeNode(ColumnRef);
n->fields = list_make1(makeNode(A_Star));
! n->location = @1;
$$ = makeNode(ResTarget);
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)n;
! $$->location = @1;
}
;
--- 11588,11606 ----
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)$1;
! $$->location = @1.begins;
}
| '*'
{
ColumnRef *n = makeNode(ColumnRef);
n->fields = list_make1(makeNode(A_Star));
! n->location = @1.begins;
$$ = makeNode(ResTarget);
$$->name = NULL;
$$->indirection = NIL;
$$->val = (Node *)n;
! $$->location = @1.begins;
}
;
*************** qualified_name_list:
*** 11626,11637 ****
qualified_name:
ColId
{
! $$ = makeRangeVar(NULL, $1, @1);
}
| ColId indirection
{
check_qualified_name($2, yyscanner);
! $$ = makeRangeVar(NULL, NULL, @1);
switch (list_length($2))
{
case 1:
--- 11626,11637 ----
qualified_name:
ColId
{
! $$ = makeRangeVar(NULL, $1, @1.begins);
}
| ColId indirection
{
check_qualified_name($2, yyscanner);
! $$ = makeRangeVar(NULL, NULL, @1.begins);
switch (list_length($2))
{
case 1:
*************** qualified_name:
*** 11649,11655 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
NameListToString(lcons(makeString($1), $2))),
! parser_errposition(@1)));
break;
}
}
--- 11649,11655 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("improper qualified name (too many dotted names): %s",
NameListToString(lcons(makeString($1), $2))),
! parser_errposition(@1.begins)));
break;
}
}
*************** func_name: type_function_name
*** 11699,11717 ****
*/
AexprConst: Iconst
{
! $$ = makeIntConst($1, @1);
}
| FCONST
{
! $$ = makeFloatConst($1, @1);
}
| Sconst
{
! $$ = makeStringConst($1, @1);
}
| BCONST
{
! $$ = makeBitStringConst($1, @1);
}
| XCONST
{
--- 11699,11717 ----
*/
AexprConst: Iconst
{
! $$ = makeIntConst($1, @1.begins, @1.length);
}
| FCONST
{
! $$ = makeFloatConst($1, @1.begins, @1.length);
}
| Sconst
{
! $$ = makeStringConst($1, @1.begins, @1.length);
}
| BCONST
{
! $$ = makeBitStringConst($1, @1.begins, @1.length);
}
| XCONST
{
*************** AexprConst: Iconst
*** 11720,11733 ****
* a <general literal> shall not be a
* <bit string literal> or a <hex string literal>.
*/
! $$ = makeBitStringConst($1, @1);
}
| func_name Sconst
{
/* generic type 'literal' syntax */
TypeName *t = makeTypeNameFromNameList($1);
! t->location = @1;
! $$ = makeStringConstCast($2, @2, t);
}
| func_name '(' func_arg_list ')' Sconst
{
--- 11720,11733 ----
* a <general literal> shall not be a
* <bit string literal> or a <hex string literal>.
*/
! $$ = makeBitStringConst($1, @1.begins, @1.length);
}
| func_name Sconst
{
/* generic type 'literal' syntax */
TypeName *t = makeTypeNameFromNameList($1);
! t->location = @1.begins;
! $$ = makeStringConstCast($2, @2.begins, @2.length, t);
}
| func_name '(' func_arg_list ')' Sconst
{
*************** AexprConst: Iconst
*** 11751,11768 ****
parser_errposition(arg->location)));
}
t->typmods = $3;
! t->location = @1;
! $$ = makeStringConstCast($5, @5, t);
}
| ConstTypename Sconst
{
! $$ = makeStringConstCast($2, @2, $1);
}
| ConstInterval Sconst opt_interval
{
TypeName *t = $1;
t->typmods = $3;
! $$ = makeStringConstCast($2, @2, t);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
--- 11751,11768 ----
parser_errposition(arg->location)));
}
t->typmods = $3;
! t->location = @1.begins;
! $$ = makeStringConstCast($5, @5.begins, @5.length, t);
}
| ConstTypename Sconst
{
! $$ = makeStringConstCast($2, @2.begins, @2.length, $1);
}
| ConstInterval Sconst opt_interval
{
TypeName *t = $1;
t->typmods = $3;
! $$ = makeStringConstCast($2, @2.begins, @2.length, t);
}
| ConstInterval '(' Iconst ')' Sconst opt_interval
{
*************** AexprConst: Iconst
*** 11773,11797 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1)));
! t->typmods = lappend($6, makeIntConst($3, @3));
}
else
! t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1),
! makeIntConst($3, @3));
! $$ = makeStringConstCast($5, @5, t);
}
| TRUE_P
{
! $$ = makeBoolAConst(TRUE, @1);
}
| FALSE_P
{
! $$ = makeBoolAConst(FALSE, @1);
}
| NULL_P
{
! $$ = makeNullAConst(@1);
}
;
--- 11773,11797 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("interval precision specified twice"),
! parser_errposition(@1.begins)));
! t->typmods = lappend($6, makeIntConst($3, @3.begins, @3.length));
}
else
! t->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1, -1),
! makeIntConst($3, @3.begins, @3.length));
! $$ = makeStringConstCast($5, @5.begins, @5.length, t);
}
| TRUE_P
{
! $$ = makeBoolAConst(TRUE, @1.begins, @1.length);
}
| FALSE_P
{
! $$ = makeBoolAConst(FALSE, @1.begins, @1.length);
}
| NULL_P
{
! $$ = makeNullAConst(@1.begins, @1.length);
}
;
*************** makeColumnRef(char *colname, List *indir
*** 12352,12451 ****
}
static Node *
! makeTypeCast(Node *arg, TypeName *typename, int location)
{
TypeCast *n = makeNode(TypeCast);
n->arg = arg;
n->typeName = typename;
n->location = location;
return (Node *) n;
}
static Node *
! makeStringConst(char *str, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = str;
n->location = location;
return (Node *)n;
}
static Node *
! makeStringConstCast(char *str, int location, TypeName *typename)
{
! Node *s = makeStringConst(str, location);
! return makeTypeCast(s, typename, -1);
}
static Node *
! makeIntConst(int val, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = val;
n->location = location;
return (Node *)n;
}
static Node *
! makeFloatConst(char *str, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
n->val.val.str = str;
n->location = location;
return (Node *)n;
}
static Node *
! makeBitStringConst(char *str, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_BitString;
n->val.val.str = str;
n->location = location;
return (Node *)n;
}
static Node *
! makeNullAConst(int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
n->location = location;
return (Node *)n;
}
static Node *
! makeAConst(Value *v, int location)
{
Node *n;
switch (v->type)
{
case T_Float:
! n = makeFloatConst(v->val.str, location);
break;
case T_Integer:
! n = makeIntConst(v->val.ival, location);
break;
case T_String:
default:
! n = makeStringConst(v->val.str, location);
break;
}
--- 12352,12457 ----
}
static Node *
! makeTypeCast(Node *arg, TypeName *typename, int location, int length)
{
TypeCast *n = makeNode(TypeCast);
n->arg = arg;
n->typeName = typename;
n->location = location;
+ n->tok_len = length;
return (Node *) n;
}
static Node *
! makeStringConst(char *str, int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = str;
n->location = location;
+ n->tok_len = length;
return (Node *)n;
}
static Node *
! makeStringConstCast(char *str, int location, int length, TypeName *typename)
{
! Node *s = makeStringConst(str, location, length);
! return makeTypeCast(s, typename, location, length);
}
static Node *
! makeIntConst(int val, int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Integer;
n->val.val.ival = val;
n->location = location;
+ n->tok_len = length;
return (Node *)n;
}
static Node *
! makeFloatConst(char *str, int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Float;
n->val.val.str = str;
n->location = location;
+ n->tok_len = length;
return (Node *)n;
}
static Node *
! makeBitStringConst(char *str, int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_BitString;
n->val.val.str = str;
n->location = location;
+ n->tok_len = length;
return (Node *)n;
}
static Node *
! makeNullAConst(int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
n->location = location;
+ n->tok_len = length;
return (Node *)n;
}
static Node *
! makeAConst(Value *v, int location, int length)
{
Node *n;
switch (v->type)
{
case T_Float:
! n = makeFloatConst(v->val.str, location, length);
break;
case T_Integer:
! n = makeIntConst(v->val.ival, location, length);
break;
case T_String:
default:
! n = makeStringConst(v->val.str, location, length);
break;
}
*************** makeAConst(Value *v, int location)
*** 12456,12470 ****
* Create an A_Const string node and put it inside a boolean cast.
*/
static Node *
! makeBoolAConst(bool state, int location)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = (state ? "t" : "f");
n->location = location;
! return makeTypeCast((Node *)n, SystemTypeName("bool"), -1);
}
/* makeOverlaps()
--- 12462,12477 ----
* Create an A_Const string node and put it inside a boolean cast.
*/
static Node *
! makeBoolAConst(bool state, int location, int length)
{
A_Const *n = makeNode(A_Const);
n->val.type = T_String;
n->val.val.str = (state ? "t" : "f");
n->location = location;
+ n->tok_len = length;
! return makeTypeCast((Node *)n, SystemTypeName("bool"), -1, -1);
}
/* makeOverlaps()
*************** SystemTypeName(char *name)
*** 12696,12702 ****
* until we know what the desired type is.
*/
static Node *
! doNegate(Node *n, int location)
{
if (IsA(n, A_Const))
{
--- 12703,12709 ----
* until we know what the desired type is.
*/
static Node *
! doNegate(Node *n, int location, int length)
{
if (IsA(n, A_Const))
{
*************** doNegate(Node *n, int location)
*** 12704,12718 ****
--- 12711,12729 ----
/* report the constant's location as that of the '-' sign */
con->location = location;
+ /* TODO: A more elegant job of calculating length than this */
+ /*con->tok_len = length; */
if (con->val.type == T_Integer)
{
con->val.val.ival = -con->val.val.ival;
+ con->tok_len = (con->val.val.ival==0? 2: ((int) log10(fabs(con->val.val.ival)) + 2 ) );
return n;
}
if (con->val.type == T_Float)
{
doNegateFloat(&con->val);
+ con->tok_len = strlen(con->val.val.str);
return n;
}
}
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index e8177bc..6aaa4d2 100644
*** a/src/backend/parser/parse_clause.c
--- b/src/backend/parser/parse_clause.c
*************** buildMergedJoinVar(ParseState *pstate, J
*** 1073,1079 ****
if (l_colvar->vartype != outcoltype)
l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype,
outcoltype, outcoltypmod,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
else if (l_colvar->vartypmod != outcoltypmod)
l_node = (Node *) makeRelabelType((Expr *) l_colvar,
outcoltype, outcoltypmod,
--- 1073,1079 ----
if (l_colvar->vartype != outcoltype)
l_node = coerce_type(pstate, (Node *) l_colvar, l_colvar->vartype,
outcoltype, outcoltypmod,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, -1);
else if (l_colvar->vartypmod != outcoltypmod)
l_node = (Node *) makeRelabelType((Expr *) l_colvar,
outcoltype, outcoltypmod,
*************** buildMergedJoinVar(ParseState *pstate, J
*** 1085,1091 ****
if (r_colvar->vartype != outcoltype)
r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype,
outcoltype, outcoltypmod,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
else if (r_colvar->vartypmod != outcoltypmod)
r_node = (Node *) makeRelabelType((Expr *) r_colvar,
outcoltype, outcoltypmod,
--- 1085,1091 ----
if (r_colvar->vartype != outcoltype)
r_node = coerce_type(pstate, (Node *) r_colvar, r_colvar->vartype,
outcoltype, outcoltypmod,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, -1);
else if (r_colvar->vartypmod != outcoltypmod)
r_node = (Node *) makeRelabelType((Expr *) r_colvar,
outcoltype, outcoltypmod,
*************** addTargetToSortList(ParseState *pstate,
*** 1965,1971 ****
restype, TEXTOID, -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1);
restype = TEXTOID;
}
--- 1965,1971 ----
restype, TEXTOID, -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1, -1);
restype = TEXTOID;
}
*************** addTargetToGroupList(ParseState *pstate,
*** 2108,2114 ****
restype, TEXTOID, -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1);
restype = TEXTOID;
}
--- 2108,2114 ----
restype, TEXTOID, -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1, -1);
restype = TEXTOID;
}
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index c072325..004cea9 100644
*** a/src/backend/parser/parse_coerce.c
--- b/src/backend/parser/parse_coerce.c
*************** coerce_to_target_type(ParseState *pstate
*** 76,82 ****
Oid targettype, int32 targettypmod,
CoercionContext ccontext,
CoercionForm cformat,
! int location)
{
Node *result;
--- 76,83 ----
Oid targettype, int32 targettypmod,
CoercionContext ccontext,
CoercionForm cformat,
! int location,
! int tok_len)
{
Node *result;
*************** coerce_to_target_type(ParseState *pstate
*** 85,91 ****
result = coerce_type(pstate, expr, exprtype,
targettype, targettypmod,
! ccontext, cformat, location);
/*
* If the target is a fixed-length type, it may need a length coercion as
--- 86,92 ----
result = coerce_type(pstate, expr, exprtype,
targettype, targettypmod,
! ccontext, cformat, location, tok_len);
/*
* If the target is a fixed-length type, it may need a length coercion as
*************** coerce_to_target_type(ParseState *pstate
*** 127,133 ****
Node *
coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
! CoercionContext ccontext, CoercionForm cformat, int location)
{
Node *result;
CoercionPathType pathtype;
--- 128,134 ----
Node *
coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
! CoercionContext ccontext, CoercionForm cformat, int location, int tok_len)
{
Node *result;
CoercionPathType pathtype;
*************** coerce_type(ParseState *pstate, Node *no
*** 256,266 ****
--- 257,276 ----
newcon->constisnull = con->constisnull;
/* Use the leftmost of the constant's and coercion's locations */
if (location < 0)
+ {
newcon->location = con->location;
+ newcon->tok_len = con->tok_len;
+ }
else if (con->location >= 0 && con->location < location)
+ {
newcon->location = con->location;
+ newcon->tok_len = con->tok_len;
+ }
else
+ {
newcon->location = location;
+ newcon->tok_len = tok_len;
+ }
/*
* Set up to point at the constant's text if the input routine throws
*************** coerce_type(ParseState *pstate, Node *no
*** 326,332 ****
newcoll->arg = (Expr *)
coerce_type(pstate, (Node *) coll->arg,
inputTypeId, targetTypeId, targetTypeMod,
! ccontext, cformat, location);
newcoll->collOid = coll->collOid;
newcoll->location = coll->location;
return (Node *) newcoll;
--- 336,342 ----
newcoll->arg = (Expr *)
coerce_type(pstate, (Node *) coll->arg,
inputTypeId, targetTypeId, targetTypeMod,
! ccontext, cformat, location, tok_len);
newcoll->collOid = coll->collOid;
newcoll->location = coll->location;
return (Node *) newcoll;
*************** coerce_record_to_complex(ParseState *pst
*** 947,953 ****
tupdesc->attrs[i]->atttypmod,
ccontext,
COERCE_IMPLICIT_CAST,
! -1);
if (cexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
--- 957,963 ----
tupdesc->attrs[i]->atttypmod,
ccontext,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (cexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
*************** coerce_to_boolean(ParseState *pstate, No
*** 1007,1013 ****
BOOLOID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (newnode == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 1017,1023 ----
BOOLOID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (newnode == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** coerce_to_specific_type(ParseState *psta
*** 1054,1060 ****
targetTypeId, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (newnode == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 1064,1070 ----
targetTypeId, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (newnode == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** coerce_to_common_type(ParseState *pstate
*** 1254,1260 ****
return node; /* no work */
if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1);
else
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
--- 1264,1270 ----
return node; /* no work */
if (can_coerce_type(1, &inputTypeId, &targetTypeId, COERCION_IMPLICIT))
node = coerce_type(pstate, node, inputTypeId, targetTypeId, -1,
! COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, -1);
else
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 75236c7..5849900 100644
*** a/src/backend/parser/parse_expr.c
--- b/src/backend/parser/parse_expr.c
*************** transformExpr(ParseState *pstate, Node *
*** 125,131 ****
A_Const *con = (A_Const *) expr;
Value *val = &con->val;
! result = (Node *) make_const(pstate, val, con->location);
break;
}
--- 125,131 ----
A_Const *con = (A_Const *) expr;
Value *val = &con->val;
! result = (Node *) make_const(pstate, val, con->location, con->tok_len);
break;
}
*************** transformCaseExpr(ParseState *pstate, Ca
*** 1347,1352 ****
--- 1347,1353 ----
n->val.type = T_Null;
n->location = -1;
+ n->tok_len = -1;
defresult = (Node *) n;
}
newc->defresult = (Expr *) transformExpr(pstate, defresult);
*************** transformArrayExpr(ParseState *pstate, A
*** 1663,1669 ****
typmod,
COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST,
! -1);
if (newe == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
--- 1664,1670 ----
typmod,
COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST,
! -1, -1);
if (newe == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
*************** transformXmlSerialize(ParseState *pstate
*** 1942,1948 ****
TEXTOID, targetType, targetTypmod,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1);
if (result == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
--- 1943,1949 ----
TEXTOID, targetType, targetTypmod,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (result == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
*************** transformTypeCast(ParseState *pstate, Ty
*** 2092,2098 ****
Oid inputType = exprType(expr);
Oid targetType;
int32 targetTypmod;
! int location;
typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
--- 2093,2099 ----
Oid inputType = exprType(expr);
Oid targetType;
int32 targetTypmod;
! int location, tok_len;
typenameTypeIdAndMod(pstate, tc->typeName, &targetType, &targetTypmod);
*************** transformTypeCast(ParseState *pstate, Ty
*** 2105,2110 ****
--- 2106,2112 ----
* name (this can happen in TypeName 'string' syntax, for instance).
*/
location = tc->location;
+ tok_len = tc->tok_len;
if (location < 0)
location = tc->typeName->location;
*************** transformTypeCast(ParseState *pstate, Ty
*** 2112,2118 ****
targetType, targetTypmod,
COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST,
! location);
if (result == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
--- 2114,2120 ----
targetType, targetTypmod,
COERCION_EXPLICIT,
COERCE_EXPLICIT_CAST,
! location, tok_len);
if (result == NULL)
ereport(ERROR,
(errcode(ERRCODE_CANNOT_COERCE),
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 01ed85b..ccebc9f 100644
*** a/src/backend/parser/parse_func.c
--- b/src/backend/parser/parse_func.c
*************** ParseFuncOrColumn(ParseState *pstate, Li
*** 222,228 ****
*/
return coerce_type(pstate, linitial(fargs),
actual_arg_types[0], rettype, -1,
! COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location);
}
else if (fdresult == FUNCDETAIL_NORMAL)
{
--- 222,228 ----
*/
return coerce_type(pstate, linitial(fargs),
actual_arg_types[0], rettype, -1,
! COERCION_EXPLICIT, COERCE_EXPLICIT_CALL, location, -1);
}
else if (fdresult == FUNCDETAIL_NORMAL)
{
*************** make_fn_arguments(ParseState *pstate,
*** 1356,1362 ****
declared_arg_types[i], -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1);
na->arg = (Expr *) node;
}
else
--- 1356,1362 ----
declared_arg_types[i], -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1, -1);
na->arg = (Expr *) node;
}
else
*************** make_fn_arguments(ParseState *pstate,
*** 1367,1373 ****
declared_arg_types[i], -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1);
lfirst(current_fargs) = node;
}
}
--- 1367,1373 ----
declared_arg_types[i], -1,
COERCION_IMPLICIT,
COERCE_IMPLICIT_CAST,
! -1, -1);
lfirst(current_fargs) = node;
}
}
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 7b5c040..2d0e610 100644
*** a/src/backend/parser/parse_node.c
--- b/src/backend/parser/parse_node.c
*************** transformArraySubscripts(ParseState *pst
*** 335,341 ****
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 335,341 ----
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** transformArraySubscripts(ParseState *pst
*** 362,368 ****
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 362,368 ----
INT4OID, -1,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (subexpr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** transformArraySubscripts(ParseState *pst
*** 386,392 ****
typeneeded, arrayTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (newFrom == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 386,392 ----
typeneeded, arrayTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (newFrom == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** transformArraySubscripts(ParseState *pst
*** 434,440 ****
* too many examples that fail if we try.
*/
Const *
! make_const(ParseState *pstate, Value *value, int location)
{
Const *con;
Datum val;
--- 434,440 ----
* too many examples that fail if we try.
*/
Const *
! make_const(ParseState *pstate, Value *value, int location, int tok_len)
{
Const *con;
Datum val;
*************** make_const(ParseState *pstate, Value *va
*** 533,538 ****
--- 533,539 ----
true,
false);
con->location = location;
+ con->tok_len = tok_len;
return con;
default:
*************** make_const(ParseState *pstate, Value *va
*** 548,553 ****
--- 549,555 ----
false,
typebyval);
con->location = location;
+ con->tok_len = tok_len;
return con;
}
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 2f2e87f..651f72a 100644
*** a/src/backend/parser/parse_target.c
--- b/src/backend/parser/parse_target.c
*************** transformAssignedExpr(ParseState *pstate
*** 478,484 ****
attrtype, attrtypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 478,484 ----
attrtype, attrtypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
*************** transformAssignmentIndirection(ParseStat
*** 722,728 ****
targetTypeId, targetTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (result == NULL)
{
if (targetIsArray)
--- 722,728 ----
targetTypeId, targetTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (result == NULL)
{
if (targetIsArray)
*************** transformAssignmentSubscripts(ParseState
*** 822,828 ****
targetTypeId, targetTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
/* probably shouldn't fail, but check */
if (result == NULL)
ereport(ERROR,
--- 822,828 ----
targetTypeId, targetTypMod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
/* probably shouldn't fail, but check */
if (result == NULL)
ereport(ERROR,
diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l
index 12db190..329a15b 100644
*** a/src/backend/parser/scan.l
--- b/src/backend/parser/scan.l
*************** bool standard_conforming_strings = tru
*** 73,84 ****
* this should be done in the first such rule, else yylloc will point
* into the middle of the token.
*/
! #define SET_YYLLOC() (*(yylloc) = yytext - yyextra->scanbuf)
/*
* Advance yylloc by the given number of bytes.
*/
! #define ADVANCE_YYLLOC(delta) ( *(yylloc) += (delta) )
#define startlit() ( yyextra->literallen = 0 )
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
--- 73,86 ----
* this should be done in the first such rule, else yylloc will point
* into the middle of the token.
*/
! #define SET_YYLLOC_BEGINS() yylloc->length = 0; yylloc->begins = yytext - yyextra->scanbuf;
! #define SET_YYLLOC_LEN() yylloc->length += strlen(yytext);
!
/*
* Advance yylloc by the given number of bytes.
*/
! #define ADVANCE_YYLLOC(delta) ( yylloc->begins += (delta) )
#define startlit() ( yyextra->literallen = 0 )
static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
*************** static void addunicode(pg_wchar c, yysca
*** 94,100 ****
#define yyerror(msg) scanner_yyerror(msg, yyscanner)
! #define lexer_errposition() scanner_errposition(*(yylloc), yyscanner)
static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner);
static void check_escape_warning(core_yyscan_t yyscanner);
--- 96,102 ----
#define yyerror(msg) scanner_yyerror(msg, yyscanner)
! #define lexer_errposition() scanner_errposition(yylloc->begins, yyscanner)
static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner);
static void check_escape_warning(core_yyscan_t yyscanner);
*************** other .
*** 377,393 ****
{xcstart} {
/* Set location in case of syntax error in comment */
! SET_YYLLOC();
yyextra->xcdepth = 0;
BEGIN(xc);
/* Put back any characters past slash-star; see above */
yyless(2);
}
<xc>{xcstart} {
(yyextra->xcdepth)++;
/* Put back any characters past slash-star; see above */
yyless(2);
}
<xc>{xcstop} {
--- 379,397 ----
{xcstart} {
/* Set location in case of syntax error in comment */
! SET_YYLLOC_BEGINS();
yyextra->xcdepth = 0;
BEGIN(xc);
/* Put back any characters past slash-star; see above */
yyless(2);
+ SET_YYLLOC_LEN();
}
<xc>{xcstart} {
(yyextra->xcdepth)++;
/* Put back any characters past slash-star; see above */
yyless(2);
+ SET_YYLLOC_LEN();
}
<xc>{xcstop} {
*************** other .
*** 395,400 ****
--- 399,405 ----
BEGIN(INITIAL);
else
(yyextra->xcdepth)--;
+ SET_YYLLOC_LEN();
}
<xc>{xcinside} {
*************** other .
*** 418,438 ****
* In the meantime, place a leading "b" on the string
* to mark it for the input routine as a binary string.
*/
! SET_YYLLOC();
BEGIN(xb);
startlit();
addlitchar('b', yyscanner);
}
<xb>{quotestop} |
<xb>{quotefail} {
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
return BCONST;
}
<xh>{xhinside} |
<xb>{xbinside} {
addlit(yytext, yyleng, yyscanner);
}
<xh>{quotecontinue} |
<xb>{quotecontinue} {
--- 423,446 ----
* In the meantime, place a leading "b" on the string
* to mark it for the input routine as a binary string.
*/
! SET_YYLLOC_BEGINS();
BEGIN(xb);
startlit();
addlitchar('b', yyscanner);
+ SET_YYLLOC_LEN();
}
<xb>{quotestop} |
<xb>{quotefail} {
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
+ SET_YYLLOC_LEN();
return BCONST;
}
<xh>{xhinside} |
<xb>{xbinside} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xh>{quotecontinue} |
<xb>{quotecontinue} {
*************** other .
*** 447,462 ****
* In the meantime, place a leading "x" on the string
* to mark it for the input routine as a hex string.
*/
! SET_YYLLOC();
BEGIN(xh);
startlit();
addlitchar('x', yyscanner);
}
<xh>{quotestop} |
<xh>{quotefail} {
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
return XCONST;
}
<xh><<EOF>> { yyerror("unterminated hexadecimal string literal"); }
--- 455,472 ----
* In the meantime, place a leading "x" on the string
* to mark it for the input routine as a hex string.
*/
! SET_YYLLOC_BEGINS();
BEGIN(xh);
startlit();
addlitchar('x', yyscanner);
+ SET_YYLLOC_LEN();
}
<xh>{quotestop} |
<xh>{quotefail} {
yyless(1);
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
+ SET_YYLLOC_LEN();
return XCONST;
}
<xh><<EOF>> { yyerror("unterminated hexadecimal string literal"); }
*************** other .
*** 468,474 ****
*/
const ScanKeyword *keyword;
! SET_YYLLOC();
yyless(1); /* eat only 'n' this time */
keyword = ScanKeywordLookup("nchar",
--- 478,485 ----
*/
const ScanKeyword *keyword;
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
yyless(1); /* eat only 'n' this time */
keyword = ScanKeywordLookup("nchar",
*************** other .
*** 490,511 ****
{xqstart} {
yyextra->warn_on_first_escape = true;
yyextra->saw_non_ascii = false;
! SET_YYLLOC();
if (standard_conforming_strings)
BEGIN(xq);
else
BEGIN(xe);
startlit();
}
{xestart} {
yyextra->warn_on_first_escape = false;
yyextra->saw_non_ascii = false;
! SET_YYLLOC();
BEGIN(xe);
startlit();
}
{xusstart} {
! SET_YYLLOC();
if (!standard_conforming_strings)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
--- 501,525 ----
{xqstart} {
yyextra->warn_on_first_escape = true;
yyextra->saw_non_ascii = false;
! SET_YYLLOC_BEGINS();
if (standard_conforming_strings)
BEGIN(xq);
else
BEGIN(xe);
startlit();
+ yylloc->length = 0;
+ SET_YYLLOC_LEN();
}
{xestart} {
yyextra->warn_on_first_escape = false;
yyextra->saw_non_ascii = false;
! SET_YYLLOC_BEGINS();
BEGIN(xe);
startlit();
+ SET_YYLLOC_LEN();
}
{xusstart} {
! SET_YYLLOC_BEGINS();
if (!standard_conforming_strings)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
*************** other .
*** 513,518 ****
--- 527,533 ----
errdetail("String constants with Unicode escapes cannot be used when standard_conforming_strings is off."),
lexer_errposition()));
BEGIN(xus);
+ SET_YYLLOC_LEN();
startlit();
}
<xq,xe>{quotestop} |
*************** other .
*** 528,533 ****
--- 543,549 ----
yyextra->literallen,
false);
yylval->str = litbufdup(yyscanner);
+ SET_YYLLOC_LEN();
return SCONST;
}
<xus>{xusstop1} {
*************** other .
*** 535,555 ****
--- 551,576 ----
yyless(1);
BEGIN(INITIAL);
yylval->str = litbuf_udeescape('\\', yyscanner);
+ SET_YYLLOC_LEN();
return SCONST;
}
<xus>{xusstop2} {
BEGIN(INITIAL);
yylval->str = litbuf_udeescape(yytext[yyleng-2], yyscanner);
+ SET_YYLLOC_LEN();
return SCONST;
}
<xq,xe,xus>{xqdouble} {
addlitchar('\'', yyscanner);
+ SET_YYLLOC_LEN();
}
<xq,xus>{xqinside} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xe>{xeinside} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xe>{xeunicode} {
pg_wchar c = strtoul(yytext+2, NULL, 16);
*************** other .
*** 565,570 ****
--- 586,592 ----
yyerror("invalid Unicode surrogate pair");
else
addunicode(c, yyscanner);
+ SET_YYLLOC_LEN();
}
<xeu>{xeunicode} {
pg_wchar c = strtoul(yytext+2, NULL, 16);
*************** other .
*** 577,582 ****
--- 599,605 ----
addunicode(c, yyscanner);
BEGIN(xe);
+ SET_YYLLOC_LEN();
}
<xeu>. { yyerror("invalid Unicode surrogate pair"); }
<xeu>\n { yyerror("invalid Unicode surrogate pair"); }
*************** other .
*** 603,608 ****
--- 626,632 ----
check_string_escape_warning(yytext[1], yyscanner);
addlitchar(unescape_single_char(yytext[1], yyscanner),
yyscanner);
+ SET_YYLLOC_LEN();
}
<xe>{xeoctesc} {
unsigned char c = strtoul(yytext+1, NULL, 8);
*************** other .
*** 611,616 ****
--- 635,641 ----
addlitchar(c, yyscanner);
if (c == '\0' || IS_HIGHBIT_SET(c))
yyextra->saw_non_ascii = true;
+ SET_YYLLOC_LEN();
}
<xe>{xehexesc} {
unsigned char c = strtoul(yytext+2, NULL, 16);
*************** other .
*** 619,624 ****
--- 644,650 ----
addlitchar(c, yyscanner);
if (c == '\0' || IS_HIGHBIT_SET(c))
yyextra->saw_non_ascii = true;
+ SET_YYLLOC_LEN();
}
<xq,xe,xus>{quotecontinue} {
/* ignore */
*************** other .
*** 626,644 ****
<xe>. {
/* This is only needed for \ just before EOF */
addlitchar(yytext[0], yyscanner);
}
<xq,xe,xus><<EOF>> { yyerror("unterminated quoted string"); }
{dolqdelim} {
! SET_YYLLOC();
yyextra->dolqstart = pstrdup(yytext);
BEGIN(xdolq);
startlit();
}
{dolqfailed} {
! SET_YYLLOC();
/* throw back all but the initial "$" */
yyless(1);
/* and treat it as {other} */
return yytext[0];
}
--- 652,674 ----
<xe>. {
/* This is only needed for \ just before EOF */
addlitchar(yytext[0], yyscanner);
+ SET_YYLLOC_LEN();
}
<xq,xe,xus><<EOF>> { yyerror("unterminated quoted string"); }
{dolqdelim} {
! SET_YYLLOC_BEGINS();
yyextra->dolqstart = pstrdup(yytext);
BEGIN(xdolq);
startlit();
+ yylloc->length = 0;
+ SET_YYLLOC_LEN();
}
{dolqfailed} {
! SET_YYLLOC_BEGINS();
/* throw back all but the initial "$" */
yyless(1);
+ SET_YYLLOC_LEN();
/* and treat it as {other} */
return yytext[0];
}
*************** other .
*** 649,654 ****
--- 679,685 ----
yyextra->dolqstart = NULL;
BEGIN(INITIAL);
yylval->str = litbufdup(yyscanner);
+ SET_YYLLOC_LEN();
return SCONST;
}
else
*************** other .
*** 660,688 ****
*/
addlit(yytext, yyleng-1, yyscanner);
yyless(yyleng-1);
}
}
<xdolq>{dolqinside} {
addlit(yytext, yyleng, yyscanner);
}
<xdolq>{dolqfailed} {
addlit(yytext, yyleng, yyscanner);
}
<xdolq>. {
/* This is only needed for $ inside the quoted text */
addlitchar(yytext[0], yyscanner);
}
<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
{xdstart} {
! SET_YYLLOC();
BEGIN(xd);
startlit();
}
{xuistart} {
! SET_YYLLOC();
BEGIN(xui);
startlit();
}
<xd>{xdstop} {
char *ident;
--- 691,725 ----
*/
addlit(yytext, yyleng-1, yyscanner);
yyless(yyleng-1);
+ SET_YYLLOC_LEN();
}
}
<xdolq>{dolqinside} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xdolq>{dolqfailed} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xdolq>. {
/* This is only needed for $ inside the quoted text */
addlitchar(yytext[0], yyscanner);
+ SET_YYLLOC_LEN();
}
<xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
{xdstart} {
! SET_YYLLOC_BEGINS();
BEGIN(xd);
startlit();
+ SET_YYLLOC_LEN();
}
{xuistart} {
! SET_YYLLOC_BEGINS();
BEGIN(xui);
startlit();
+ SET_YYLLOC_LEN();
}
<xd>{xdstop} {
char *ident;
*************** other .
*** 694,699 ****
--- 731,737 ----
if (yyextra->literallen >= NAMEDATALEN)
truncate_identifier(ident, yyextra->literallen, true);
yylval->str = ident;
+ SET_YYLLOC_LEN();
return IDENT;
}
<xui>{xuistop1} {
*************** other .
*** 708,713 ****
--- 746,752 ----
yylval->str = ident;
/* throw back all but the quote */
yyless(1);
+ SET_YYLLOC_LEN();
return IDENT;
}
<xui>{xuistop2} {
*************** other .
*** 720,764 ****
if (yyextra->literallen >= NAMEDATALEN)
truncate_identifier(ident, yyextra->literallen, true);
yylval->str = ident;
return IDENT;
}
<xd,xui>{xddouble} {
addlitchar('"', yyscanner);
}
<xd,xui>{xdinside} {
addlit(yytext, yyleng, yyscanner);
}
<xd,xui><<EOF>> { yyerror("unterminated quoted identifier"); }
{xufailed} {
char *ident;
! SET_YYLLOC();
/* throw back all but the initial u/U */
yyless(1);
/* and treat it as {identifier} */
ident = downcase_truncate_identifier(yytext, yyleng, true);
yylval->str = ident;
return IDENT;
}
{typecast} {
! SET_YYLLOC();
return TYPECAST;
}
{dot_dot} {
! SET_YYLLOC();
return DOT_DOT;
}
{colon_equals} {
! SET_YYLLOC();
return COLON_EQUALS;
}
{self} {
! SET_YYLLOC();
return yytext[0];
}
--- 759,811 ----
if (yyextra->literallen >= NAMEDATALEN)
truncate_identifier(ident, yyextra->literallen, true);
yylval->str = ident;
+ SET_YYLLOC_LEN();
return IDENT;
}
<xd,xui>{xddouble} {
addlitchar('"', yyscanner);
+ SET_YYLLOC_LEN();
}
<xd,xui>{xdinside} {
addlit(yytext, yyleng, yyscanner);
+ SET_YYLLOC_LEN();
}
<xd,xui><<EOF>> { yyerror("unterminated quoted identifier"); }
{xufailed} {
char *ident;
! SET_YYLLOC_BEGINS();
/* throw back all but the initial u/U */
yyless(1);
/* and treat it as {identifier} */
ident = downcase_truncate_identifier(yytext, yyleng, true);
yylval->str = ident;
+ SET_YYLLOC_LEN();
return IDENT;
}
{typecast} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return TYPECAST;
}
{dot_dot} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return DOT_DOT;
}
{colon_equals} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return COLON_EQUALS;
}
{self} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return yytext[0];
}
*************** other .
*** 808,814 ****
nchars--; /* else remove the +/-, and check again */
}
! SET_YYLLOC();
if (nchars < yyleng)
{
--- 855,861 ----
nchars--; /* else remove the +/-, and check again */
}
! SET_YYLLOC_BEGINS();
if (nchars < yyleng)
{
*************** other .
*** 839,871 ****
yylval->str = pstrdup("<>");
else
yylval->str = pstrdup(yytext);
return Op;
}
{param} {
! SET_YYLLOC();
yylval->ival = atol(yytext + 1);
return PARAM;
}
{integer} {
! SET_YYLLOC();
return process_integer_literal(yytext, yylval);
}
{decimal} {
! SET_YYLLOC();
yylval->str = pstrdup(yytext);
return FCONST;
}
{decimalfail} {
/* throw back the .., and treat as integer */
yyless(yyleng-2);
! SET_YYLLOC();
return process_integer_literal(yytext, yylval);
}
{real} {
! SET_YYLLOC();
yylval->str = pstrdup(yytext);
return FCONST;
}
{realfail1} {
--- 886,924 ----
yylval->str = pstrdup("<>");
else
yylval->str = pstrdup(yytext);
+ SET_YYLLOC_LEN();
return Op;
}
{param} {
! SET_YYLLOC_BEGINS();
yylval->ival = atol(yytext + 1);
+ SET_YYLLOC_LEN();
return PARAM;
}
{integer} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return process_integer_literal(yytext, yylval);
}
{decimal} {
! SET_YYLLOC_BEGINS();
yylval->str = pstrdup(yytext);
+ SET_YYLLOC_LEN();
return FCONST;
}
{decimalfail} {
/* throw back the .., and treat as integer */
yyless(yyleng-2);
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return process_integer_literal(yytext, yylval);
}
{real} {
! SET_YYLLOC_BEGINS();
yylval->str = pstrdup(yytext);
+ SET_YYLLOC_LEN();
return FCONST;
}
{realfail1} {
*************** other .
*** 876,890 ****
* syntax error anyway, we don't bother to distinguish.
*/
yyless(yyleng-1);
! SET_YYLLOC();
yylval->str = pstrdup(yytext);
return FCONST;
}
{realfail2} {
/* throw back the [Ee][+-], and proceed as above */
yyless(yyleng-2);
! SET_YYLLOC();
yylval->str = pstrdup(yytext);
return FCONST;
}
--- 929,945 ----
* syntax error anyway, we don't bother to distinguish.
*/
yyless(yyleng-1);
! SET_YYLLOC_BEGINS();
yylval->str = pstrdup(yytext);
+ SET_YYLLOC_LEN();
return FCONST;
}
{realfail2} {
/* throw back the [Ee][+-], and proceed as above */
yyless(yyleng-2);
! SET_YYLLOC_BEGINS();
yylval->str = pstrdup(yytext);
+ SET_YYLLOC_LEN();
return FCONST;
}
*************** other .
*** 893,904 ****
const ScanKeyword *keyword;
char *ident;
! SET_YYLLOC();
/* Is it a keyword? */
keyword = ScanKeywordLookup(yytext,
yyextra->keywords,
yyextra->num_keywords);
if (keyword != NULL)
{
yylval->keyword = keyword->name;
--- 948,961 ----
const ScanKeyword *keyword;
char *ident;
! SET_YYLLOC_BEGINS();
+ yylloc->length = 0;
/* Is it a keyword? */
keyword = ScanKeywordLookup(yytext,
yyextra->keywords,
yyextra->num_keywords);
+ SET_YYLLOC_LEN();
if (keyword != NULL)
{
yylval->keyword = keyword->name;
*************** other .
*** 915,926 ****
}
{other} {
! SET_YYLLOC();
return yytext[0];
}
<<EOF>> {
! SET_YYLLOC();
yyterminate();
}
--- 972,985 ----
}
{other} {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
return yytext[0];
}
<<EOF>> {
! SET_YYLLOC_BEGINS();
! SET_YYLLOC_LEN();
yyterminate();
}
*************** scanner_errposition(int location, core_y
*** 982,988 ****
void
scanner_yyerror(const char *message, core_yyscan_t yyscanner)
{
! const char *loc = yyextra->scanbuf + *yylloc;
if (*loc == YY_END_OF_BUFFER_CHAR)
{
--- 1041,1047 ----
void
scanner_yyerror(const char *message, core_yyscan_t yyscanner)
{
! const char *loc = yyextra->scanbuf + yylloc->begins;
if (*loc == YY_END_OF_BUFFER_CHAR)
{
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index a6f4141..5763991 100644
*** a/src/backend/rewrite/rewriteHandler.c
--- b/src/backend/rewrite/rewriteHandler.c
*************** build_column_default(Relation rel, int a
*** 1023,1029 ****
atttype, atttypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
--- 1023,1029 ----
atttype, atttypmod,
COERCION_ASSIGNMENT,
COERCE_IMPLICIT_CAST,
! -1, -1);
if (expr == NULL)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9e277c5..2de221e 100644
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
*************** typedef struct A_Const
*** 252,257 ****
--- 252,258 ----
NodeTag type;
Value val; /* value (includes type info, see value.h) */
int location; /* token location, or -1 if unknown */
+ int tok_len; /* token length (in bytes) */
} A_Const;
/*
*************** typedef struct TypeCast
*** 263,268 ****
--- 264,270 ----
Node *arg; /* the expression being casted */
TypeName *typeName; /* the target type */
int location; /* token location, or -1 if unknown */
+ int tok_len; /* token length (in bytes) */
} TypeCast;
/*
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 28a2b12..c164a55 100644
*** a/src/include/nodes/primnodes.h
--- b/src/include/nodes/primnodes.h
*************** typedef struct Const
*** 171,176 ****
--- 171,177 ----
* in the Datum. If false, then the Datum
* contains a pointer to the information. */
int location; /* token location, or -1 if unknown */
+ int tok_len; /* token length (in bytes) */
} Const;
/* ----------------
diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h
index ceaff2f..85f3fdd 100644
*** a/src/include/parser/parse_coerce.h
--- b/src/include/parser/parse_coerce.h
*************** extern Node *coerce_to_target_type(Parse
*** 40,51 ****
Oid targettype, int32 targettypmod,
CoercionContext ccontext,
CoercionForm cformat,
! int location);
extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
CoercionContext ccontext);
extern Node *coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
! CoercionContext ccontext, CoercionForm cformat, int location);
extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
Oid typeId,
CoercionForm cformat, int location,
--- 40,52 ----
Oid targettype, int32 targettypmod,
CoercionContext ccontext,
CoercionForm cformat,
! int location,
! int tok_len);
extern bool can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
CoercionContext ccontext);
extern Node *coerce_type(ParseState *pstate, Node *node,
Oid inputTypeId, Oid targetTypeId, int32 targetTypeMod,
! CoercionContext ccontext, CoercionForm cformat, int location, int tok_len);
extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod,
Oid typeId,
CoercionForm cformat, int location,
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index 0ca7914..fde2a93 100644
*** a/src/include/parser/parse_node.h
--- b/src/include/parser/parse_node.h
*************** extern ArrayRef *transformArraySubscript
*** 148,153 ****
int32 arrayTypMod,
List *indirection,
Node *assignFrom);
! extern Const *make_const(ParseState *pstate, Value *value, int location);
#endif /* PARSE_NODE_H */
--- 148,153 ----
int32 arrayTypMod,
List *indirection,
Node *assignFrom);
! extern Const *make_const(ParseState *pstate, Value *value, int location, int tok_len);
#endif /* PARSE_NODE_H */
diff --git a/src/include/parser/scanner.h b/src/include/parser/scanner.h
index 2a88e97..e12ccf4 100644
*** a/src/include/parser/scanner.h
--- b/src/include/parser/scanner.h
*************** typedef union core_YYSTYPE
*** 36,47 ****
/*
* We track token locations in terms of byte offsets from the start of the
* source string, not the column number/line number representation that
! * bison uses by default. Also, to minimize overhead we track only one
! * location (usually the first token location) for each construct, not
! * the beginning and ending locations as bison does by default. It's
! * therefore sufficient to make YYLTYPE an int.
*/
! #define YYLTYPE int
/*
* Another important component of the scanner's API is the token code numbers.
--- 36,51 ----
/*
* We track token locations in terms of byte offsets from the start of the
* source string, not the column number/line number representation that
! * bison uses by default. We track the beginning of the token, as well
! * as its total length.
*/
! typedef struct my_yyltype
! {
! int begins;
! int length;
! } my_yyltype;
!
! #define YYLTYPE my_yyltype
/*
* Another important component of the scanner's API is the token code numbers.
diff --git a/src/pl/plpgsql/src/gram.y b/src/pl/plpgsql/src/gram.y
index 8c4c2f7..ce932c4 100644
*** a/src/pl/plpgsql/src/gram.y
--- b/src/pl/plpgsql/src/gram.y
*************** pl_block : decl_sect K_BEGIN proc_sect
*** 367,380 ****
new = palloc0(sizeof(PLpgSQL_stmt_block));
new->cmd_type = PLPGSQL_STMT_BLOCK;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1.label;
new->n_initvars = $1.n_initvars;
new->initvarnos = $1.initvarnos;
new->body = $3;
new->exceptions = $4;
! check_labels($1.label, $6, @6);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)new;
--- 367,380 ----
new = palloc0(sizeof(PLpgSQL_stmt_block));
new->cmd_type = PLPGSQL_STMT_BLOCK;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1.label;
new->n_initvars = $1.n_initvars;
new->initvarnos = $1.initvarnos;
new->body = $3;
new->exceptions = $4;
! check_labels($1.label, $6, @6.begins);
plpgsql_ns_pop();
$$ = (PLpgSQL_stmt *)new;
*************** decl_stmt : decl_statement
*** 436,442 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("block label must be placed before DECLARE, not after"),
! parser_errposition(@1)));
}
;
--- 436,442 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("block label must be placed before DECLARE, not after"),
! parser_errposition(@1.begins)));
}
;
*************** decl_statement : decl_varname decl_const
*** 457,463 ****
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("collations are not supported by type %s",
format_type_be($3->typoid)),
! parser_errposition(@4)));
$3->collation = $4;
}
--- 457,463 ----
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("collations are not supported by type %s",
format_type_be($3->typoid)),
! parser_errposition(@4.begins)));
$3->collation = $4;
}
*************** decl_statement : decl_varname decl_const
*** 471,477 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row or record variable cannot be CONSTANT"),
! parser_errposition(@2)));
}
if ($5)
{
--- 471,477 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row or record variable cannot be CONSTANT"),
! parser_errposition(@2.begins)));
}
if ($5)
{
*************** decl_statement : decl_varname decl_const
*** 481,487 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row or record variable cannot be NOT NULL"),
! parser_errposition(@4)));
}
if ($6 != NULL)
--- 481,487 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("row or record variable cannot be NOT NULL"),
! parser_errposition(@4.begins)));
}
if ($6 != NULL)
*************** decl_statement : decl_varname decl_const
*** 492,498 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("default value for row or record variable is not supported"),
! parser_errposition(@5)));
}
}
| decl_varname K_ALIAS K_FOR decl_aliasitem ';'
--- 492,498 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("default value for row or record variable is not supported"),
! parser_errposition(@5.begins)));
}
}
| decl_varname K_ALIAS K_FOR decl_aliasitem ';'
*************** decl_cursor_args :
*** 584,590 ****
new = palloc0(sizeof(PLpgSQL_row));
new->dtype = PLPGSQL_DTYPE_ROW;
! new->lineno = plpgsql_location_to_lineno(@1);
new->rowtupdesc = NULL;
new->nfields = list_length($2);
new->fieldnames = palloc(new->nfields * sizeof(char *));
--- 584,590 ----
new = palloc0(sizeof(PLpgSQL_row));
new->dtype = PLPGSQL_DTYPE_ROW;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->rowtupdesc = NULL;
new->nfields = list_length($2);
new->fieldnames = palloc(new->nfields * sizeof(char *));
*************** decl_aliasitem : T_WORD
*** 638,644 ****
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("variable \"%s\" does not exist",
$1.ident),
! parser_errposition(@1)));
$$ = nsi;
}
| T_CWORD
--- 638,644 ----
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("variable \"%s\" does not exist",
$1.ident),
! parser_errposition(@1.begins)));
$$ = nsi;
}
| T_CWORD
*************** decl_aliasitem : T_WORD
*** 664,670 ****
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("variable \"%s\" does not exist",
NameListToString($1.idents)),
! parser_errposition(@1)));
$$ = nsi;
}
;
--- 664,670 ----
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("variable \"%s\" does not exist",
NameListToString($1.idents)),
! parser_errposition(@1.begins)));
$$ = nsi;
}
;
*************** decl_aliasitem : T_WORD
*** 672,678 ****
decl_varname : T_WORD
{
$$.name = $1.ident;
! $$.lineno = plpgsql_location_to_lineno(@1);
/*
* Check to make sure name isn't already declared
* in the current block.
--- 672,678 ----
decl_varname : T_WORD
{
$$.name = $1.ident;
! $$.lineno = plpgsql_location_to_lineno(@1.begins);
/*
* Check to make sure name isn't already declared
* in the current block.
*************** decl_varname : T_WORD
*** 685,691 ****
| unreserved_keyword
{
$$.name = pstrdup($1);
! $$.lineno = plpgsql_location_to_lineno(@1);
/*
* Check to make sure name isn't already declared
* in the current block.
--- 685,691 ----
| unreserved_keyword
{
$$.name = pstrdup($1);
! $$.lineno = plpgsql_location_to_lineno(@1.begins);
/*
* Check to make sure name isn't already declared
* in the current block.
*************** stmt_perform : K_PERFORM expr_until_semi
*** 819,825 ****
new = palloc0(sizeof(PLpgSQL_stmt_perform));
new->cmd_type = PLPGSQL_STMT_PERFORM;
! new->lineno = plpgsql_location_to_lineno(@1);
new->expr = $2;
$$ = (PLpgSQL_stmt *)new;
--- 819,825 ----
new = palloc0(sizeof(PLpgSQL_stmt_perform));
new->cmd_type = PLPGSQL_STMT_PERFORM;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->expr = $2;
$$ = (PLpgSQL_stmt *)new;
*************** stmt_assign : assign_var assign_operato
*** 832,838 ****
new = palloc0(sizeof(PLpgSQL_stmt_assign));
new->cmd_type = PLPGSQL_STMT_ASSIGN;
! new->lineno = plpgsql_location_to_lineno(@1);
new->varno = $1;
new->expr = $3;
--- 832,838 ----
new = palloc0(sizeof(PLpgSQL_stmt_assign));
new->cmd_type = PLPGSQL_STMT_ASSIGN;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->varno = $1;
new->expr = $3;
*************** stmt_getdiag : K_GET getdiag_area_opt K_
*** 847,853 ****
new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
new->cmd_type = PLPGSQL_STMT_GETDIAG;
! new->lineno = plpgsql_location_to_lineno(@1);
new->is_stacked = $2;
new->diag_items = $4;
--- 847,853 ----
new = palloc0(sizeof(PLpgSQL_stmt_getdiag));
new->cmd_type = PLPGSQL_STMT_GETDIAG;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->is_stacked = $2;
new->diag_items = $4;
*************** stmt_getdiag : K_GET getdiag_area_opt K_
*** 868,874 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS",
plpgsql_getdiag_kindname(ditem->kind)),
! parser_errposition(@1)));
break;
/* these fields are disallowed in current case */
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
--- 868,874 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("diagnostics item %s is not allowed in GET STACKED DIAGNOSTICS",
plpgsql_getdiag_kindname(ditem->kind)),
! parser_errposition(@1.begins)));
break;
/* these fields are disallowed in current case */
case PLPGSQL_GETDIAG_ERROR_CONTEXT:
*************** stmt_getdiag : K_GET getdiag_area_opt K_
*** 881,887 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS",
plpgsql_getdiag_kindname(ditem->kind)),
! parser_errposition(@1)));
break;
default:
elog(ERROR, "unrecognized diagnostic item kind: %d",
--- 881,887 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("diagnostics item %s is not allowed in GET CURRENT DIAGNOSTICS",
plpgsql_getdiag_kindname(ditem->kind)),
! parser_errposition(@1.begins)));
break;
default:
elog(ERROR, "unrecognized diagnostic item kind: %d",
*************** getdiag_item :
*** 962,993 ****
getdiag_target : T_DATUM
{
! check_assignable($1.datum, @1);
if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
$1.datum->dtype == PLPGSQL_DTYPE_REC)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("\"%s\" is not a scalar variable",
NameOfDatum(&($1))),
! parser_errposition(@1)));
$$ = $1.datum->dno;
}
| T_WORD
{
/* just to give a better message than "syntax error" */
! word_is_not_variable(&($1), @1);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1);
}
;
assign_var : T_DATUM
{
! check_assignable($1.datum, @1);
$$ = $1.datum->dno;
}
| assign_var '[' expr_until_rightbracket
--- 962,993 ----
getdiag_target : T_DATUM
{
! check_assignable($1.datum, @1.begins);
if ($1.datum->dtype == PLPGSQL_DTYPE_ROW ||
$1.datum->dtype == PLPGSQL_DTYPE_REC)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("\"%s\" is not a scalar variable",
NameOfDatum(&($1))),
! parser_errposition(@1.begins)));
$$ = $1.datum->dno;
}
| T_WORD
{
/* just to give a better message than "syntax error" */
! word_is_not_variable(&($1), @1.begins);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1.begins);
}
;
assign_var : T_DATUM
{
! check_assignable($1.datum, @1.begins);
$$ = $1.datum->dno;
}
| assign_var '[' expr_until_rightbracket
*************** stmt_if : K_IF expr_until_then proc_se
*** 1013,1019 ****
new = palloc0(sizeof(PLpgSQL_stmt_if));
new->cmd_type = PLPGSQL_STMT_IF;
! new->lineno = plpgsql_location_to_lineno(@1);
new->cond = $2;
new->then_body = $3;
new->elsif_list = $4;
--- 1013,1019 ----
new = palloc0(sizeof(PLpgSQL_stmt_if));
new->cmd_type = PLPGSQL_STMT_IF;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->cond = $2;
new->then_body = $3;
new->elsif_list = $4;
*************** stmt_elsifs :
*** 1032,1038 ****
PLpgSQL_if_elsif *new;
new = palloc0(sizeof(PLpgSQL_if_elsif));
! new->lineno = plpgsql_location_to_lineno(@2);
new->cond = $3;
new->stmts = $4;
--- 1032,1038 ----
PLpgSQL_if_elsif *new;
new = palloc0(sizeof(PLpgSQL_if_elsif));
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->cond = $3;
new->stmts = $4;
*************** stmt_else :
*** 1052,1058 ****
stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';'
{
! $$ = make_case(@1, $2, $3, $4);
}
;
--- 1052,1058 ----
stmt_case : K_CASE opt_expr_until_when case_when_list opt_case_else K_END K_CASE ';'
{
! $$ = make_case(@1.begins, $2, $3, $4);
}
;
*************** case_when : K_WHEN expr_until_then proc
*** 1085,1091 ****
{
PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
! new->lineno = plpgsql_location_to_lineno(@1);
new->expr = $2;
new->stmts = $3;
$$ = new;
--- 1085,1091 ----
{
PLpgSQL_case_when *new = palloc(sizeof(PLpgSQL_case_when));
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->expr = $2;
new->stmts = $3;
$$ = new;
*************** stmt_loop : opt_block_label K_LOOP loop
*** 1117,1123 ****
new = palloc0(sizeof(PLpgSQL_stmt_loop));
new->cmd_type = PLPGSQL_STMT_LOOP;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1;
new->body = $3.stmts;
--- 1117,1123 ----
new = palloc0(sizeof(PLpgSQL_stmt_loop));
new->cmd_type = PLPGSQL_STMT_LOOP;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1;
new->body = $3.stmts;
*************** stmt_while : opt_block_label K_WHILE ex
*** 1134,1140 ****
new = palloc0(sizeof(PLpgSQL_stmt_while));
new->cmd_type = PLPGSQL_STMT_WHILE;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1;
new->cond = $3;
new->body = $4.stmts;
--- 1134,1140 ----
new = palloc0(sizeof(PLpgSQL_stmt_while));
new->cmd_type = PLPGSQL_STMT_WHILE;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1;
new->cond = $3;
new->body = $4.stmts;
*************** stmt_for : opt_block_label K_FOR for_co
*** 1154,1160 ****
PLpgSQL_stmt_fori *new;
new = (PLpgSQL_stmt_fori *) $3;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
--- 1154,1160 ----
PLpgSQL_stmt_fori *new;
new = (PLpgSQL_stmt_fori *) $3;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
*************** stmt_for : opt_block_label K_FOR for_co
*** 1168,1174 ****
$3->cmd_type == PLPGSQL_STMT_DYNFORS);
/* forq is the common supertype of all three */
new = (PLpgSQL_stmt_forq *) $3;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
--- 1168,1174 ----
$3->cmd_type == PLPGSQL_STMT_DYNFORS);
/* forq is the common supertype of all three */
new = (PLpgSQL_stmt_forq *) $3;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1;
new->body = $4.stmts;
$$ = (PLpgSQL_stmt *) new;
*************** stmt_for : opt_block_label K_FOR for_co
*** 1183,1189 ****
for_control : for_variable K_IN
{
int tok = yylex();
! int tokloc = yylloc;
if (tok == K_EXECUTE)
{
--- 1183,1189 ----
for_control : for_variable K_IN
{
int tok = yylex();
! int tokloc = yylloc.begins;
if (tok == K_EXECUTE)
{
*************** for_control : for_variable K_IN
*** 1201,1218 ****
if ($1.rec)
{
new->rec = $1.rec;
! check_assignable((PLpgSQL_datum *) new->rec, @1);
}
else if ($1.row)
{
new->row = $1.row;
! check_assignable((PLpgSQL_datum *) new->row, @1);
}
else if ($1.scalar)
{
/* convert single scalar to list */
new->row = make_scalar_list1($1.name, $1.scalar,
! $1.lineno, @1);
/* no need for check_assignable */
}
else
--- 1201,1218 ----
if ($1.rec)
{
new->rec = $1.rec;
! check_assignable((PLpgSQL_datum *) new->rec, @1.begins);
}
else if ($1.row)
{
new->row = $1.row;
! check_assignable((PLpgSQL_datum *) new->row, @1.begins);
}
else if ($1.scalar)
{
/* convert single scalar to list */
new->row = make_scalar_list1($1.name, $1.scalar,
! $1.lineno, @1.begins);
/* no need for check_assignable */
}
else
*************** for_control : for_variable K_IN
*** 1220,1226 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
! parser_errposition(@1)));
}
new->query = expr;
--- 1220,1226 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
! parser_errposition(@1.begins)));
}
new->query = expr;
*************** for_control : for_variable K_IN
*** 1254,1260 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor FOR loop must have only one target variable"),
! parser_errposition(@1)));
/* can't use an unbound cursor this way */
if (cursor->cursor_explicit_expr == NULL)
--- 1254,1260 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor FOR loop must have only one target variable"),
! parser_errposition(@1.begins)));
/* can't use an unbound cursor this way */
if (cursor->cursor_explicit_expr == NULL)
*************** for_control : for_variable K_IN
*** 1344,1350 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("integer FOR loop must have only one target variable"),
! parser_errposition(@1)));
/* create loop's private variable */
fvar = (PLpgSQL_var *)
--- 1344,1350 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("integer FOR loop must have only one target variable"),
! parser_errposition(@1.begins)));
/* create loop's private variable */
fvar = (PLpgSQL_var *)
*************** for_control : for_variable K_IN
*** 1394,1411 ****
if ($1.rec)
{
new->rec = $1.rec;
! check_assignable((PLpgSQL_datum *) new->rec, @1);
}
else if ($1.row)
{
new->row = $1.row;
! check_assignable((PLpgSQL_datum *) new->row, @1);
}
else if ($1.scalar)
{
/* convert single scalar to list */
new->row = make_scalar_list1($1.name, $1.scalar,
! $1.lineno, @1);
/* no need for check_assignable */
}
else
--- 1394,1411 ----
if ($1.rec)
{
new->rec = $1.rec;
! check_assignable((PLpgSQL_datum *) new->rec, @1.begins);
}
else if ($1.row)
{
new->row = $1.row;
! check_assignable((PLpgSQL_datum *) new->row, @1.begins);
}
else if ($1.scalar)
{
/* convert single scalar to list */
new->row = make_scalar_list1($1.name, $1.scalar,
! $1.lineno, @1.begins);
/* no need for check_assignable */
}
else
*************** for_control : for_variable K_IN
*** 1413,1419 ****
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
! parser_errposition(@1)));
}
new->query = expr1;
--- 1413,1419 ----
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("loop variable of loop over rows must be a record or row variable or list of scalar variables"),
! parser_errposition(@1.begins)));
}
new->query = expr1;
*************** for_control : for_variable K_IN
*** 1444,1450 ****
for_variable : T_DATUM
{
$$.name = NameOfDatum(&($1));
! $$.lineno = plpgsql_location_to_lineno(@1);
if ($1.datum->dtype == PLPGSQL_DTYPE_ROW)
{
$$.scalar = NULL;
--- 1444,1450 ----
for_variable : T_DATUM
{
$$.name = NameOfDatum(&($1));
! $$.lineno = plpgsql_location_to_lineno(@1.begins);
if ($1.datum->dtype == PLPGSQL_DTYPE_ROW)
{
$$.scalar = NULL;
*************** for_variable : T_DATUM
*** 1470,1476 ****
if (tok == ',')
$$.row = read_into_scalar_list($$.name,
$$.scalar,
! @1);
}
}
| T_WORD
--- 1470,1476 ----
if (tok == ',')
$$.row = read_into_scalar_list($$.name,
$$.scalar,
! @1.begins);
}
}
| T_WORD
*************** for_variable : T_DATUM
*** 1478,1484 ****
int tok;
$$.name = $1.ident;
! $$.lineno = plpgsql_location_to_lineno(@1);
$$.scalar = NULL;
$$.rec = NULL;
$$.row = NULL;
--- 1478,1484 ----
int tok;
$$.name = $1.ident;
! $$.lineno = plpgsql_location_to_lineno(@1.begins);
$$.scalar = NULL;
$$.rec = NULL;
$$.row = NULL;
*************** for_variable : T_DATUM
*** 1486,1497 ****
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == ',')
! word_is_not_variable(&($1), @1);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1);
}
;
--- 1486,1497 ----
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == ',')
! word_is_not_variable(&($1), @1.begins);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1.begins);
}
;
*************** stmt_foreach_a : opt_block_label K_FOREA
*** 1501,1507 ****
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
! new->lineno = plpgsql_location_to_lineno(@2);
new->label = $1;
new->slice = $4;
new->expr = $7;
--- 1501,1507 ----
new = palloc0(sizeof(PLpgSQL_stmt_foreach_a));
new->cmd_type = PLPGSQL_STMT_FOREACH_A;
! new->lineno = plpgsql_location_to_lineno(@2.begins);
new->label = $1;
new->slice = $4;
new->expr = $7;
*************** stmt_foreach_a : opt_block_label K_FOREA
*** 1510,1533 ****
if ($3.rec)
{
new->varno = $3.rec->dno;
! check_assignable((PLpgSQL_datum *) $3.rec, @3);
}
else if ($3.row)
{
new->varno = $3.row->dno;
! check_assignable((PLpgSQL_datum *) $3.row, @3);
}
else if ($3.scalar)
{
new->varno = $3.scalar->dno;
! check_assignable($3.scalar, @3);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("loop variable of FOREACH must be a known variable or list of variables"),
! parser_errposition(@3)));
}
check_labels($1, $8.end_label, $8.end_label_location);
--- 1510,1533 ----
if ($3.rec)
{
new->varno = $3.rec->dno;
! check_assignable((PLpgSQL_datum *) $3.rec, @3.begins);
}
else if ($3.row)
{
new->varno = $3.row->dno;
! check_assignable((PLpgSQL_datum *) $3.row, @3.begins);
}
else if ($3.scalar)
{
new->varno = $3.scalar->dno;
! check_assignable($3.scalar, @3.begins);
}
else
{
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("loop variable of FOREACH must be a known variable or list of variables"),
! parser_errposition(@3.begins)));
}
check_labels($1, $8.end_label, $8.end_label_location);
*************** stmt_exit : exit_type opt_label opt_exi
*** 1554,1560 ****
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
new->is_exit = $1;
! new->lineno = plpgsql_location_to_lineno(@1);
new->label = $2;
new->cond = $3;
--- 1554,1560 ----
new = palloc0(sizeof(PLpgSQL_stmt_exit));
new->cmd_type = PLPGSQL_STMT_EXIT;
new->is_exit = $1;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->label = $2;
new->cond = $3;
*************** stmt_return : K_RETURN
*** 1583,1599 ****
if (tok_is_keyword(tok, &yylval,
K_NEXT, "next"))
{
! $$ = make_return_next_stmt(@1);
}
else if (tok_is_keyword(tok, &yylval,
K_QUERY, "query"))
{
! $$ = make_return_query_stmt(@1);
}
else
{
plpgsql_push_back_token(tok);
! $$ = make_return_stmt(@1);
}
}
;
--- 1583,1599 ----
if (tok_is_keyword(tok, &yylval,
K_NEXT, "next"))
{
! $$ = make_return_next_stmt(@1.begins);
}
else if (tok_is_keyword(tok, &yylval,
K_QUERY, "query"))
{
! $$ = make_return_query_stmt(@1.begins);
}
else
{
plpgsql_push_back_token(tok);
! $$ = make_return_stmt(@1.begins);
}
}
;
*************** stmt_raise : K_RAISE
*** 1606,1612 ****
new = palloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
! new->lineno = plpgsql_location_to_lineno(@1);
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
--- 1606,1612 ----
new = palloc(sizeof(PLpgSQL_stmt_raise));
new->cmd_type = PLPGSQL_STMT_RAISE;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->elog_level = ERROR; /* default */
new->condname = NULL;
new->message = NULL;
*************** loop_body : proc_sect K_END K_LOOP opt_
*** 1741,1747 ****
{
$$.stmts = $1;
$$.end_label = $4;
! $$.end_label_location = @4;
}
;
--- 1741,1747 ----
{
$$.stmts = $1;
$$.end_label = $4;
! $$.end_label_location = @4.begins;
}
;
*************** loop_body : proc_sect K_END K_LOOP opt_
*** 1757,1763 ****
*/
stmt_execsql : K_INSERT
{
! $$ = make_execsql_stmt(K_INSERT, @1);
}
| T_WORD
{
--- 1757,1763 ----
*/
stmt_execsql : K_INSERT
{
! $$ = make_execsql_stmt(K_INSERT, @1.begins);
}
| T_WORD
{
*************** stmt_execsql : K_INSERT
*** 1766,1773 ****
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == '=' || tok == COLON_EQUALS || tok == '[')
! word_is_not_variable(&($1), @1);
! $$ = make_execsql_stmt(T_WORD, @1);
}
| T_CWORD
{
--- 1766,1773 ----
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == '=' || tok == COLON_EQUALS || tok == '[')
! word_is_not_variable(&($1), @1.begins);
! $$ = make_execsql_stmt(T_WORD, @1.begins);
}
| T_CWORD
{
*************** stmt_execsql : K_INSERT
*** 1776,1783 ****
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == '=' || tok == COLON_EQUALS || tok == '[')
! cword_is_not_variable(&($1), @1);
! $$ = make_execsql_stmt(T_CWORD, @1);
}
;
--- 1776,1783 ----
tok = yylex();
plpgsql_push_back_token(tok);
if (tok == '=' || tok == COLON_EQUALS || tok == '[')
! cword_is_not_variable(&($1), @1.begins);
! $$ = make_execsql_stmt(T_CWORD, @1.begins);
}
;
*************** stmt_dynexecute : K_EXECUTE
*** 1795,1801 ****
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
! new->lineno = plpgsql_location_to_lineno(@1);
new->query = expr;
new->into = false;
new->strict = false;
--- 1795,1801 ----
new = palloc(sizeof(PLpgSQL_stmt_dynexecute));
new->cmd_type = PLPGSQL_STMT_DYNEXECUTE;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->query = expr;
new->into = false;
new->strict = false;
*************** stmt_open : K_OPEN cursor_variable
*** 1852,1858 ****
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
! new->lineno = plpgsql_location_to_lineno(@1);
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
--- 1852,1858 ----
new = palloc0(sizeof(PLpgSQL_stmt_open));
new->cmd_type = PLPGSQL_STMT_OPEN;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->curvar = $2->dno;
new->cursor_options = CURSOR_OPT_FAST_PLAN;
*************** stmt_fetch : K_FETCH opt_fetch_directio
*** 1942,1950 ****
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("FETCH statement cannot return multiple rows"),
! parser_errposition(@1)));
! fetch->lineno = plpgsql_location_to_lineno(@1);
fetch->rec = rec;
fetch->row = row;
fetch->curvar = $3->dno;
--- 1942,1950 ----
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("FETCH statement cannot return multiple rows"),
! parser_errposition(@1.begins)));
! fetch->lineno = plpgsql_location_to_lineno(@1.begins);
fetch->rec = rec;
fetch->row = row;
fetch->curvar = $3->dno;
*************** stmt_move : K_MOVE opt_fetch_direction
*** 1958,1964 ****
{
PLpgSQL_stmt_fetch *fetch = $2;
! fetch->lineno = plpgsql_location_to_lineno(@1);
fetch->curvar = $3->dno;
fetch->is_move = true;
--- 1958,1964 ----
{
PLpgSQL_stmt_fetch *fetch = $2;
! fetch->lineno = plpgsql_location_to_lineno(@1.begins);
fetch->curvar = $3->dno;
fetch->is_move = true;
*************** stmt_close : K_CLOSE cursor_variable ';
*** 1978,1984 ****
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
! new->lineno = plpgsql_location_to_lineno(@1);
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
--- 1978,1984 ----
new = palloc(sizeof(PLpgSQL_stmt_close));
new->cmd_type = PLPGSQL_STMT_CLOSE;
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->curvar = $2->dno;
$$ = (PLpgSQL_stmt *)new;
*************** cursor_variable : T_DATUM
*** 1998,2022 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cursor variable must be a simple variable"),
! parser_errposition(@1)));
if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("variable \"%s\" must be of type cursor or refcursor",
((PLpgSQL_var *) $1.datum)->refname),
! parser_errposition(@1)));
$$ = (PLpgSQL_var *) $1.datum;
}
| T_WORD
{
/* just to give a better message than "syntax error" */
! word_is_not_variable(&($1), @1);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1);
}
;
--- 1998,2022 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cursor variable must be a simple variable"),
! parser_errposition(@1.begins)));
if (((PLpgSQL_var *) $1.datum)->datatype->typoid != REFCURSOROID)
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("variable \"%s\" must be of type cursor or refcursor",
((PLpgSQL_var *) $1.datum)->refname),
! parser_errposition(@1.begins)));
$$ = (PLpgSQL_var *) $1.datum;
}
| T_WORD
{
/* just to give a better message than "syntax error" */
! word_is_not_variable(&($1), @1.begins);
}
| T_CWORD
{
/* just to give a better message than "syntax error" */
! cword_is_not_variable(&($1), @1.begins);
}
;
*************** exception_sect :
*** 2031,2037 ****
* scope of the names extends to the end of the
* current block.
*/
! int lineno = plpgsql_location_to_lineno(@1);
PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
PLpgSQL_variable *var;
--- 2031,2037 ----
* scope of the names extends to the end of the
* current block.
*/
! int lineno = plpgsql_location_to_lineno(@1.begins);
PLpgSQL_exception_block *new = palloc(sizeof(PLpgSQL_exception_block));
PLpgSQL_variable *var;
*************** proc_exception : K_WHEN proc_conditions
*** 2077,2083 ****
PLpgSQL_exception *new;
new = palloc0(sizeof(PLpgSQL_exception));
! new->lineno = plpgsql_location_to_lineno(@1);
new->conditions = $2;
new->action = $4;
--- 2077,2083 ----
PLpgSQL_exception *new;
new = palloc0(sizeof(PLpgSQL_exception));
! new->lineno = plpgsql_location_to_lineno(@1.begins);
new->conditions = $2;
new->action = $4;
*************** static void
*** 2310,2318 ****
current_token_is_not_variable(int tok)
{
if (tok == T_WORD)
! word_is_not_variable(&(yylval.word), yylloc);
else if (tok == T_CWORD)
! cword_is_not_variable(&(yylval.cword), yylloc);
else
yyerror("syntax error");
}
--- 2310,2318 ----
current_token_is_not_variable(int tok)
{
if (tok == T_WORD)
! word_is_not_variable(&(yylval.word), yylloc.begins);
else if (tok == T_CWORD)
! cword_is_not_variable(&(yylval.cword), yylloc.begins);
else
yyerror("syntax error");
}
*************** read_sql_construct(int until,
*** 2385,2391 ****
{
tok = yylex();
if (startlocation < 0) /* remember loc of first token */
! startlocation = yylloc;
if (tok == until && parenlevel == 0)
break;
if (tok == until2 && parenlevel == 0)
--- 2385,2391 ----
{
tok = yylex();
if (startlocation < 0) /* remember loc of first token */
! startlocation = yylloc.begins;
if (tok == until && parenlevel == 0)
break;
if (tok == until2 && parenlevel == 0)
*************** read_sql_construct(int until,
*** 2414,2426 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL expression",
expected),
! parser_errposition(yylloc)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL statement",
expected),
! parser_errposition(yylloc)));
}
}
--- 2414,2426 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL expression",
expected),
! parser_errposition(yylloc.begins)));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("missing \"%s\" at end of SQL statement",
expected),
! parser_errposition(yylloc.begins)));
}
}
*************** read_sql_construct(int until,
*** 2432,2438 ****
*endtoken = tok;
/* give helpful complaint about empty input */
! if (startlocation >= yylloc)
{
if (isexpression)
yyerror("missing expression");
--- 2432,2438 ----
*endtoken = tok;
/* give helpful complaint about empty input */
! if (startlocation >= yylloc.begins)
{
if (isexpression)
yyerror("missing expression");
*************** read_sql_construct(int until,
*** 2440,2446 ****
yyerror("missing SQL statement");
}
! plpgsql_append_source_text(&ds, startlocation, yylloc);
/* trim any trailing whitespace, for neatness */
while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
--- 2440,2446 ----
yyerror("missing SQL statement");
}
! plpgsql_append_source_text(&ds, startlocation, yylloc.begins);
/* trim any trailing whitespace, for neatness */
while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
*************** read_datatype(int tok)
*** 2476,2482 ****
if (tok == YYEMPTY)
tok = yylex();
! startlocation = yylloc;
/*
* If we have a simple or composite identifier, check for %TYPE
--- 2476,2482 ----
if (tok == YYEMPTY)
tok = yylex();
! startlocation = yylloc.begins;
/*
* If we have a simple or composite identifier, check for %TYPE
*************** read_datatype(int tok)
*** 2557,2563 ****
/* set up ds to contain complete typename text */
initStringInfo(&ds);
! plpgsql_append_source_text(&ds, startlocation, yylloc);
type_name = ds.data;
if (type_name[0] == '\0')
--- 2557,2563 ----
/* set up ds to contain complete typename text */
initStringInfo(&ds);
! plpgsql_append_source_text(&ds, startlocation, yylloc.begins);
type_name = ds.data;
if (type_name[0] == '\0')
*************** make_execsql_stmt(int firsttoken, int lo
*** 2608,2614 ****
prev_tok = tok;
tok = yylex();
if (have_into && into_end_loc < 0)
! into_end_loc = yylloc; /* token after the INTO part */
if (tok == ';')
break;
if (tok == 0)
--- 2608,2614 ----
prev_tok = tok;
tok = yylex();
if (have_into && into_end_loc < 0)
! into_end_loc = yylloc.begins; /* token after the INTO part */
if (tok == ';')
break;
if (tok == 0)
*************** make_execsql_stmt(int firsttoken, int lo
*** 2619,2625 ****
if (have_into)
yyerror("INTO specified more than once");
have_into = true;
! into_start_loc = yylloc;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
read_into_target(&rec, &row, &have_strict);
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
--- 2619,2625 ----
if (have_into)
yyerror("INTO specified more than once");
have_into = true;
! into_start_loc = yylloc.begins;
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_NORMAL;
read_into_target(&rec, &row, &have_strict);
plpgsql_IdentifierLookup = IDENTIFIER_LOOKUP_EXPR;
*************** make_execsql_stmt(int firsttoken, int lo
*** 2637,2646 ****
*/
plpgsql_append_source_text(&ds, location, into_start_loc);
appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
! plpgsql_append_source_text(&ds, into_end_loc, yylloc);
}
else
! plpgsql_append_source_text(&ds, location, yylloc);
/* trim any trailing whitespace, for neatness */
while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
--- 2637,2646 ----
*/
plpgsql_append_source_text(&ds, location, into_start_loc);
appendStringInfoSpaces(&ds, into_end_loc - into_start_loc);
! plpgsql_append_source_text(&ds, into_end_loc, yylloc.begins);
}
else
! plpgsql_append_source_text(&ds, location, yylloc.begins);
/* trim any trailing whitespace, for neatness */
while (ds.len > 0 && scanner_isspace(ds.data[ds.len - 1]))
*************** make_return_stmt(int location)
*** 2847,2853 ****
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning set"),
errhint("Use RETURN NEXT or RETURN QUERY."),
! parser_errposition(yylloc)));
}
else if (plpgsql_curr_compile->out_param_varno >= 0)
{
--- 2847,2853 ----
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning set"),
errhint("Use RETURN NEXT or RETURN QUERY."),
! parser_errposition(yylloc.begins)));
}
else if (plpgsql_curr_compile->out_param_varno >= 0)
{
*************** make_return_stmt(int location)
*** 2855,2861 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function with OUT parameters"),
! parser_errposition(yylloc)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
--- 2855,2861 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function with OUT parameters"),
! parser_errposition(yylloc.begins)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else if (plpgsql_curr_compile->fn_rettype == VOIDOID)
*************** make_return_stmt(int location)
*** 2864,2870 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning void"),
! parser_errposition(yylloc)));
}
else if (plpgsql_curr_compile->fn_retistuple)
{
--- 2864,2870 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN cannot have a parameter in function returning void"),
! parser_errposition(yylloc.begins)));
}
else if (plpgsql_curr_compile->fn_retistuple)
{
*************** make_return_stmt(int location)
*** 2882,2895 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN must specify a record or row variable in function returning row"),
! parser_errposition(yylloc)));
break;
default:
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN must specify a record or row variable in function returning row"),
! parser_errposition(yylloc)));
break;
}
if (yylex() != ';')
--- 2882,2895 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN must specify a record or row variable in function returning row"),
! parser_errposition(yylloc.begins)));
break;
default:
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN must specify a record or row variable in function returning row"),
! parser_errposition(yylloc.begins)));
break;
}
if (yylex() != ';')
*************** make_return_next_stmt(int location)
*** 2931,2937 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
! parser_errposition(yylloc)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else if (plpgsql_curr_compile->fn_retistuple)
--- 2931,2937 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT cannot have a parameter in function with OUT parameters"),
! parser_errposition(yylloc.begins)));
new->retvarno = plpgsql_curr_compile->out_param_varno;
}
else if (plpgsql_curr_compile->fn_retistuple)
*************** make_return_next_stmt(int location)
*** 2946,2959 ****
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
! parser_errposition(yylloc)));
break;
default:
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
! parser_errposition(yylloc)));
break;
}
if (yylex() != ';')
--- 2946,2959 ----
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
! parser_errposition(yylloc.begins)));
break;
default:
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("RETURN NEXT must specify a record or row variable in function returning row"),
! parser_errposition(yylloc.begins)));
break;
}
if (yylex() != ';')
*************** read_into_target(PLpgSQL_rec **rec, PLpg
*** 3087,3118 ****
case T_DATUM:
if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW)
{
! check_assignable(yylval.wdatum.datum, yylloc);
*row = (PLpgSQL_row *) yylval.wdatum.datum;
if ((tok = yylex()) == ',')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("record or row variable cannot be part of multiple-item INTO list"),
! parser_errposition(yylloc)));
plpgsql_push_back_token(tok);
}
else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
{
! check_assignable(yylval.wdatum.datum, yylloc);
*rec = (PLpgSQL_rec *) yylval.wdatum.datum;
if ((tok = yylex()) == ',')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("record or row variable cannot be part of multiple-item INTO list"),
! parser_errposition(yylloc)));
plpgsql_push_back_token(tok);
}
else
{
*row = read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
! yylval.wdatum.datum, yylloc);
}
break;
--- 3087,3118 ----
case T_DATUM:
if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW)
{
! check_assignable(yylval.wdatum.datum, yylloc.begins);
*row = (PLpgSQL_row *) yylval.wdatum.datum;
if ((tok = yylex()) == ',')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("record or row variable cannot be part of multiple-item INTO list"),
! parser_errposition(yylloc.begins)));
plpgsql_push_back_token(tok);
}
else if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
{
! check_assignable(yylval.wdatum.datum, yylloc.begins);
*rec = (PLpgSQL_rec *) yylval.wdatum.datum;
if ((tok = yylex()) == ',')
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("record or row variable cannot be part of multiple-item INTO list"),
! parser_errposition(yylloc.begins)));
plpgsql_push_back_token(tok);
}
else
{
*row = read_into_scalar_list(NameOfDatum(&(yylval.wdatum)),
! yylval.wdatum.datum, yylloc.begins);
}
break;
*************** read_into_scalar_list(char *initial_name
*** 3151,3170 ****
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many INTO variables specified"),
! parser_errposition(yylloc)));
tok = yylex();
switch (tok)
{
case T_DATUM:
! check_assignable(yylval.wdatum.datum, yylloc);
if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("\"%s\" is not a scalar variable",
NameOfDatum(&(yylval.wdatum))),
! parser_errposition(yylloc)));
fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
varnos[nfields++] = yylval.wdatum.datum->dno;
break;
--- 3151,3170 ----
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("too many INTO variables specified"),
! parser_errposition(yylloc.begins)));
tok = yylex();
switch (tok)
{
case T_DATUM:
! check_assignable(yylval.wdatum.datum, yylloc.begins);
if (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("\"%s\" is not a scalar variable",
NameOfDatum(&(yylval.wdatum))),
! parser_errposition(yylloc.begins)));
fieldnames[nfields] = NameOfDatum(&(yylval.wdatum));
varnos[nfields++] = yylval.wdatum.datum->dno;
break;
*************** read_cursor_args(PLpgSQL_var *cursor, in
*** 3394,3400 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has no arguments",
cursor->refname),
! parser_errposition(yylloc)));
if (tok != until)
yyerror("syntax error");
--- 3394,3400 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has no arguments",
cursor->refname),
! parser_errposition(yylloc.begins)));
if (tok != until)
yyerror("syntax error");
*************** read_cursor_args(PLpgSQL_var *cursor, in
*** 3408,3414 ****
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has arguments",
cursor->refname),
! parser_errposition(yylloc)));
/*
* Read expressions until the matching ')'.
--- 3408,3414 ----
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("cursor \"%s\" has arguments",
cursor->refname),
! parser_errposition(yylloc.begins)));
/*
* Read expressions until the matching ')'.
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index 76e8436..7f18560 100644
*** a/src/pl/plpgsql/src/pl_scanner.c
--- b/src/pl/plpgsql/src/pl_scanner.c
*************** plpgsql_yylex(void)
*** 283,289 ****
push_back_token(tok3, &aux3);
push_back_token(tok2, &aux2);
if (plpgsql_parse_word(aux1.lval.str,
! core_yy.scanbuf + aux1.lloc,
&aux1.lval.wdatum,
&aux1.lval.word))
tok1 = T_DATUM;
--- 283,289 ----
push_back_token(tok3, &aux3);
push_back_token(tok2, &aux2);
if (plpgsql_parse_word(aux1.lval.str,
! core_yy.scanbuf + aux1.lloc.begins,
&aux1.lval.wdatum,
&aux1.lval.word))
tok1 = T_DATUM;
*************** plpgsql_yylex(void)
*** 304,310 ****
/* not A.B, so just process A */
push_back_token(tok2, &aux2);
if (plpgsql_parse_word(aux1.lval.str,
! core_yy.scanbuf + aux1.lloc,
&aux1.lval.wdatum,
&aux1.lval.word))
tok1 = T_DATUM;
--- 304,310 ----
/* not A.B, so just process A */
push_back_token(tok2, &aux2);
if (plpgsql_parse_word(aux1.lval.str,
! core_yy.scanbuf + aux1.lloc.begins,
&aux1.lval.wdatum,
&aux1.lval.word))
tok1 = T_DATUM;
*************** internal_yylex(TokenAuxData *auxdata)
*** 356,362 ****
yyscanner);
/* remember the length of yytext before it gets changed */
! yytext = core_yy.scanbuf + auxdata->lloc;
auxdata->leng = strlen(yytext);
/* Check for << >> and #, which the core considers operators */
--- 356,362 ----
yyscanner);
/* remember the length of yytext before it gets changed */
! yytext = core_yy.scanbuf + auxdata->lloc.begins;
auxdata->leng = strlen(yytext);
/* Check for << >> and #, which the core considers operators */
*************** plpgsql_scanner_errposition(int location
*** 464,470 ****
void
plpgsql_yyerror(const char *message)
{
! char *yytext = core_yy.scanbuf + plpgsql_yylloc;
if (*yytext == '\0')
{
--- 464,470 ----
void
plpgsql_yyerror(const char *message)
{
! char *yytext = core_yy.scanbuf + plpgsql_yylloc.begins;
if (*yytext == '\0')
{
*************** plpgsql_yyerror(const char *message)
*** 472,478 ****
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is typically the translation of "syntax error" */
errmsg("%s at end of input", _(message)),
! plpgsql_scanner_errposition(plpgsql_yylloc)));
}
else
{
--- 472,478 ----
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: %s is typically the translation of "syntax error" */
errmsg("%s at end of input", _(message)),
! plpgsql_scanner_errposition(plpgsql_yylloc.begins)));
}
else
{
*************** plpgsql_yyerror(const char *message)
*** 488,494 ****
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: first %s is typically the translation of "syntax error" */
errmsg("%s at or near \"%s\"", _(message), yytext),
! plpgsql_scanner_errposition(plpgsql_yylloc)));
}
}
--- 488,494 ----
(errcode(ERRCODE_SYNTAX_ERROR),
/* translator: first %s is typically the translation of "syntax error" */
errmsg("%s at or near \"%s\"", _(message), yytext),
! plpgsql_scanner_errposition(plpgsql_yylloc.begins)));
}
}
[text/x-python] normalization_regression.py (38.6K, ../../[email protected]/3-normalization_regression.py)
download | inline:
#!/usr/bin/env python
# Regression tests for pg_stat_statements normalization
# Peter Geoghegan
# Any sort of concurrency can be expected to break these
# regression tests, as they rely on the number of tuples
# in the pg_stat_statements view not changing due to
# external factors
# I assume that the dellstore 2 dump has been restored
# to the postgres database
# http://pgfoundry.org/forum/forum.php?forum_id=603
import psycopg2
test_no = 1
def print_queries(conn):
print "Queries that were found in pg_stat_statements: "
cur = conn.cursor()
cur.execute("select query from pg_stat_statements;")
for i in cur:
print i[0]
def demonstrate_buffer_limitation(conn):
# It's expected that comparing a number of sufficiently large queries will result
# in their incorrectly being considered equivalent provided the differences occur
# after we run out of space to selectively serialize to in our buffer.
set_operations = ['union', 'union all', 'except' ]
for it, i in enumerate(["select 1,2,3,4",
"select upper(lower(upper(lower(initcap(lower('Foo'))))))",
"select count(*) from orders o group by orderid" ]):
long_query = ""
long_long_query = ""
for j in range(0,100):
long_query += i + (' ' + set_operations[it] + ' \n' if j != 99 else " ")
for j in range(0,1000):
long_long_query += i + (' ' + set_operations[it] + ' \n' if j != 999 else " ")
print long_query
# Ideally, this test would fail, but it doesn't
verify_statement_equivalency(long_query, long_long_query, conn, "Differences out of range (iteration {0})".format(it + 1))
def verify_statement_equivalency(sql, equiv, conn, test_name = None, cleanup_sql = None):
# Run both queries in isolation and verify that there
# is only a single tuple
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(equiv)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(
"select count(*) from pg_stat_statements where query not ilike '%pg_stat_statements%' {0};".format(
"" if cleanup_sql is None else "and query != '{0}'".format(cleanup_sql))
)
for i in cur:
tuple_n = i[0]
if tuple_n != 1:
raise SystemExit("""The SQL statements \n'{0}'\n and \n'{1}'\n do not appear to be equivalent!
Test {2} failed.""".format(sql, equiv, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)) )
print """The statements \n'{0}'\n and \n'{1}'\n are equivalent, as expected.
Test {2} passed.\n\n""".format(sql, equiv, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
test_no +=1
def verify_statement_differs(sql, diff, conn, test_name = None, cleanup_sql = None):
# Run both queries in isolation and verify that there are
# two tuples
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(diff)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(
"select count(*) from pg_stat_statements where query not ilike '%pg_stat_statements%' {0};".format(
"" if cleanup_sql is None else "and query != '{0}'".format(cleanup_sql))
)
for i in cur:
tuple_n = i[0]
if tuple_n != 2:
raise SystemExit("""The SQL statements \n'{0}'\n and \n'{1}'\n do not appear to be different!
Test {2} failed.""".format(sql, diff, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)))
print """The statements \n'{0}'\n and \n'{1}'\n are not equivalent, as expected.
Test {2} passed.\n\n """.format(sql, diff, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
test_no +=1
def verify_normalizes_correctly(sql, norm_sql, conn, test_name = None):
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
ver_exists = "select exists(select 1 from pg_stat_statements where query = %s);"
cur.execute(ver_exists, (norm_sql, ) )
for i in cur:
exists = i[0]
if exists:
print """The SQL \n'{0}'\n normalizes to \n'{1}'\n , as expected.
Test {2} passed.\n\n """.format(sql, norm_sql, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
else:
raise SystemExit("""The SQL statement \n'{0}'\n does not normalize to \n '{1}'\n , which is not expected!
Test {2} failed.""".format(sql, norm_sql, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)))
test_no +=1
def main():
conn = psycopg2.connect("")
# Just let exceptions propagate
verify_statement_equivalency("select '5'::integer;", "select '17'::integer;", conn)
verify_statement_equivalency("select 1;", "select 5 ;", conn)
verify_statement_equivalency("select 'foo'::text;", "select 'bar'::text;", conn)
# Date constant normalization
verify_statement_equivalency("select * from orders where orderdate = '2001-01-01';" ,"select * from orders where orderdate = '1960-01-01'", conn)
verify_statement_equivalency("select '5'::integer;","select '17'::integer;", conn)
# Test equivalency of cast syntaxes:
verify_statement_equivalency("select '5'::integer;","select integer '5'", conn)
# We don't care about whitespace or differences in constants:
verify_statement_equivalency(
"select o.orderid from orders o join orderlines ol on o.orderid = ol.orderid where customerid = 12345 ;",
"select o.orderid from orders o join orderlines ol on o.orderid = ol.orderid where customerid = 6789;", conn)
# using clause matters:
verify_statement_differs(
"select o.orderid from orders o join orders oo using (orderid);",
"select o.orderid from orders o join orders oo using (customerid);", conn)
# "select * from " and "select <enumerate columns> from " equivalency:
verify_statement_equivalency("select * from orders", "select orderid, orderdate, customerid, netamount, tax, totalamount from orders;", conn)
# The equivalency only holds if you happen to enumerate columns in the exact same order though:
verify_statement_differs("select * from orders", "select orderid, orderdate, customerid, tax, netamount, totalamount from orders", conn)
# columns must match:
verify_statement_differs("select customerid from orders", "select orderid from orders", conn)
# We haven't really resolved the types of these values, so they're actually equivalent:
verify_statement_equivalency("select 1;", "select 1000000000;", conn)
# However, these are not:
verify_statement_differs("select 1::integer", "select 1000000000::bigint", conn)
# Types must match - types aren't resolved here, but they are partially resolved:
verify_statement_differs("select 5", "select 'foo'", conn)
# Join Qual differences matter:
verify_statement_differs("select * from orders o join orderlines ol on o.orderid = ol.orderid;",
"select * from orders o join orderlines ol on o.orderid = 5;", conn)
# Although differences in Join Qual constants do not:
verify_statement_equivalency("select * from orders o join orderlines ol on o.orderid = 66;",
"select * from orders o join orderlines ol on o.orderid = 5;", conn)
# Constants may vary here:
verify_statement_equivalency("select orderid from orders where orderid = 5 and 1=1;",
"select orderid from orders where orderid = 7 and 3=3;", conn)
# Different logical operator means different query though:
verify_statement_differs("select orderid from orders where orderid = 5 and 1=1;",
"select orderid from orders where orderid = 7 or 3=3;", conn)
# don't mistake the same column number (MyVar->varno) from different tables:
verify_statement_differs("select a.orderid from orders a join orderlines b on a.orderid = b.orderlineid",
"select b.orderlineid from orders a join orderlines b on a.orderid = b.orderlineid", conn)
# Note that these queries are considered equivalent, though you could argue that they shouldn't be.
# This is because they have the same range table entry. I could look at aliases and differentiate
# them that way, but I'm reasonably convinced that to do so would be a mistake. This is a feature,
# not a bug.
verify_statement_equivalency("select a.orderid from orders a join orders b on a.orderid = b.orderid",
"select b.orderid from orders a join orders b on a.orderid = b.orderid", conn)
# Boolean Test node:
verify_statement_differs(
"select orderid from orders where orderid = 5 and (1=1) is true;",
"select orderid from orders where orderid = 5 and (1=1) is not true;",
conn)
verify_statement_equivalency(
"values(1, 2, 3);",
"values(4, 5, 6);", conn)
verify_statement_differs(
"values(1, 2, 3);",
"values(4, 5, 6, 7);", conn)
verify_statement_equivalency(
"select * from (values(1, 2, 3)) as v;",
"select * from (values(4, 5, 6)) as v;", conn)
verify_statement_differs(
"select * from (values(1, 2, 3)) as v;",
"select * from (values(4, 5, 6, 7)) as v;", conn)
# Coalesce
verify_statement_equivalency("select coalesce(orderid, null, null) from orders where orderid = 5 and 1=1;",
"select coalesce(orderid, 5, 5) from orders where orderid = 7 and 3=3;", conn)
verify_statement_differs("select coalesce(orderid, 5, 5, 6 ) from orders where orderid = 5 and 1=1;",
"select coalesce(orderid, 5, 5) from orders where orderid = 7 and 3=3;", conn)
# Observe what we can do with noise words (no "outer" in later statement, plus we use AS in the second query):
verify_statement_equivalency("select * from orders o left outer join orderlines ol on o.orderid = ol.orderid;",
"select * from orders AS o left join orderlines AS ol on o.orderid = ol.orderid;", conn)
# Join order in statement matters:
verify_statement_differs("select * from orderlines ol join orders o on o.orderid = ol.orderid;",
"select * from orders o join orderlines ol on o.orderid = ol.orderid;", conn)
# Join strength/type matters:
verify_statement_differs("select * from orderlines ol inner join orders o on o.orderid = ol.orderid;",
"select * from orderlines ol left outer join orders o on o.orderid = ol.orderid;", conn)
# ExprNodes can be processed recursively:
verify_statement_differs(
"select upper(lower(upper(lower (initcap(lower('Foo'))))));",
"select upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_equivalency(
"select upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select upper(lower(upper(lower(initcap(lower('Bar'))))));",
conn)
# Do same again, but put function in FROM
verify_statement_differs(
"select * from upper(lower(upper(lower (initcap(lower('Foo'))))));",
"select * from upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_equivalency(
"select * from upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select * from upper(lower(upper(lower(initcap(lower('Bar'))))));",
conn)
# In the where clause too:
verify_statement_equivalency(
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('FOOFofofo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 'foo' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('FOOFofofo'))))));",
conn)
verify_statement_equivalency(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
"select 1 from orders where 1=2 and 'feew' = 'fi' or 'bar' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
"select 1 from orders where 1=2 and 'feew' = 'fi' or 'bar' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is not null;",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
"select 1 from orders where 1=55 and 'foo' = 'fi' or not upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
conn)
# Nested BoolExpr is a differentiator:
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
"select 1 from orders where 1=55 and 'foo' = 'fi' and 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
conn)
# For aggregates too
verify_statement_differs(
"select array_agg(lower(upper(initcap(initcap(lower('Foo')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower('Bar')))))) from orders;",
conn)
verify_statement_equivalency(
"select array_agg(lower(upper(lower(initcap(lower('Baz')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower('Bar')))))) from orders;",
conn)
# Row-wise comparison
verify_statement_differs(
"select (1, 2) < (3, 4);",
"select ('a', 'b') < ('c', 'd');",
conn)
verify_statement_differs(
"select (1, 2, 3) < (3, 4, 5);",
"select (1, 2) < (3, 4);",
conn)
verify_statement_equivalency(
"select (1, 2, 3) < (3, 4, 5);",
"select (3, 4, 5) < (1, 2, 3);",
conn)
# Use lots of different operators:
verify_statement_differs(
"select 1 < 2;",
"select 1 <= 2;",
conn)
verify_statement_differs(
"select ARRAY[1,2,3]::integer[] && ARRAY[1]::integer[];",
"select ARRAY[1,2,3]::integer[] <@ ARRAY[1]::integer[];",
conn)
# Number of elements in ARRAY[] expression is a differentiator:
verify_statement_differs(
"select ARRAY[1,2,3]::integer[] <@ ARRAY[1]::integer[];",
"select ARRAY[999]::integer[] <@ ARRAY[342, 543, 634 ,753]::integer[];",
conn)
# Array coercion
verify_statement_equivalency(
"select '{1,2,3}'::oid[]::integer[] from orders;",
"select '{4,5,6}'::oid[]::integer[] from orders;",
conn)
# array subscripting operations
verify_statement_equivalency(
"select (array_agg(lower(upper(lower(initcap(lower('Baz')))))))[5:5] from orders;",
"select (array_agg(lower(upper(lower(initcap(lower('Bar')))))))[6:6] from orders;",
conn)
verify_statement_differs(
"select (array_agg(lower(upper(lower(initcap(lower('Baz')))))))[5:5] from orders;",
"select (array_agg(lower(upper(lower(initcap(lower('Bar')))))))[6] from orders;",
conn)
# nullif, represented as a distinct node but actually just a typedef
verify_statement_differs(
"select *, (select customerid from orders limit 1), nullif(5,10) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select customerid from orders limit 1), nullif('a','b') from orderlines ol join orders o on o.orderid = ol.orderid;",
conn)
verify_statement_equivalency(
"select *, (select customerid from orders limit 1), nullif(5,10) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select customerid from orders limit 1), nullif(10,15) from orderlines ol join orders o on o.orderid = ol.orderid;",
conn)
# Row constructor
verify_statement_differs(
"select row(1, 2,'this is a test');",
"select row(1, 2.5,'this is a test');",
conn)
# XML Stuff
verify_statement_differs(
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.datname as "name"),
xmlforest(
pg_database_size(d.datname) as size,
xact_commit,
xact_rollback,
blks_read,
blks_hit,
tup_fetched,
tup_returned,
tup_inserted,
tup_updated,
tup_deleted
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
"""
,
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.datname as "name"),
xmlforest(
pg_database_size(d.datname) as size,
xact_commit,
xact_rollback,
blks_read,
blks_hit,
tup_fetched,
tup_returned,
tup_updated,
tup_deleted
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
""",
conn)
verify_statement_differs(
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.blks_hit as "name"),
xmlforest(
pg_database_size(d.datname) as size
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
"""
,
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.blks_read as "name"),
xmlforest(
pg_database_size(d.datname) as size
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
""",
conn)
# subqueries
# in select list
verify_statement_differs("select *, (select customerid from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select orderid from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# select list nested subselection - inner most types differ
verify_statement_differs(
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select (select 1::bigint from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# This time, they're the same
verify_statement_equivalency(
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# in from - this particular set of queries entail recursive JoinExprNode() calls
verify_statement_differs(
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid a from orders) as t on ol.orderid=t.a;",
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid, customerid a from orders) as t on ol.orderid = t.a;", conn)
# another in from - entails recursive JoinExprNode() call
verify_statement_equivalency(
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid a from orders where orderid = 77) as t on ol.orderid=t.a;",
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid b from orders where orderid = 5) as t on ol.orderid = t.b;", conn)
# Even though these two queries will result in the same plan, they are not yet equivalent - they are not
# semantically equivalent, as least by our standard. We could probably figure out a way of having the
# equivalency recognized, but I highly doubt it's worth bothering, since recognizing most kinds of semantic
# equivalence is generally more of a neat consequence of our implementation than a practical feature:
verify_statement_differs("select * from orderlines ol inner join orders o on o.orderid = ol.orderid;",
"select * from orderlines ol, orders o where o.orderid = ol.orderid;", conn)
# Aggregate group by normalisation:
verify_statement_differs("select count(*) from orders o group by orderid;",
"select count(*) from orders o group by customerid;", conn)
# Which aggregate was called matters
verify_statement_differs("select sum(customerid) from orders o group by orderid;",
"select avg(customerid) from orders o group by orderid;", conn)
# As does the order of aggregates
verify_statement_differs("select sum(customerid), avg(customerid) from orders o group by orderid;",
"select avg(customerid), sum(customerid) from orders o group by orderid;", conn)
# As does the having clause
verify_statement_equivalency(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 50;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 1000;",
conn)
# operator in having clause matters
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) = 100;",
conn)
# as does datatype
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100::bigint;",
conn)
verify_statement_equivalency(
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 100;",
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 15450;",
conn)
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 100;",
conn)
# columns order in "order by" matters:
verify_statement_differs(
"select * from orders o join orderlines ol on o.orderid = ol.orderid order by o.orderdate, o.orderid, customerid, netamount, totalamount, tax ;",
"select * from orders o join orderlines ol on o.orderid = ol.orderid order by o.orderdate, o.orderid, customerid, netamount, tax, totalamount;", conn)
# distinct on is a differentiator:
verify_statement_differs("select distinct on(customerid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select distinct on(o.orderid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# both the "on" value and the absence or presence of the clause:
verify_statement_differs("select distinct on(customerid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# select "all" is generally just a noise word:
verify_statement_equivalency("select all customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# Updates are similarly normalised, and their internal representations shares much with select statements
verify_statement_equivalency("update orders set orderdate='2011-01-06' where orderid=3;",
"update orders set orderdate='1992-01-06' where orderid = 10;", conn)
# updates with different columns are not equivalent:
verify_statement_differs("update orders set orderdate='2011-01-06' where orderid = 3;",
"update orders set orderdate='1992-01-06' where customerid = 10;", conn)
# default within update statement
verify_statement_equivalency(
"update products set special=default where prod_id = 7;",
"update products set special=default where prod_id = 10;",
conn)
# select into
verify_statement_equivalency(
"select * into orders_recent FROM orders WHERE orderdate >= '2002-01-01';",
"select * into orders_recent FROM orders WHERE orderdate >= '2010-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
verify_statement_differs(
"select * into orders_recent FROM orders WHERE orderdate >= '2002-01-01';",
"select * into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
verify_statement_differs(
"select orderdate into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
"select orderid into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
# Here, name of new relation matters:
verify_statement_differs(
"select * into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
"select * into orders_recent2 FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent; drop table if exists orders_recent2;", conn = conn)
# CTE
verify_statement_differs(
"with a as (select customerid from orders ), b as (select 'foo') select orderid from orders",
"with a as (select customerid from orders ), b as (select 1) select orderid from orders",
conn)
# temporary column name within recursive CTEs doesn't differentiate
verify_statement_equivalency(
"""
with recursive j(n) AS (
values (1)
union all
select n + 1 from j where n < 100
)
select avg(n) from j;
""",
"""
with recursive k(n) AS (
values (1)
union all
select n + 1 from k where n < 50
)
select avg(n) from k;
""",
conn)
# set operation normalization occurs by walking the query tree recursively.
verify_statement_differs( "select orderid from orders union all select customerid from orders", "select customerid from orders union all select orderid from orders", conn)
verify_statement_equivalency(
"select 1, 2, 3 except select orderid, 6, 7 from orders",
"select 4, 5, 6 except select orderid, 55, 33 from orders",
conn)
verify_statement_differs(
"select orderid, 6 from orders union select 1,2 ",
"select 55, orderid from orders union select 4,5 ",
conn,
"column order differs (left child)")
verify_statement_differs(
"select 1, 2 union select orderid, 6 from orders",
"select 4, 5 union select 55, orderid from orderlines",
conn,
"column order differs (right child easy)")
verify_statement_differs(
"select 1, 2 union select orderid, 6 from orders",
"select 4, 5 union select 55, orderid from orders",
conn,
"column order differs (right child)")
# union != union all
verify_statement_differs(
"select customerid from orders union all select customerid from orders",
"select customerid from orders union select customerid from orders",
conn, "union != union all")
verify_statement_equivalency(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68;
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select orderid, 73737, 4235 from orderlines
intersect
select 5432, 6667,6337;
""",
conn)
verify_statement_differs(
"select orderid from orders union all select customerid from orders",
"select customerid from orders union all select orderid from orders",
conn)
verify_statement_differs(
"select 1::integer union all select orderid from orders union all select customerid from orders",
"select customerid from orders union all select orderid from orders", conn)
# My attempt to isolate the set operation problem.
# test passes if there is one less select,
# even if it'si an int, or if there's
# one more "select 1"
verify_statement_differs(
"""
select 1
union
select (current_date - orderdate + 5 + 6 + 7 + 8) from orderlines
union
select 1;
""",
"""
select 1
union
select orderid from orders
union
select 1;
""",
conn, "isolate set operations problem")
# Same as above, but the one table is different
verify_statement_differs(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68;
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select orderid, 73737, 4235 from orders
intersect
select 5432, 6667,6337;
""",
conn, "one table is different")
# Same as original, but I've switched a column reference with a constant in
# the second query
verify_statement_differs(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select 73737, orderid, 4235 from orderlines
intersect
select 5432, 6667,6337
""",
conn)
# The left node in the set operation tree matches for before and after; we should still catch that
verify_statement_differs(
"""
select orderid from orders
union all
select customerid from orders
union all
select customerid from orders
""",
"""
select orderid from orders
union all
select orderid from orders
union all
select customerid from orders
""", conn)
verify_statement_differs(
"""
select orderid, customerid from orders
union
select orderid, customerid from orders
order by orderid
""",
"""
select orderid, customerid from orders
union
select orderid, customerid from orders
order by customerid
""", conn)
verify_statement_differs(
"""
with recursive j(n) AS (
values (1)
union all
select n + 1 from j where n < 100
)
select avg(n) from j;
""",
"""
with recursive j(n) AS (
values (1)
union all
select 1 from orders
)
select avg(n) from j;
""",
conn)
# Excercise some less frequently used Expr nodes
verify_statement_equivalency(
"""
select
case orderid
when 0 then 'zero'
when 1 then 'one'
else 'some other number' end
from orders
""",
""" select
case orderid
when 5 then 'five'
when 6 then 'six'
else 'some other number' end
from orders
""", conn)
verify_statement_differs(
"""
select
case orderid
when 0 then 'zero'
else 'some other number' end
from orders
""",
""" select
case orderid
when 5 then 'five'
when 6 then 'six'
else 'some other number' end
from orders
""", conn)
# Counter-intuitively, these two statements are equivalent...
verify_statement_equivalency(
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one'
else 'other number' end
from orders
""",
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one' end
from orders
""", conn, "Case when test")
# ...this is because no else clause is actually equivalent to "else NULL".
verify_statement_equivalency(
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one'
else 'other number' end
from orders
""",
"""
select
case when orderid = 5
then 'five'
when orderid = 6
then 'six'
else 'some other number' end
from orders
""", conn, "second case when test")
verify_statement_differs( "select min(orderid) from orders", "select max(orderid) from orders", conn, "min not max check")
# The parser uses a dedicated Expr node to handle greatest()/least()
verify_statement_differs( "select greatest(1,2,3) from orders", "select least(1,2,3) from orders", conn, "greatest/least differ check")
# Window functions
verify_statement_differs(
"select sum(netamount) over () from orders",
"select sum(tax) over () from orders",
conn, "window function column check")
verify_statement_differs(
"select sum(netamount) over (partition by customerid) from orders",
"select sum(netamount) over (partition by orderdate) from orders",
conn, "window function over column differs check")
verify_statement_differs(
"select sum(netamount) over (partition by customerid order by orderid) from orders",
"select sum(netamount) over (partition by customerid order by tax) from orders",
conn, "window function over column differs check")
verify_statement_differs(
"""
SELECT c.oid AS relid,
n.nspname AS schemaname,
c.relname
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indrelid
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
LEFT JOIN pg_class x ON t.reltoastidxid = x.oid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])
GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
"""
,
"""
SELECT c.oid AS relid,
n.nspname AS schemaname,
c.relname
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indrelid
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
LEFT JOIN pg_class x ON t.reltoastidxid = x.oid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'v'::"char"])
GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
"""
,conn, "number of ARRAY elements varies in ANY() in where clause")
# problematic query
verify_statement_equivalency(
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','d','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
conn)
verify_statement_differs(
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','d','x', 'd'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
conn)
# Don't confuse functions and function-like dedicated ExprNodes, or pairs of
# function-like dedicated ExprNodes
# I'd speculate that if this was performed with every ExprNode that resembles
# a function, it wouldn't actually fail, since there tends to be a good reason
# for having a dedicated though function-like ExprNode rather than just an
# SQL-callable function, and I'm naturally already serializing those differences
# as they're rather obviously essential to the query
# The concern here is a specific case of a more general one - that successive
# queries with similar ExprNodes could incorrectly be considered equivalent.
# NB:
# I consider the question of whether or not it is necessary to escape query-tree
# serializations (in a way that includes a magic number for the ExprNode, such as
# its offset in the NodeTag enum) to be an open one.
# Part of the difficulty is that OIDs cannot be expected to remain unique
# over time and across pg_* tables
verify_statement_differs(
"select coalesce(orderid) from orders;",
"select sum(orderid) from orders;",
conn, "Don't confuse functions/function like nodes")
verify_normalizes_correctly("select 1, 2, 3;", "select ?, ?, ?;", conn, "integer verification" )
verify_normalizes_correctly("select 'foo';", "select ?;", conn, "unknown/string normalization verification" )
verify_normalizes_correctly("select 'bar'::text;", "select ?::text;", conn, "text verification" )
verify_normalizes_correctly("select $$bar$$;", "select ?;", conn, "unknown/string normalization verification" )
verify_normalizes_correctly("select $$bar$$ from pg_database where datname = 'postgres';",
"select ? from pg_database where datname = ?;", conn, "Quals comparison" )
# You can parameterize a limit constant, so our behavior is consistent with that
verify_normalizes_correctly("select * from orders limit 1 offset 5;", "select * from orders limit ? offset ?;", conn, "integer verification" )
# Note: Due to :: operator precedence, this behavior is correct:
verify_normalizes_correctly("select -12345::integer;", "select -?::integer;", conn, "show operator precedence issue" )
verify_normalizes_correctly("select -12345;", "select ?;", conn, "show no operator precedence issue" )
verify_normalizes_correctly("select -12345.12345::float;", "select -?::float;", conn, "show operator precedence issue" )
verify_normalizes_correctly("select -12345.12345;", "select ?;", conn, "show no operator precedence issue" )
verify_normalizes_correctly("select array_agg(lower(upper(lower(initcap(lower('Baz')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower(?)))))) from orders;", conn, "Function call")
# Test this cast syntax works:
verify_normalizes_correctly("select timestamp without time zone '2009-05-05 15:34:24';",
"select timestamp without time zone ?;", conn, "excercise special handling, timestamp")
verify_normalizes_correctly("select timestamptz '2009-05-05 15:34:24.1234';",
"select timestamptz ?;", conn, "excercise special handling, timestamptz")
verify_normalizes_correctly("select date '2009-05-05';",
"select date ?;", conn, "excercise special handling, date")
verify_normalizes_correctly("select time '15:15:15';",
"select time ?;", conn, "excercise special handling, time")
verify_normalizes_correctly("select time with time zone '15:15:15';",
"select time with time zone ?;", conn, "excercise special handling, time with time zone")
verify_normalizes_correctly("select interval '1 hour';", "select interval ?;", conn, "excercise special handling, interval")
demonstrate_buffer_limitation(conn)
if __name__=="__main__":
main()
[text/x-python] performance_test.py (3.0K, ../../[email protected]/4-performance_test.py)
download | inline:
#!/usr/bin/env python
# Performance test for pg_stat_statements normalization
# Peter Geoghegan
# This test is intended to isolate the overhead of additional
# infrastructure in the grammar and plan tree, which is used to
# add a field to Const nodes so that the corresponding lexeme's
# length is known from the query tree.
# It is intended to be run without pg_stat_statements, because
# the really pertinent issue is if these changes impose any
# noticeable overhead on Postgres users that don't use
# pg_stat_statements, and the degree thereof.
# For best results, run with CPU frequency scaling disabled.
import psycopg2
import random
import time
import csv
from optparse import OptionParser
# store results of a given run in a dedicated csv file
def serialize_to_file(times, filename):
wrt = csv.writer(open(filename, 'wb'), delimiter=',')
# mark median run for runs of this
# query (or if there is an even number of elements, near enough)
median_i = (len(times) + 1) / 2 - 1
for i, v in enumerate(times):
wrt.writerow([ v[0], time.ctime(v[1]), str(v[2]) + " seconds", '*' if i == median_i else 'n'])
def run_test(conn, num_its, num_const_nodes):
# A very unsympathetic query here is one with lots of
# Const nodes that explain shows as a single "Result" node.
# This is because parsing has a large overhead
# relative to planning and execution, and there is an unusually
# high number of Const nodes.
# Use psuedo-random numbers with a consistent seed value - numbers
# used are deterministic for absolute consistency, though I don't
# believe that to be significant, at least for now.
random.seed(55)
cur = conn.cursor()
times = []
for i in range(0, num_its):
# Generate new query with psuedo-random integer Const nodes
qry = "select "
for i in range(0, num_const_nodes):
n = random.randint(0, 10000000)
qry += str(n) + (", " if i != num_const_nodes - 1 else ";")
begin = time.time()
cur.execute(qry)
end = time.time()
elapsed = end - begin
times.append((qry, begin, elapsed))
# Sort values for reference, and to locate the median value
sort_vals = sorted(times, key=lambda tot_time: tot_time[2])
serialize_to_file(sort_vals, "test_results.csv")
def main():
parser = OptionParser(description="")
parser.add_option('-c', '--conninfo', type=str, help="libpq-style connection info string of database to connect to. "
"Can be omitted, in which case we get details from our environment. "
"You'll probably want to put this in double-quotes, like this: --conninfo \"hostaddr=127.0.0.1 port=5432 dbname=postgres user=postgres\". ", default="")
parser.add_option('-n', '--num_its', type=int, help="Number of iterations (times a query is executed)", default=5000)
parser.add_option('-s', '--num_const_nodes', type=int, help="Number of Const nodes that each query contains", default=300)
args = parser.parse_args()[0]
conn_str = args.conninfo
num_its = args.num_its
num_const_nodes = args.num_const_nodes
conn = psycopg2.connect(conn_str)
run_test(conn, num_its, num_const_nodes)
if __name__=="__main__":
main()
^ permalink raw reply [nested|flat] 800+ messages in thread
* Re: pg_stat_statements with query tree based normalization
2011-12-07 01:19 Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
2011-12-10 13:56 ` Re: pg_stat_statements with query tree based normalization Greg Smith <[email protected]>
@ 2011-12-11 01:52 ` Peter Geoghegan <[email protected]>
2011-12-14 10:14 ` Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
0 siblings, 1 reply; 800+ messages in thread
From: Peter Geoghegan @ 2011-12-11 01:52 UTC (permalink / raw)
To: Greg Smith <[email protected]>; +Cc: pgsql-hackers
On 10 December 2011 13:56, Greg Smith <[email protected]> wrote:
> I heard about some bitrot creeping in here too, but it seems gone now; I had
> no problem merging Peter's development branch against master. I've attached
> a newer patch of the main code, which fixes most of the earlier issues there
> were disclaimers about.
I'm aware of some further bugs in the patch that Greg posted regarding
the synchronisation of executor and planner plugins, so please bear
with me while I squash them.
--
Peter Geoghegan http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training and Services
^ permalink raw reply [nested|flat] 800+ messages in thread
* Re: pg_stat_statements with query tree based normalization
2011-12-07 01:19 Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
2011-12-10 13:56 ` Re: pg_stat_statements with query tree based normalization Greg Smith <[email protected]>
2011-12-11 01:52 ` Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
@ 2011-12-14 10:14 ` Peter Geoghegan <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Peter Geoghegan @ 2011-12-14 10:14 UTC (permalink / raw)
To: Greg Smith <[email protected]>; +Cc: pgsql-hackers
The latest revision of the patch, along with latest revision of
regression tests are attached.
This patch handles synchronisation of the planner and executor
plugins. This was always going to be a problem, regardless of what
implementation was chosen (with the exception of plan hashing). I
think that the idea of hashing Plans themselves from an ExecutorEnd
hooked-in function, while interesting and probably worth pursuing at
some other point, is not a good match for pg_stat_statements today.
Any useful tool that did that would be orthogonal to what
pg_stat_statements is supposed to be - it would be affected by
completely external factors like planner cost constants. What would
the canonicalized representation of the query string look like then,
and how would that interact with the selectivity of constants,
particularly over time? What would the DBA's workflow be to isolate
poorly performing plans - how exactly is this tool useful? These are
questions that do not have simple answers, and the fact that I'm not
aware of a successful precedent makes me hesitant to sink too much
time into the idea just yet.
The other proposal that Tom had in the other thread, to directly hash
the raw parse tree, had a number of disadvantages to my mind. Firstly,
it prevents us from benefiting from additional normalisation performed
by the parser itself in later stages, like ignoring noise words.
Secondly, it prevents us from creating a less-complete version of this
that can be used with Postgres 8.4+ stock binaries. We therefore
cannot get field experience/ bug reports with the tool in advance of
the release of 9.2. Tom was pretty sceptical of this second reason.
However, I think that it's an issue of major concern to the PostgreSQL
community. For example, the immediate reaction of Depesz, writing on
pg_stat_statements when it was initially committed in 2009 was:
"To sum it up. I think that functionality of the module would be
greatly enhanced if it would store queries without parameters (instead
of “select 2 + 3″ -> “select $1 + $2″, or something like this) –
otherwise, with real-world databases, the buffer for queries will fill
up too soon, and it will not “catch” the fact that “select * from
table where id = 3″ and “select * from table where id = 23″ is
practically the same."
It would be great to have this functionality, but it would be even
better if we could get it to people today, rather than in a couple of
years time, assured by the fact that it is largely the same as the
pg_stat_statements that ships with 9.2. That was not the primary
consideration that informed the design of this patch though - I
genuinely thought that after the rewriting stage was the correct time
to hash the query tree, as it is at that point that it most accurately
reflects what the query will actually do without involving how it will
do it. This made good sense to me.
I'm now sometimes using a selective serialisation (or "jumble", as
I've termed it to reflect the fact that it is selective), and other
times using the query string instead. Basically, I'll only use a
jumble if:
* The query is not nested (i.e. it is directly issued by a client).
This generally isn't a problem as nested queries are almost always
prepared. The one case that this is a problem that I'm aware of is if
someone is dynamically executing SQL with SPI, using plpgsql's
execute, for example. However, that pattern already has plenty of
problems (It doesn't set FOUND, etc).
* We're not in legacy/compatibility mode (and we're not by default)
* The query is not prepared. It's not possible to synchronise Planner
and Executor hooks as things stand, at least not without adding
additional infrastructure and complex logic for keeping track of
things.
* The query is not a utility statement (including DECLARE CURSOR
statements) - It is a select, update, delete or insert.
You might find the fact that it serializes at this later stage
objectionable, because of the potential for that to interact with
things like search_path in ways that might not be appreciated - this
was something that I thought was an advantage. You might also find it
strange that it does one or the other. It might do this for some query
that is prepared but not another similar one, which is not prepared.
One solution to this could be to hash relationOids along with the
query string in pgss_ExecutorEnd for prepared queries. I don't think
this inconsistency is especially worth concerning ourselves with
though - a better solution might be to simply document it, as it isn't
hard to understand.
Likely other areas of concern with this patch are:
* My modifications to scan.l and to a lesser extent gram.y to
accommodate the new length field in Const nodes are not particularly
elegant. It would be useful to get an expert's input here. In
particular, note the strlen() calls within the SET_YYCCOC_LEN() macro.
It is unfortunate that by making the YYLTYPE representation closer to
that of the default (which has column and row positions for both the
start and end of lexemes), it reverberates further than I'd like,
including necessitating modifications to plpgsql, which is why the
patch is so large. It's a mostly mechanical change though.
* The fact that JUMBLE_SIZE is a compile time constant, whereas the
query size is not and has not been, which is important for the
purposes of determining query equivalency with large queries.
Basically, it's not quite obvious when you've run out of space to
store a query jumble, whereas it was obvious when that happens with
the query string.
* The possibility of two substantively different queries having the
same jumble, and therefore actually being considered equivalent. The
basic problem is that I'm not serialising NULL pointers - the
serialization logic is currently faulty. It's pretty simple to do this
with something like a binary tree, but I thought I'd get input here
before doing something better - it's probably possible to cheat and
not have to serialise every single NULL pointer, which would be quite
wasteful (consider the last bullet point), but I wouldn't like to
attempt that without input.
* Lack of documentation. The code is fairly heavily commented though.
--
Peter Geoghegan http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training and Services
Attachments:
[text/x-python] normalization_regression.py (41.9K, ../../CAEYLb_UC+D0VDJsNgjxwxCsta3GGyGfkwvRgCoZNvX=W3unRLw@mail.gmail.com/2-normalization_regression.py)
download | inline:
#!/usr/bin/env python
# Regression tests for pg_stat_statements normalization
# Peter Geoghegan
# Any sort of concurrency can be expected to break these
# regression tests, as they rely on the number of tuples
# in the pg_stat_statements view not changing due to
# external factors
# I assume that the dellstore 2 dump has been restored
# to the postgres database
# http://pgfoundry.org/forum/forum.php?forum_id=603
import psycopg2
test_no = 1
def do_post_mortem(conn):
print "Post-mortem:"
cur = conn.cursor()
cur.execute("select * from pg_stat_statements();")
for i in cur:
print i
print "\n"
def print_queries(conn):
print "Queries that were found in pg_stat_statements: "
cur = conn.cursor()
cur.execute("select query from pg_stat_statements;")
for i in cur:
print i[0]
def demonstrate_buffer_limitation(conn):
# It's expected that comparing a number of sufficiently large queries will result
# in their incorrectly being considered equivalent provided the differences occur
# after we run out of space to selectively serialize to in our buffer.
set_operations = ['union', 'union all', 'except' ]
for it, i in enumerate(["select 1,2,3,4",
"select upper(lower(upper(lower(initcap(lower('Foo'))))))",
"select count(*) from orders o group by orderid" ]):
long_query = ""
long_long_query = ""
for j in range(0,100):
long_query += i + (' ' + set_operations[it] + ' \n' if j != 99 else " ")
for j in range(0,1000):
long_long_query += i + (' ' + set_operations[it] + ' \n' if j != 999 else " ")
print long_query
# Ideally, this test would fail, but it doesn't
verify_statement_equivalency(long_query, long_long_query, conn, "Differences out of range (iteration {0})".format(it + 1))
def verify_statement_equivalency(sql, equiv, conn, test_name = None, cleanup_sql = None):
# Run both queries in isolation and verify that there
# is only a single tuple
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(equiv)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(
# Exclude both pg_stat_statements_reset() calls and foreign key enforcement queries
"""select count(*) from pg_stat_statements
where query not like '%pg_stat_statements_reset%'
and
query not like 'SELECT 1 FROM ONLY%'
{0};""".format(
"" if cleanup_sql is None else "and query != '{0}'".format(cleanup_sql))
)
for i in cur:
tuple_n = i[0]
if tuple_n != 1:
do_post_mortem(conn)
raise SystemExit("""The SQL statements \n'{0}'\n and \n'{1}'\n do not appear to be equivalent!
Test {2} failed.""".format(sql, equiv, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)) )
print """The statements \n'{0}'\n and \n'{1}'\n are equivalent, as expected.
Test {2} passed.\n\n""".format(sql, equiv, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
test_no +=1
def verify_statement_differs(sql, diff, conn, test_name = None, cleanup_sql = None):
# Run both queries in isolation and verify that there are
# two tuples
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(diff)
if cleanup_sql is not None:
cur.execute(cleanup_sql)
cur.execute(
# Exclude both pg_stat_statements_reset() calls and foreign key enforcement queries
"""select count(*) from pg_stat_statements
where query not like '%pg_stat_statements_reset%'
and
query not like 'SELECT 1 FROM ONLY%'
{0};""".format(
"" if cleanup_sql is None else "and query != '{0}'".format(cleanup_sql))
)
for i in cur:
tuple_n = i[0]
if tuple_n != 2:
do_post_mortem(conn)
raise SystemExit("""The SQL statements \n'{0}'\n and \n'{1}'\n do not appear to be different!
Test {2} failed.""".format(sql, diff, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)))
print """The statements \n'{0}'\n and \n'{1}'\n are not equivalent, as expected.
Test {2} passed.\n\n """.format(sql, diff, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
test_no +=1
def verify_normalizes_correctly(sql, norm_sql, conn, test_name = None):
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
cur.execute(sql)
ver_exists = "select exists(select 1 from pg_stat_statements where query = %s);"
cur.execute(ver_exists, (norm_sql, ) )
for i in cur:
exists = i[0]
if exists:
print """The SQL \n'{0}'\n normalizes to \n'{1}'\n , as expected.
Test {2} passed.\n\n """.format(sql, norm_sql, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no))
else:
do_post_mortem(conn)
raise SystemExit("""The SQL statement \n'{0}'\n does not normalize to \n '{1}'\n , which is not expected!
Test {2} failed.""".format(sql, norm_sql, test_no if test_name is None else "'{0}' ({1})".format( test_name, test_no)))
test_no +=1
# Test for bugs in synchronisation between planner and executor
def test_sync_issues(conn, count=5):
global test_no
cur = conn.cursor()
cur.execute("select pg_stat_statements_reset();")
# Note that the SQL in this plpgsql function is not paramaterized, so
# detecting that and hashing on string doesn't get the implementation
# off-the-hook:
spi_query = "update orders set orderid = 5 where orderid = 5"
cur.execute(""" create or replace function test() returns void as
$$begin {0};
end;$$ language plpgsql""".format(spi_query))
sql = "select test();"
for i in range(0, count):
cur.execute(sql)
# Plan caching will make the first call of the function above plan the sql statement after it plans the function call.
# This caused the assumption about their synchronisation to fall down in earlier revisions of the patch.
# Another concern is that we don't overwrite the jumble that is needed in the executor for an unnested
# query with a nested query's jumble
# pg_stat_statements.track is set to 'all', so we expect to see both the function call and the spi-executed query `count` times
cur.execute("select calls from pg_stat_statements where query = '{0}' order by calls;".format(sql));
for i in cur:
function_calls = i[0]
cur.execute("select calls from pg_stat_statements where query = '{0}' order by calls;".format(spi_query));
for i in cur:
spi_query_calls = i[0]
for i in (function_calls, spi_query_calls):
name = "function_calls" if i is function_calls else "spi_query_calls"
if i == count:
print "Planner/ Executor sync issue test (test {0}, '{1}') passed. actual calls: {2}".format(test_no, name, i)
else:
do_post_mortem(conn)
raise SystemExit("Planner/ Executor sync issue detected! Test {0} ('{1}') failed! (actual calls: {2}, reported: {3}".format(test_no, name, i, count))
test_no +=1
def main():
conn = psycopg2.connect("")
# Run all tests while tracking all statements (i.e. nested ones too, within
# functions). This is necessary for the test_sync_issues() test, but shouldn't
# otherwise matter. I suspect that it may usefully increase test coverage
# in some cases at some point in the code's development.
# cur = conn.cursor()
# cur.execute("set pg_stat_statements.track = 'all';")
## Start tests...just let exceptions propagate
# test_sync_issues(conn, 25)
verify_statement_equivalency("select '5'::integer;", "select '17'::integer;", conn)
verify_statement_equivalency("select 1;", "select 5 ;", conn)
verify_statement_equivalency("select 'foo'::text;", "select 'bar'::text;", conn)
# Date constant normalization
verify_statement_equivalency("select * from orders where orderdate = '2001-01-01';" ,"select * from orders where orderdate = '1960-01-01'", conn)
verify_statement_equivalency("select '5'::integer;","select '17'::integer;", conn)
# Test equivalency of cast syntaxes:
verify_statement_equivalency("select '5'::integer;","select integer '5'", conn)
# We don't care about whitespace or differences in constants:
verify_statement_equivalency(
"select o.orderid from orders o join orderlines ol on o.orderid = ol.orderid where customerid = 12345 ;",
"select o.orderid from orders o join orderlines ol on o.orderid = ol.orderid where customerid = 6789;", conn)
# using clause matters:
verify_statement_differs(
"select o.orderid from orders o join orders oo using (orderid);",
"select o.orderid from orders o join orders oo using (customerid);", conn)
# "select * from " and "select <enumerate columns> from " equivalency:
verify_statement_equivalency("select * from orders", "select orderid, orderdate, customerid, netamount, tax, totalamount from orders;", conn)
# The equivalency only holds if you happen to enumerate columns in the exact same order though:
verify_statement_differs("select * from orders", "select orderid, orderdate, customerid, tax, netamount, totalamount from orders", conn)
# columns must match:
verify_statement_differs("select customerid from orders", "select orderid from orders", conn)
# We haven't really resolved the types of these values, so they're actually equivalent:
verify_statement_equivalency("select 1;", "select 1000000000;", conn)
# However, these are not:
verify_statement_differs("select 1::integer", "select 1000000000::bigint", conn)
# Types must match - types aren't resolved here, but they are partially resolved:
verify_statement_differs("select 5", "select 'foo'", conn)
# Join Qual differences matter:
verify_statement_differs("select * from orders o join orderlines ol on o.orderid = ol.orderid;",
"select * from orders o join orderlines ol on o.orderid = 5;", conn)
# Although differences in Join Qual constants do not:
verify_statement_equivalency("select * from orders o join orderlines ol on o.orderid = 66;",
"select * from orders o join orderlines ol on o.orderid = 5;", conn)
# Constants may vary here:
verify_statement_equivalency("select orderid from orders where orderid = 5 and 1=1;",
"select orderid from orders where orderid = 7 and 3=3;", conn)
# Different logical operator means different query though:
verify_statement_differs("select orderid from orders where orderid = 5 and 1=1;",
"select orderid from orders where orderid = 7 or 3=3;", conn)
# don't mistake the same column number (MyVar->varno) from different tables:
verify_statement_differs("select a.orderid from orders a join orderlines b on a.orderid = b.orderlineid",
"select b.orderlineid from orders a join orderlines b on a.orderid = b.orderlineid", conn)
# Note that these queries are considered equivalent, though you could argue that they shouldn't be.
# This is because they have the same range table entry. I could look at aliases and differentiate
# them that way, but I'm reasonably convinced that to do so would be a mistake. This is a feature,
# not a bug.
verify_statement_equivalency("select a.orderid from orders a join orders b on a.orderid = b.orderid",
"select b.orderid from orders a join orders b on a.orderid = b.orderid", conn)
# Boolean Test node:
verify_statement_differs(
"select orderid from orders where orderid = 5 and (1=1) is true;",
"select orderid from orders where orderid = 5 and (1=1) is not true;",
conn)
verify_statement_equivalency(
"values(1, 2, 3);",
"values(4, 5, 6);", conn)
verify_statement_differs(
"values(1, 2, 3);",
"values(4, 5, 6, 7);", conn)
verify_statement_equivalency(
"select * from (values(1, 2, 3)) as v;",
"select * from (values(4, 5, 6)) as v;", conn)
verify_statement_differs(
"select * from (values(1, 2, 3)) as v;",
"select * from (values(4, 5, 6, 7)) as v;", conn)
# Coalesce
verify_statement_equivalency("select coalesce(orderid, null, null) from orders where orderid = 5 and 1=1;",
"select coalesce(orderid, 5, 5) from orders where orderid = 7 and 3=3;", conn)
verify_statement_differs("select coalesce(orderid, 5, 5, 6 ) from orders where orderid = 5 and 1=1;",
"select coalesce(orderid, 5, 5) from orders where orderid = 7 and 3=3;", conn)
# Observe what we can do with noise words (no "outer" in later statement, plus we use AS in the second query):
verify_statement_equivalency("select * from orders o left outer join orderlines ol on o.orderid = ol.orderid;",
"select * from orders AS o left join orderlines AS ol on o.orderid = ol.orderid;", conn)
# Join order in statement matters:
verify_statement_differs("select * from orderlines ol join orders o on o.orderid = ol.orderid;",
"select * from orders o join orderlines ol on o.orderid = ol.orderid;", conn)
# Join strength/type matters:
verify_statement_differs("select * from orderlines ol inner join orders o on o.orderid = ol.orderid;",
"select * from orderlines ol left outer join orders o on o.orderid = ol.orderid;", conn)
# ExprNodes can be processed recursively:
verify_statement_differs(
"select upper(lower(upper(lower (initcap(lower('Foo'))))));",
"select upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_equivalency(
"select upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select upper(lower(upper(lower(initcap(lower('Bar'))))));",
conn)
# Do same again, but put function in FROM
verify_statement_differs(
"select * from upper(lower(upper(lower (initcap(lower('Foo'))))));",
"select * from upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_equivalency(
"select * from upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select * from upper(lower(upper(lower(initcap(lower('Bar'))))));",
conn)
# In the where clause too:
verify_statement_equivalency(
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('Foo'))))));",
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('FOOFofofo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 'foo' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
"select 1 from orders where 'foo' = upper(lower(upper(lower(initcap(lower('FOOFofofo'))))));",
conn)
verify_statement_equivalency(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
"select 1 from orders where 1=2 and 'feew' = 'fi' or 'bar' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
"select 1 from orders where 1=2 and 'feew' = 'fi' or 'bar' = upper(lower(upper(initcap(initcap(lower('Foo'))))));",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is not null;",
conn)
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
"select 1 from orders where 1=55 and 'foo' = 'fi' or not upper(lower(upper(initcap(upper(lower('Foo')))))) is null;",
conn)
# Nested BoolExpr is a differentiator:
verify_statement_differs(
"select 1 from orders where 1=55 and 'foo' = 'fi' or 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
"select 1 from orders where 1=55 and 'foo' = 'fi' and 'foo' = upper(lower(upper(initcap(upper (lower('Foo'))))));",
conn)
# For aggregates too
verify_statement_differs(
"select array_agg(lower(upper(initcap(initcap(lower('Foo')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower('Bar')))))) from orders;",
conn)
verify_statement_equivalency(
"select array_agg(lower(upper(lower(initcap(lower('Baz')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower('Bar')))))) from orders;",
conn)
# Row-wise comparison
verify_statement_differs(
"select (1, 2) < (3, 4);",
"select ('a', 'b') < ('c', 'd');",
conn)
verify_statement_differs(
"select (1, 2, 3) < (3, 4, 5);",
"select (1, 2) < (3, 4);",
conn)
verify_statement_equivalency(
"select (1, 2, 3) < (3, 4, 5);",
"select (3, 4, 5) < (1, 2, 3);",
conn)
# Use lots of different operators:
verify_statement_differs(
"select 1 < 2;",
"select 1 <= 2;",
conn)
verify_statement_differs(
"select ARRAY[1,2,3]::integer[] && ARRAY[1]::integer[];",
"select ARRAY[1,2,3]::integer[] <@ ARRAY[1]::integer[];",
conn)
# Number of elements in ARRAY[] expression is a differentiator:
verify_statement_differs(
"select ARRAY[1,2,3]::integer[] <@ ARRAY[1]::integer[];",
"select ARRAY[999]::integer[] <@ ARRAY[342, 543, 634 ,753]::integer[];",
conn)
# Array coercion
verify_statement_equivalency(
"select '{1,2,3}'::oid[]::integer[] from orders;",
"select '{4,5,6}'::oid[]::integer[] from orders;",
conn)
# array subscripting operations
verify_statement_equivalency(
"select (array_agg(lower(upper(lower(initcap(lower('Baz')))))))[5:5] from orders;",
"select (array_agg(lower(upper(lower(initcap(lower('Bar')))))))[6:6] from orders;",
conn)
verify_statement_differs(
"select (array_agg(lower(upper(lower(initcap(lower('Baz')))))))[5:5] from orders;",
"select (array_agg(lower(upper(lower(initcap(lower('Bar')))))))[6] from orders;",
conn)
# nullif, represented as a distinct node but actually just a typedef
verify_statement_differs(
"select *, (select customerid from orders limit 1), nullif(5,10) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select customerid from orders limit 1), nullif('a','b') from orderlines ol join orders o on o.orderid = ol.orderid;",
conn)
verify_statement_equivalency(
"select *, (select customerid from orders limit 1), nullif(5,10) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select customerid from orders limit 1), nullif(10,15) from orderlines ol join orders o on o.orderid = ol.orderid;",
conn)
# Row constructor
verify_statement_differs(
"select row(1, 2,'this is a test');",
"select row(1, 2.5,'this is a test');",
conn)
# XML Stuff
verify_statement_differs(
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.datname as "name"),
xmlforest(
pg_database_size(d.datname) as size,
xact_commit,
xact_rollback,
blks_read,
blks_hit,
tup_fetched,
tup_returned,
tup_inserted,
tup_updated,
tup_deleted
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
"""
,
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.datname as "name"),
xmlforest(
pg_database_size(d.datname) as size,
xact_commit,
xact_rollback,
blks_read,
blks_hit,
tup_fetched,
tup_returned,
tup_updated,
tup_deleted
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
""",
conn)
verify_statement_differs(
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.blks_hit as "name"),
xmlforest(
pg_database_size(d.datname) as size
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
"""
,
"""
select xmlagg
(
xmlelement
( name database,
xmlattributes (d.blks_read as "name"),
xmlforest(
pg_database_size(d.datname) as size
)
)
)
from pg_stat_database d
right join pg_database
on d.datname = pg_database.datname
where not datistemplate;
""",
conn)
# subqueries
# in select list
verify_statement_differs("select *, (select customerid from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select orderid from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# select list nested subselection - inner most types differ
verify_statement_differs(
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select (select 1::bigint from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# This time, they're the same
verify_statement_equivalency(
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;",
"select *, (select (select 1::integer from customers limit 1) from orders limit 1) from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# in from - this particular set of queries entail recursive JoinExprNode() calls
verify_statement_differs(
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid a from orders) as t on ol.orderid=t.a;",
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid, customerid a from orders) as t on ol.orderid = t.a;", conn)
# another in from - entails recursive JoinExprNode() call
verify_statement_equivalency(
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid a from orders where orderid = 77) as t on ol.orderid=t.a;",
"select * from orderlines ol join orders o on o.orderid = ol.orderid join (select orderid b from orders where orderid = 5) as t on ol.orderid = t.b;", conn)
# Even though these two queries will result in the same plan, they are not yet equivalent - they are not
# semantically equivalent, as least by our standard. We could probably figure out a way of having the
# equivalency recognized, but I highly doubt it's worth bothering, since recognizing most kinds of semantic
# equivalence is generally more of a neat consequence of our implementation than a practical feature:
verify_statement_differs("select * from orderlines ol inner join orders o on o.orderid = ol.orderid;",
"select * from orderlines ol, orders o where o.orderid = ol.orderid;", conn)
# Aggregate group by normalisation:
verify_statement_differs("select count(*) from orders o group by orderid;",
"select count(*) from orders o group by customerid;", conn)
# Which aggregate was called matters
verify_statement_differs("select sum(customerid) from orders o group by orderid;",
"select avg(customerid) from orders o group by orderid;", conn)
# As does the order of aggregates
verify_statement_differs("select sum(customerid), avg(customerid) from orders o group by orderid;",
"select avg(customerid), sum(customerid) from orders o group by orderid;", conn)
# As does the having clause
verify_statement_equivalency(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 50;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 1000;",
conn)
# operator in having clause matters
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) = 100;",
conn)
# as does datatype
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100::bigint;",
conn)
verify_statement_equivalency(
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 100;",
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 15450;",
conn)
verify_statement_differs(
"select avg(customerid), sum(customerid) from orders o group by orderid having sum(customerid) > 100;",
"select avg(customerid), sum(customerid::bigint) from orders o group by orderid having sum(customerid::bigint) > 100;",
conn)
# columns order in "order by" matters:
verify_statement_differs(
"select * from orders o join orderlines ol on o.orderid = ol.orderid order by o.orderdate, o.orderid, customerid, netamount, totalamount, tax ;",
"select * from orders o join orderlines ol on o.orderid = ol.orderid order by o.orderdate, o.orderid, customerid, netamount, tax, totalamount;", conn)
# distinct on is a differentiator:
verify_statement_differs("select distinct on(customerid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select distinct on(o.orderid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# both the "on" value and the absence or presence of the clause:
verify_statement_differs("select distinct on(customerid) customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# select "all" is generally just a noise word:
verify_statement_equivalency("select all customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;",
"select customerid, o.orderid from orderlines ol join orders o on o.orderid = ol.orderid;", conn)
# Updates are similarly normalised, and their internal representations shares much with select statements
verify_statement_equivalency("update orders set orderdate='2011-01-06' where orderid=3;",
"update orders set orderdate='1992-01-06' where orderid = 10;", conn)
# updates with different columns are not equivalent:
verify_statement_differs("update orders set orderdate='2011-01-06' where orderid = 3;",
"update orders set orderdate='1992-01-06' where customerid = 10;", conn)
# default within update statement
verify_statement_equivalency(
"update products set special=default where prod_id = 7;",
"update products set special=default where prod_id = 10;",
conn)
# select into
verify_statement_equivalency(
"select * into orders_recent FROM orders WHERE orderdate >= '2002-01-01';",
"select * into orders_recent FROM orders WHERE orderdate >= '2010-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
verify_statement_differs(
"select * into orders_recent FROM orders WHERE orderdate >= '2002-01-01';",
"select * into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
verify_statement_differs(
"select orderdate into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
"select orderid into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent;", conn = conn)
# Here, name of new relation matters:
verify_statement_differs(
"select * into orders_recent FROM orders WHERE orderdate > '2002-01-01';",
"select * into orders_recent2 FROM orders WHERE orderdate > '2002-01-01';",
cleanup_sql = "drop table if exists orders_recent; drop table if exists orders_recent2;", conn = conn)
# CTE
verify_statement_differs(
"with a as (select customerid from orders ), b as (select 'foo') select orderid from orders",
"with a as (select customerid from orders ), b as (select 1) select orderid from orders",
conn)
# temporary column name within recursive CTEs doesn't differentiate
verify_statement_equivalency(
"""
with recursive j(n) AS (
values (1)
union all
select n + 1 from j where n < 100
)
select avg(n) from j;
""",
"""
with recursive k(n) AS (
values (1)
union all
select n + 1 from k where n < 50
)
select avg(n) from k;
""",
conn)
# set operation normalization occurs by walking the query tree recursively.
verify_statement_differs( "select orderid from orders union all select customerid from orders", "select customerid from orders union all select orderid from orders", conn)
verify_statement_equivalency(
"select 1, 2, 3 except select orderid, 6, 7 from orders",
"select 4, 5, 6 except select orderid, 55, 33 from orders",
conn)
verify_statement_differs(
"select orderid, 6 from orders union select 1,2 ",
"select 55, orderid from orders union select 4,5 ",
conn,
"column order differs (left child)")
verify_statement_differs(
"select 1, 2 union select orderid, 6 from orders",
"select 4, 5 union select 55, orderid from orderlines",
conn,
"column order differs (right child easy)")
verify_statement_differs(
"select 1, 2 union select orderid, 6 from orders",
"select 4, 5 union select 55, orderid from orders",
conn,
"column order differs (right child)")
# union != union all
verify_statement_differs(
"select customerid from orders union all select customerid from orders",
"select customerid from orders union select customerid from orders",
conn, "union != union all")
verify_statement_equivalency(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68;
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select orderid, 73737, 4235 from orderlines
intersect
select 5432, 6667,6337;
""",
conn)
verify_statement_differs(
"select orderid from orders union all select customerid from orders",
"select customerid from orders union all select orderid from orders",
conn)
verify_statement_differs(
"select 1::integer union all select orderid from orders union all select customerid from orders",
"select customerid from orders union all select orderid from orders", conn)
# My attempt to isolate the set operation problem.
# test passes if there is one less select,
# even if it'si an int, or if there's
# one more "select 1"
verify_statement_differs(
"""
select 1
union
select (current_date - orderdate + 5 + 6 + 7 + 8) from orderlines
union
select 1;
""",
"""
select 1
union
select orderid from orders
union
select 1;
""",
conn, "isolate set operations problem")
# Same as above, but the one table is different
verify_statement_differs(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68;
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select orderid, 73737, 4235 from orders
intersect
select 5432, 6667,6337;
""",
conn, "one table is different")
# Same as original, but I've switched a column reference with a constant in
# the second query
verify_statement_differs(
"""
select 1,2,3
union all
select 5,6,7 from orders
except
select orderid, 934, 194 from orderlines
intersect
select 66,67,68
""",
"""
select 535,8437,366
union all
select 1,1,1 from orders
except
select 73737, orderid, 4235 from orderlines
intersect
select 5432, 6667,6337
""",
conn)
# The left node in the set operation tree matches for before and after; we should still catch that
verify_statement_differs(
"""
select orderid from orders
union all
select customerid from orders
union all
select customerid from orders
""",
"""
select orderid from orders
union all
select orderid from orders
union all
select customerid from orders
""", conn)
verify_statement_differs(
"""
select orderid, customerid from orders
union
select orderid, customerid from orders
order by orderid
""",
"""
select orderid, customerid from orders
union
select orderid, customerid from orders
order by customerid
""", conn)
verify_statement_differs(
"""
with recursive j(n) AS (
values (1)
union all
select n + 1 from j where n < 100
)
select avg(n) from j;
""",
"""
with recursive j(n) AS (
values (1)
union all
select 1 from orders
)
select avg(n) from j;
""",
conn)
# Excercise some less frequently used Expr nodes
verify_statement_equivalency(
"""
select
case orderid
when 0 then 'zero'
when 1 then 'one'
else 'some other number' end
from orders
""",
""" select
case orderid
when 5 then 'five'
when 6 then 'six'
else 'some other number' end
from orders
""", conn)
verify_statement_differs(
"""
select
case orderid
when 0 then 'zero'
else 'some other number' end
from orders
""",
""" select
case orderid
when 5 then 'five'
when 6 then 'six'
else 'some other number' end
from orders
""", conn)
# Counter-intuitively, these two statements are equivalent...
verify_statement_equivalency(
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one'
else 'other number' end
from orders
""",
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one' end
from orders
""", conn, "Case when test")
# ...this is because no else clause is actually equivalent to "else NULL".
verify_statement_equivalency(
"""
select
case when orderid = 0
then 'zero'
when orderid = 1
then 'one'
else 'other number' end
from orders
""",
"""
select
case when orderid = 5
then 'five'
when orderid = 6
then 'six'
else 'some other number' end
from orders
""", conn, "second case when test")
verify_statement_differs( "select min(orderid) from orders", "select max(orderid) from orders", conn, "min not max check")
# The parser uses a dedicated Expr node to handle greatest()/least()
verify_statement_differs( "select greatest(1,2,3) from orders", "select least(1,2,3) from orders", conn, "greatest/least differ check")
# Window functions
verify_statement_differs(
"select sum(netamount) over () from orders",
"select sum(tax) over () from orders",
conn, "window function column check")
verify_statement_differs(
"select sum(netamount) over (partition by customerid) from orders",
"select sum(netamount) over (partition by orderdate) from orders",
conn, "window function over column differs check")
verify_statement_differs(
"select sum(netamount) over (partition by customerid order by orderid) from orders",
"select sum(netamount) over (partition by customerid order by tax) from orders",
conn, "window function over column differs check")
verify_statement_differs(
"""
SELECT c.oid AS relid,
n.nspname AS schemaname,
c.relname
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indrelid
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
LEFT JOIN pg_class x ON t.reltoastidxid = x.oid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = ANY (ARRAY['r'::"char", 't'::"char"])
GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
"""
,
"""
SELECT c.oid AS relid,
n.nspname AS schemaname,
c.relname
FROM pg_class c
LEFT JOIN pg_index i ON c.oid = i.indrelid
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
LEFT JOIN pg_class x ON t.reltoastidxid = x.oid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = ANY (ARRAY['r'::"char", 't'::"char", 'v'::"char"])
GROUP BY c.oid, n.nspname, c.relname, t.oid, x.oid;
"""
,conn, "number of ARRAY elements varies in ANY() in where clause")
# problematic query
verify_statement_equivalency(
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','d','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
conn)
verify_statement_differs(
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
"""
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','d','x', 'd'))
WHERE c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
""",
conn)
# Declare cursor is a special sort of utility statement - one with
# a query tree that looks pretty much like that of a select statement
# Not really worth serializing the tree like a select statement though -
# Just treat it as a utility statement
verify_statement_equivalency(
"declare test cursor for select * from orders;",
"declare test cursor for select * from orders;",
cleanup_sql = "close all;", conn = conn)
# function-like dedicated ExprNodes
# I'd speculate that if this was performed with every ExprNode that resembles
# a function, it wouldn't actually fail, since there tends to be a good reason
# for having a dedicated though function-like ExprNode rather than just an
# SQL-callable function, and I'm naturally already serializing those differences
# as they're rather obviously essential to the query
# The concern here is a specific case of a more general one - that successive
# queries with similar ExprNodes could incorrectly be considered equivalent.
# NB:
# I consider the question of whether or not it is necessary to escape query-tree
# serializations (in a way that includes a magic number for the ExprNode, such as
# its offset in the NodeTag enum) to be an open one.
# Part of the difficulty is that OIDs cannot be expected to remain unique
# over time and across pg_* tables
verify_statement_differs(
"select coalesce(orderid) from orders;",
"select sum(orderid) from orders;",
conn, "Don't confuse functions/function like nodes")
verify_normalizes_correctly("select 1, 2, 3;", "select ?, ?, ?;", conn, "integer verification" )
verify_normalizes_correctly("select 'foo';", "select ?;", conn, "unknown/string normalization verification" )
verify_normalizes_correctly("select 'bar'::text;", "select ?::text;", conn, "text verification" )
verify_normalizes_correctly("select $$bar$$;", "select ?;", conn, "unknown/string normalization verification" )
verify_normalizes_correctly("select $$bar$$ from pg_database where datname = 'postgres';",
"select ? from pg_database where datname = ?;", conn, "Quals comparison" )
# You can parameterize a limit constant, so our behavior is consistent with that
verify_normalizes_correctly("select * from orders limit 1 offset 5;", "select * from orders limit ? offset ?;", conn, "integer verification" )
# Note: Due to :: operator precedence, this behavior is correct:
verify_normalizes_correctly("select -12345::integer;", "select -?::integer;", conn, "show operator precedence issue" )
verify_normalizes_correctly("select -12345;", "select ?;", conn, "show no operator precedence issue" )
verify_normalizes_correctly("select -12345.12345::float;", "select -?::float;", conn, "show operator precedence issue" )
verify_normalizes_correctly("select -12345.12345;", "select ?;", conn, "show no operator precedence issue" )
verify_normalizes_correctly("select array_agg(lower(upper(lower(initcap(lower('Baz')))))) from orders;",
"select array_agg(lower(upper(lower(initcap(lower(?)))))) from orders;", conn, "Function call")
# Test this cast syntax works:
verify_normalizes_correctly("select timestamp without time zone '2009-05-05 15:34:24';",
"select timestamp without time zone ?;", conn, "excercise alternative cast syntax, timestamp")
verify_normalizes_correctly("select timestamptz '2009-05-05 15:34:24.1234';",
"select timestamptz ?;", conn, "excercise alternative cast syntax, timestamptz")
verify_normalizes_correctly("select date '2009-05-05';",
"select date ?;", conn, "excercise alternative cast syntax, date")
verify_normalizes_correctly("select time '15:15:15';",
"select time ?;", conn, "excercise alternative cast syntax, time")
verify_normalizes_correctly("select time with time zone '15:15:15';",
"select time with time zone ?;", conn, "excercise alternative cast syntax, time with time zone")
verify_normalizes_correctly("select interval '1 hour';", "select interval ?;", conn, "excercise alternative cast syntax, interval")
# Binary/bit strings have special handling within parser
verify_normalizes_correctly("select B'1001' | B'1111';", "select ? | ?;", conn, "bitstring parser handling")
demonstrate_buffer_limitation(conn)
if __name__=="__main__":
main()
[application/x-gzip] 0001-Revision-with-synchronization-fixes.patch.gz (37.9K, ../../CAEYLb_UC+D0VDJsNgjxwxCsta3GGyGfkwvRgCoZNvX=W3unRLw@mail.gmail.com/3-0001-Revision-with-synchronization-fixes.patch.gz)
download
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
* [PATCH v1 2/4] autovac: resolve relopts before vacuuming
@ 2025-06-23 19:42 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 800+ messages in thread
From: Nathan Bossart @ 2025-06-23 19:42 UTC (permalink / raw)
---
src/backend/commands/vacuum.c | 7 ++--
src/backend/postmaster/autovacuum.c | 52 +++++++++++++++++++++--------
2 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 33a33bf6b1c..0015b9ef4b0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -421,7 +421,7 @@ ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
/*
* Later, in vacuum_rel(), we check if a reloption override was specified.
*/
- params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ params.max_eager_freeze_failure_rate = -1.0;
/*
* Create special memory context for cross-transaction storage.
@@ -2195,10 +2195,13 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
* Check if the vacuum_max_eager_freeze_failure_rate table storage
* parameter was specified. This overrides the GUC value.
*/
- if (rel->rd_options != NULL &&
+ if (params->max_eager_freeze_failure_rate < 0 &&
+ rel->rd_options != NULL &&
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate >= 0)
params->max_eager_freeze_failure_rate =
((StdRdOptions *) rel->rd_options)->vacuum_max_eager_freeze_failure_rate;
+ else
+ params->max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
/*
* Set truncate option based on truncate reloption or GUC if it wasn't
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index f86c9fed853..3bedca971ff 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -2758,6 +2758,9 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
int multixact_freeze_table_age;
int log_min_duration;
AutoVacOpts *avopts = (relopts ? &relopts->autovacuum : NULL);
+ VacOptValue index_cleanup;
+ VacOptValue truncate;
+ double max_eager_freeze_failure_rate;
/*
* Calculate the vacuum cost parameters and the freeze ages. If there
@@ -2790,6 +2793,39 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
? avopts->multixact_freeze_table_age
: default_multixact_freeze_table_age;
+ if (relopts)
+ {
+ switch (relopts->vacuum_index_cleanup)
+ {
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_AUTO:
+ index_cleanup = VACOPTVALUE_AUTO;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_ON:
+ index_cleanup = VACOPTVALUE_ENABLED;
+ break;
+ case STDRD_OPTION_VACUUM_INDEX_CLEANUP_OFF:
+ index_cleanup = VACOPTVALUE_DISABLED;
+ break;
+ }
+ }
+ else
+ index_cleanup = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_truncate_set)
+ {
+ if (relopts->vacuum_truncate)
+ truncate = VACOPTVALUE_ENABLED;
+ else
+ truncate = VACOPTVALUE_DISABLED;
+ }
+ else
+ truncate = VACOPTVALUE_UNSPECIFIED;
+
+ if (relopts && relopts->vacuum_max_eager_freeze_failure_rate >= 0)
+ max_eager_freeze_failure_rate = relopts->vacuum_max_eager_freeze_failure_rate;
+ else
+ max_eager_freeze_failure_rate = -1.0;
+
tab = palloc(sizeof(autovac_table));
tab->at_relid = relid;
tab->at_sharedrel = classForm->relisshared;
@@ -2806,13 +2842,8 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
(doanalyze ? VACOPT_ANALYZE : 0) |
(!wraparound ? VACOPT_SKIP_LOCKED : 0);
- /*
- * index_cleanup and truncate are unspecified at first in autovacuum.
- * They will be filled in with usable values using their reloptions
- * (or reloption defaults) later.
- */
- tab->at_params.index_cleanup = VACOPTVALUE_UNSPECIFIED;
- tab->at_params.truncate = VACOPTVALUE_UNSPECIFIED;
+ tab->at_params.index_cleanup = index_cleanup;
+ tab->at_params.truncate = truncate;
/* As of now, we don't support parallel vacuum for autovacuum */
tab->at_params.nworkers = -1;
tab->at_params.freeze_min_age = freeze_min_age;
@@ -2822,12 +2853,7 @@ table_recheck_autovac(Oid relid, HTAB *table_toast_map,
tab->at_params.is_wraparound = wraparound;
tab->at_params.log_min_duration = log_min_duration;
tab->at_params.toast_parent = InvalidOid;
-
- /*
- * Later, in vacuum_rel(), we check reloptions for any
- * vacuum_max_eager_freeze_failure_rate override.
- */
- tab->at_params.max_eager_freeze_failure_rate = vacuum_max_eager_freeze_failure_rate;
+ tab->at_params.max_eager_freeze_failure_rate = max_eager_freeze_failure_rate;
tab->at_storage_param_vac_cost_limit = avopts ?
avopts->vacuum_cost_limit : 0;
tab->at_storage_param_vac_cost_delay = avopts ?
--
2.39.5 (Apple Git-154)
--QWBYbd5Ar5k8NvSv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0003-autovac-combine-reloptions-correctly.patch
^ permalink raw reply [nested|flat] 800+ messages in thread
end of thread, other threads:[~2025-06-23 19:42 UTC | newest]
Thread overview: 800+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2011-12-07 01:19 Re: pg_stat_statements with query tree based normalization Peter Geoghegan <[email protected]>
2011-12-07 14:13 ` Marti Raudsepp <[email protected]>
2011-12-10 13:56 ` Greg Smith <[email protected]>
2011-12-11 01:52 ` Peter Geoghegan <[email protected]>
2011-12-14 10:14 ` Peter Geoghegan <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
2025-06-23 19:42 [PATCH v1 2/4] autovac: resolve relopts before vacuuming Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox