diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 22dbc07..db7842a 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -1488,6 +1488,23 @@ WITH ( MODULUS numeric_literal, REM + shrink_enabled (boolean) + + + Enables or disables shrinking the table when it's vacuumed. + The default is true. If true, VACUUM frees empty pages at the end of the table. + Shrinking the table requires ACCESS EXCLUSIVE lock on the table. + It can take non-negligible time when the shared buffer is large. Besides, ACCESS EXCLUSIVE + lock could lead to query cancellation on the standby server. + If the workload is likely to reuse the freed space soon + (e.g., UPDATE-heavy, or new rows will be added after deleting + old rows), setting this parameter to false makes sense to avoid unnecessary shrinking. + This parameter cannot be set for TOAST tables. + + + + + user_catalog_table (boolean) diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index cdf1f4a..63157e7 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -89,6 +89,11 @@ * Setting parallel_workers is safe, since it acts the same as * max_parallel_workers_per_gather which is a USERSET parameter that doesn't * affect existing plans or queries. + * + * shrink_enabled can be set at ShareUpdateExclusiveLock because it + * is only used during VACUUM, which uses a ShareUpdateExclusiveLock, + * so the VACUUM will not be affected by in-flight changes. Changing its + * value has no affect until the next VACUUM, so no need for stronger lock. */ static relopt_bool boolRelOpts[] = @@ -113,6 +118,15 @@ static relopt_bool boolRelOpts[] = }, { { + "shrink_enabled", + "Enables shrinking this table at vacuum", + RELOPT_KIND_HEAP, + ShareUpdateExclusiveLock + }, + true + }, + { + { "user_catalog_table", "Declare a table as an additional catalog table, e.g. for the purpose of logical replication", RELOPT_KIND_HEAP, @@ -1383,6 +1397,8 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind) offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor)}, {"autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL, offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_scale_factor)}, + {"shrink_enabled", RELOPT_TYPE_BOOL, + offsetof(StdRdOptions, shrink_enabled)}, {"user_catalog_table", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, user_catalog_table)}, {"parallel_workers", RELOPT_TYPE_INT, diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 37aa484..000401f 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -285,7 +285,9 @@ heap_vacuum_rel(Relation onerel, int options, VacuumParams *params, /* * Optionally truncate the relation. */ - if (should_attempt_truncation(vacrelstats)) + if ((onerel->rd_options == NULL || + ((StdRdOptions *) onerel->rd_options)->shrink_enabled) && + should_attempt_truncation(vacrelstats)) lazy_truncate_heap(onerel, vacrelstats); /* Report that we are now doing final cleanup */ diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7b7a88f..f7b3501 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -1025,6 +1025,7 @@ static const char *const table_storage_parameters[] = { "fillfactor", "log_autovacuum_min_duration", "parallel_workers", + "shrink_enabled", "toast.autovacuum_enabled", "toast.autovacuum_freeze_max_age", "toast.autovacuum_freeze_min_age",