From d3bcc907cdbfdea63ee4a72d979674b445a83812 Mon Sep 17 00:00:00 2001 From: PegoraroF10 Date: Thu, 30 Jul 2026 11:31:06 -0300 Subject: [PATCH v2] doc: Update REPACK-related table rewrite documentation Adding REPACK introduced table-rewrite behavior that overlaps with VACUUM FULL and CLUSTER, but some documentation still mentioned only one of these commands or described the progress and locking behavior imprecisely. Clarify that table-rewriting operations, including REPACK, can change CTIDs. Also describe VACUUM FULL, CLUSTER, and REPACK consistently as table-rewriting operations for disk-space recovery where appropriate, document the pg_stat_progress_repack and compatibility pg_stat_progress_cluster views consistently, and clarify the ACCESS EXCLUSIVE locking behavior of REPACK, including CONCURRENTLY. Backpatch to v19, where REPACK was introduced. --- doc/src/sgml/ddl.sgml | 4 +++- doc/src/sgml/maintenance.sgml | 45 +++++++++++++++++++++-------------- doc/src/sgml/monitoring.sgml | 24 +++++++++++-------- doc/src/sgml/mvcc.sgml | 12 ++++++---- 4 files changed, 52 insertions(+), 33 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index 9006b947e74..4ae6ff2d614 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -1568,7 +1568,9 @@ CREATE TABLE circles ( although the ctid can be used to locate the row version very quickly, a row's ctid will change if it is - updated or moved by VACUUM FULL. Therefore + updated, or moved by a table-rewriting operation such as + VACUUM FULL, CLUSTER, or + REPACK. Therefore ctid should not be used as a row identifier. A primary key should be used to identify logical rows. diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index 33ab4edf87c..c0972b04212 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -171,11 +171,13 @@ future reuse. However, it will not return the space to the operating system, except in the special case where one or more pages at the end of a table become entirely free and an exclusive table lock can be - easily obtained. In contrast, VACUUM FULL actively compacts - tables by writing a complete new version of the table file with no dead - space. This minimizes the size of the table, but can take a long time. - It also requires extra disk space for the new copy of the table, until - the operation completes. + easily obtained. In contrast, table-rewriting commands such as + VACUUM FULL, CLUSTER, and + REPACK actively compact tables by writing a complete + new version of the table file without the dead space left by old row + versions. This minimizes the size of the table, but can take a long time. + It also requires extra disk space for the new copy of the table, until the + operation completes. @@ -186,12 +188,14 @@ is not to keep tables at their minimum size, but to maintain steady-state usage of disk space: each table occupies space equivalent to its minimum size plus however much space gets used up between vacuum runs. - Although VACUUM FULL can be used to shrink a table back - to its minimum size and return the disk space to the operating system, - there is not much point in this if the table will just grow again in the - future. Thus, moderately-frequent standard VACUUM runs are a - better approach than infrequent VACUUM FULL runs for - maintaining heavily-updated tables. + Although table-rewriting compaction operations such as + VACUUM FULL, CLUSTER, and + REPACK can be used to shrink a table back to its + minimum size and return the disk space to the operating system, there is + not much point in this if the table will just grow again in the future. + Thus, moderately-frequent standard VACUUM runs are a + better approach than infrequent use of such operations for maintaining + heavily-updated tables. @@ -199,7 +203,8 @@ doing all the work at night when load is low. The difficulty with doing vacuuming according to a fixed schedule is that if a table has an unexpected spike in update activity, it may - get bloated to the point that VACUUM FULL is really necessary + get bloated to the point that a table-rewriting compaction operation such + as VACUUM FULL or REPACK may be needed to reclaim space. Using the autovacuum daemon alleviates this problem, since the daemon schedules vacuuming dynamically in response to update activity. It is unwise to disable the daemon completely unless you @@ -227,16 +232,20 @@ a table contains large numbers of dead row versions as a result of massive update or delete activity. If you have such a table and you need to reclaim the excess disk space it occupies, you will need - to use VACUUM FULL, or alternatively - CLUSTER + to use VACUUM FULL, + CLUSTER, + REPACK, or one of the table-rewriting variants of ALTER TABLE. These commands rewrite an entire new copy of the table and build new indexes for it. All these options require an - ACCESS EXCLUSIVE lock. Note that - they also temporarily use extra disk space approximately equal to the size - of the table, since the old copies of the table and indexes can't be - released until the new ones are complete. + ACCESS EXCLUSIVE lock, except that + REPACK can be run with CONCURRENTLY, + in which case the ACCESS EXCLUSIVE lock is held only + while swapping the table and index files. Note that they also + temporarily use extra disk space approximately equal to the size of the + table, since the old copies of the table and indexes can't be released + until the new ones are complete. diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 32cb6fdbd76..53d81ac63d1 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -417,7 +417,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser pg_stat_progress_repackpg_stat_progress_repack One row for each backend running REPACK, CLUSTER or VACUUM FULL, showing current progress. - . + See . @@ -6726,7 +6726,8 @@ FROM pg_stat_get_backend_idset() AS backendid; VACUUM FULL is running, the backwards-compatibility pg_stat_progress_cluster view will - contain a row for each backend that is currently running either command. + contain a row for each backend that is currently running one of these + commands. The tables below describe the information that will be reported and provide information about how to interpret it. @@ -7400,10 +7401,11 @@ FROM pg_stat_get_backend_idset() AS backendid; - Whenever REPACK is running, + Whenever REPACK, CLUSTER, or + VACUUM FULL is running, the pg_stat_progress_repack view will contain a - row for each backend that is currently running the command. The tables - below describe the information that will be reported and provide + row for each backend that is currently running one of these commands. + The tables below describe the information that will be reported and provide information about how to interpret it. @@ -7454,7 +7456,7 @@ FROM pg_stat_get_backend_idset() AS backendid; relid oid - OID of the table being repacked. + OID of the table being processed. @@ -7463,8 +7465,8 @@ FROM pg_stat_get_backend_idset() AS backendid; command text - The command that is running. Either REPACK or - VACUUM FULL, or CLUSTER. + The command that is running. One of CLUSTER, + REPACK, or VACUUM FULL. @@ -7657,10 +7659,12 @@ FROM pg_stat_get_backend_idset() AS backendid; currently vacuuming. The tables below describe the information that will be reported and provide information about how to interpret it. Progress for VACUUM FULL commands is reported via - pg_stat_progress_cluster + pg_stat_progress_repack, and is also visible via + the backwards-compatibility pg_stat_progress_cluster because both VACUUM FULL and CLUSTER rewrite the table, while regular VACUUM only modifies it - in place. See . + in place. See and + . diff --git a/doc/src/sgml/mvcc.sgml b/doc/src/sgml/mvcc.sgml index 9cb52302f23..ff01e97ea3d 100644 --- a/doc/src/sgml/mvcc.sgml +++ b/doc/src/sgml/mvcc.sgml @@ -1095,10 +1095,14 @@ ERROR: could not serialize access due to read/write dependencies among transact Acquired by the DROP TABLE, TRUNCATE, REINDEX, - CLUSTER, VACUUM FULL, - and REFRESH MATERIALIZED VIEW (without - ) - commands. Many forms of ALTER INDEX and ALTER TABLE also acquire + CLUSTER, VACUUM FULL, and + REFRESH MATERIALIZED VIEW (without + ) commands. + REPACK also acquires this lock mode. When run + with , REPACK acquires + it only while swapping the table and index files. + Many forms of ALTER INDEX and + ALTER TABLE also acquire a lock at this level. This is also the default lock mode for LOCK TABLE statements that do not specify a mode explicitly. -- 2.55.0