diff --git a/doc/src/sgml/ref/repack.sgml b/doc/src/sgml/ref/repack.sgml
index 346cba89c90..14651715013 100644
--- a/doc/src/sgml/ref/repack.sgml
+++ b/doc/src/sgml/ref/repack.sgml
@@ -61,16 +61,149 @@ REPACK [ ( option [, ...] ) ] USING
If a USING INDEX clause is specified, the rows are
- physically reordered based on information from an index. Please see the
- notes on clustering below.
+ physically reordered based on information from an index. Please see
+ below.
When a table is being repacked, an ACCESS EXCLUSIVE lock
- is acquired on it. This prevents any other database operations (both reads
- and writes) from operating on the table until the REPACK
- is finished. If you want to keep the table accessible during the repacking,
- consider using the CONCURRENTLY option.
+ is acquired on it, unless the CONCURRENTLY option is given.
+ See for a discussion
+ on the effects of this option.
+
+
+
+
+ Parameters
+
+
+
+ table_name
+
+
+ The name (possibly schema-qualified) of a table.
+
+
+
+
+
+ column_name
+
+
+ The name of a specific column to analyze. Defaults to all columns.
+ If a column list is specific, ANALYZE must also
+ be specified.
+
+
+
+
+
+ index_name
+
+
+ The name of an index.
+
+
+
+
+
+ CONCURRENTLY
+
+
+ Allow other transactions to use the table while it is being repacked.
+ See for more details.
+
+
+
+
+
+
+ VERBOSE
+
+
+ Prints a progress report as each table is repacked
+ at INFO level.
+
+
+
+
+
+ ANALYZE
+ ANALYSE
+
+
+ Applies on the table after repacking. This is
+ currently only supported when a single (non-partitioned) table is specified.
+ This option cannot be used inside a transaction block, or from a function,
+ procedure, or DO block.
+
+
+
+
+
+ boolean
+
+
+ Specifies whether the selected option should be turned on or off.
+ You can write TRUE, ON, or
+ 1 to enable the option, and FALSE,
+ OFF, or 0 to disable it. The
+ boolean value can also
+ be omitted, in which case TRUE is assumed.
+
+
+
+
+
+
+
+ Notes
+
+
+ To repack a table, one must have the MAINTAIN privilege
+ on the table.
+
+
+
+ REPACK is primarily meant to remove bloat and, with
+ USING INDEX, to cluster the table, in order to improve
+ performance. Although it also advances the table's
+ relfrozenxid and relminmxid,
+ it is not a good way to prevent transaction ID or multixact ID wraparound:
+ it rewrites the whole table and all of its indexes, so it takes much longer
+ than VACUUM, and it can fail after most of the work
+ is done, especially with CONCURRENTLY on a busy table.
+ VACUUM is recommended for that instead (see
+ ).
+ When a table gets close to wraparound, VACUUM skips index
+ vacuuming on its own (see ), and its
+ INDEX_CLEANUP OFF
+ option can do the same earlier.
+
+
+
+ REPACK refuses to process a table on which an invalid
+ index exists. Such indexes must be dropped or reindexed by the user ahead
+ of time.
+
+
+
+ While REPACK is running, the is temporarily changed to pg_catalog,
+ pg_temp.
+
+
+
+ Each backend running REPACK will report its progress
+ in the pg_stat_progress_repack view. See
+ for details.
+
+
+
+ Repacking a partitioned table repacks each of its partitions. If an index
+ is specified, each partition is repacked using the partition of that
+ index. REPACK on a partitioned table cannot be executed
+ inside a transaction block.
@@ -141,27 +274,37 @@ REPACK [ ( option [, ...] ) ] USING
all tables which have a clustering index defined and which the calling
user has privileges for are processed.
-
Notes on Resources
- When an index scan or a sequential scan without sort is used, a temporary
- copy of the table is created that contains the table data in the index
- order. Temporary copies of each index on the table are created as well.
- Therefore, you need free space on disk at least equal to the sum of the
- table size and the index sizes.
+ REPACK creates a temporary copy of the table and all
+ of its indexes, so you need free disk space at least equal to the sum
+ of the table size and the index sizes.
- When a sequential scan and sort is used, a temporary sort file is also
- created, so that the peak temporary space requirement is as much as double
- the table size, plus the index sizes. This method is often faster than
- the index scan method, but if the disk space requirement is intolerable,
- you can disable this choice by temporarily setting
- to off.
+ If the USING INDEX clause is given and the planner
+ chooses a sequential scan and sort to implement it, a temporary sort
+ file of up to the size of the table is needed in addition to the above.
+ This method is usually faster than an index scan, but if the disk space
+ requirement is intolerable, you can disable this choice by temporarily
+ setting to off; or
+ omitting USING INDEX if the table doesn't need to be
+ reordered.
+
+
+
+ For the purposes of transaction ID wraparound
+ (see ),
+ REPACK is considered a single long-running
+ transaction, which prevents VACUUM from cleaning
+ up dead rows from other tables.
+ It is advisable to monitor pg_stat_activity.backend_xid
+ for the process running REPACK when repacking
+ very large tables, to avoid causing excessive bloat in other tables.
@@ -171,244 +314,136 @@ REPACK [ ( option [, ...] ) ] USING
-
+
+ Notes on Concurrent Operation
-
- Parameters
+
+
+ REPACK with the CONCURRENTLY
+ option is not MVCC-safe. After the repacking transaction commits,
+ the table will appear empty to concurrent transactions, if they are
+ using a snapshot taken before repacking started.
+ See for more details.
+
+
-
-
- table_name
-
-
- The name (possibly schema-qualified) of a table.
-
-
-
+
+ REPACK copies the contents of the table
+ (ignoring dead tuples) into a new file, sorted by the specified index,
+ and also creates a new file for each index. It then swaps the old and
+ new files for the table and all the indexes, and deletes the old files.
+ Without the CONCURRENTLY option, an
+ ACCESS EXCLUSIVE lock is acquired at the beginning
+ and remains held throughout the operation to make sure that the old
+ files do not change during the processing; otherwise, any concurrent
+ changes would get lost due to the swap.
+
-
- column_name
-
-
- The name of a specific column to analyze. Defaults to all columns.
- If a column list is specific, ANALYZE must also
- be specified.
-
-
-
+
+ By contrast, when the CONCURRENTLY option is
+ specified, the bulk of the operation is run with
+ SHARE UPDATE EXCLUSIVE lock, and the
+ ACCESS EXCLUSIVE lock is only acquired
+ during the final phase to swap the table and index files.
+ The data changes that took place during the creation of the new
+ table and index files are captured using logical decoding
+ (see ) and applied before
+ the ACCESS EXCLUSIVE lock is requested.
+ Once that lock is obtained, a final pass over any remaining captured
+ concurrent data changes is done and the files are swapped.
+ Thus the lock is typically held for a short time, depending
+ on the amount of changes accumulated while the lock was being
+ waited for.
+
-
- index_name
-
-
- The name of an index.
-
-
-
+
+ Processing of these concurrent changes requires a fixed small
+ amount of memory for each tuple concurrently updated or deleted,
+ not limited by ;
+ if more than about 104 million rows are concurrently updated or
+ deleted during the execution of REPACK, the
+ command fails. In addition, the complete tuple data for all
+ concurrent changes (except for TOAST columns that are not modified
+ by UPDATE) are stored on disk separately.
+
-
- CONCURRENTLY
-
-
- Allow other transactions to use the table while it is being repacked.
-
+
+ REPACK (CONCURRENTLY) might fail to complete if DDL
+ commands are executed on the table by other transactions during the
+ repacking.
+
-
- Internally, REPACK copies the contents of the table
- (ignoring dead tuples) into a new file, sorted by the specified index,
- and also creates a new file for each index. Then it swaps the old and
- new files for the table and all the indexes, and deletes the old
- files. The ACCESS EXCLUSIVE lock is needed to make
- sure that the old files do not change during the processing because the
- changes would get lost due to the swap.
-
+
+ REPACK (CONCURRENTLY) USING INDEX
+ does not try to order the rows inserted into the table after the
+ repacking started.
+
-
- With the CONCURRENTLY option, the ACCESS
- EXCLUSIVE lock is only acquired to swap the table and index
- files. The data changes that took place during the creation of the new
- table and index files are captured using logical decoding
- () and applied before
- the ACCESS EXCLUSIVE lock is requested. Thus the lock
- is typically held only for the time needed to swap the files, which
- should be pretty short. However, the time might still be noticeable if
- too many data changes have been done to the table while
- REPACK was waiting for the lock: those changes must
- be processed just before the files are swapped, while the
- ACCESS EXCLUSIVE lock is being held.
-
+
+ The CONCURRENTLY option cannot be used in the
+ following cases:
-
- Note that REPACK with the
- CONCURRENTLY option does not try to order the rows
- inserted into the table after the repacking started. Also
- note REPACK might fail to complete due to DDL
- commands executed on the table by other transactions during the
- repacking.
-
-
-
+
+
- In addition to the temporary space requirements explained in
- ,
- the CONCURRENTLY option can add to the usage of
- temporary space a bit more. The reason is that other transactions can
- perform DML operations which cannot be applied to the new file until
- REPACK has copied all the existing tuples from the
- old file. Thus the tuples inserted into the old file during the copying
- are also stored separately in a temporary file, until they can be
- processed.
+ The relation is not a table (e.g., it is a materialized view).
-
+
-
- The CONCURRENTLY option cannot be used in the
- following cases:
-
-
-
-
- The relation is not a table (e.g., it is a materialized view).
-
-
-
-
-
- The table is UNLOGGED.
-
-
-
-
-
- The table is partitioned.
-
-
-
-
-
- The table lacks a primary key and index-based replica identity.
-
-
-
-
-
- The table is a system catalog or a TOAST table.
-
-
-
-
-
- The table's access method is not heap.
-
-
-
-
-
- The table is declared as a catalog table using the
- user_catalog_table
- storage parameter.
-
-
-
-
-
- REPACK is executed inside a transaction block.
-
-
-
-
-
- The max_repack_replication_slots
- configuration parameter does not allow for the creation of an
- additional replication slot.
-
-
-
-
-
-
+
- REPACK with the CONCURRENTLY
- option is not MVCC-safe, see for
- details.
+ The table is UNLOGGED.
-
+
-
-
+
+
+ The table is partitioned.
+
+
-
- VERBOSE
-
-
- Prints a progress report as each table is repacked
- at INFO level.
-
-
-
+
+
+ The table lacks a primary key and index-based replica identity.
+
+
-
- ANALYZE
- ANALYSE
-
-
- Applies on the table after repacking. This is
- currently only supported when a single (non-partitioned) table is specified.
- This option cannot be used inside a transaction block, or from a function,
- procedure, or DO block.
-
-
-
+
+
+ The table is a system catalog or a TOAST table.
+
+
-
- boolean
-
-
- Specifies whether the selected option should be turned on or off.
- You can write TRUE, ON, or
- 1 to enable the option, and FALSE,
- OFF, or 0 to disable it. The
- boolean value can also
- be omitted, in which case TRUE is assumed.
-
-
-
-
-
+
+
+ The table's access method is not heap.
+
+
-
- Notes
+
+
+ The table is declared as a catalog table using the
+ user_catalog_table
+ storage parameter.
+
+
-
- To repack a table, one must have the MAINTAIN privilege
- on the table.
+
+
+ REPACK is executed inside a transaction block.
+
+
+
+
+
+ The max_repack_replication_slots
+ configuration parameter does not allow for the creation of an
+ additional replication slot.
+
+
+
-
-
- REPACK refuses to process a table on which an invalid
- index exists. Such indexes must be dropped or reindexed by the user ahead
- of time.
-
-
-
- While REPACK is running, the is temporarily changed to pg_catalog,
- pg_temp.
-
-
-
- Each backend running REPACK will report its progress
- in the pg_stat_progress_repack view. See
- for details.
-
-
-
- Repacking a partitioned table repacks each of its partitions. If an index
- is specified, each partition is repacked using the partition of that
- index. REPACK on a partitioned table cannot be executed
- inside a transaction block.
-
-
+