{"Entry":{"collection":"sql","key":"repack","name":"REPACK","aliases":["repack"],"metadata":{"aliases":["repack"],"changed_in":[],"changes":[{"from":"18","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":[],"removed":[]},"status":"added","synopsis":null,"to":"19"}],"content_hash":"7046b472b8fe6f5935f4b8b1ddbc0654639de9c740713bab423edb592c0a9ece","editorial":{},"first_version":"19","group":"misc","imported_at":"2026-09-27T17:57:27.465795+08:00","last_version":"20","name":"REPACK","object":"","position":16001,"present_in":["19","20"],"purpose":"rewrite a table to reclaim disk space","purpose_zh":"","related":[],"slug":"repack","source_rev":"b7bd9cda","synopsis":"REPACK [ ( option [, ...] ) ] [ table_and_columns [ USING INDEX [ index_name ] ] ]\nREPACK [ ( option [, ...] ) ] USING INDEX\n\nwhere option can be one of:\n\nVERBOSE [ boolean ]\nANALYZE [ boolean ]\nCONCURRENTLY [ boolean ]\n\nand table_and_columns is:\ntable_name [ ( column_name [, ...] ) ]","verb":"REPACK"}},"Definition":{"Collection":"sql","Key":"repack","SourceDatabase":"center","Version":"20","SourceTable":"sqlcmd","SourceKey":"repack","SourceRevision":"b7bd9cda","Facts":{"anchor":"SQL-REPACK","file":"sql-repack.html","lang":"en","name":"REPACK","purpose":"rewrite a table to reclaim disk space","purpose_zh":"","related":[],"sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e reclaims storage occupied by dead tuples. Unlike \u003ccode class=\"command\"\u003eVACUUM\u003c/code\u003e, it does so by rewriting the entire contents of the table specified by \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e into a new disk file with no extra space (except for the space guaranteed by the \u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e storage parameter), allowing unused space to be returned to the operating system.\u003c/p\u003e\u003cp\u003eWithout a \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e, \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e processes every table and materialized view in the current database that the current user has the \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e privilege on. This form of \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e cannot be executed inside a transaction block. Also, this form is not allowed if the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option is used.\u003c/p\u003e\u003cp\u003eIf a \u003ccode class=\"literal\"\u003eUSING INDEX\u003c/code\u003e clause is specified, the rows are physically reordered based on information from an index. Please see the notes on clustering below.\u003c/p\u003e\u003cp\u003eWhen a table is being repacked, an \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e lock is acquired on it. This prevents any other database operations (both reads and writes) from operating on the table until the \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e is finished. If you want to keep the table accessible during the repacking, consider using the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option.\u003c/p\u003e\u003cdiv class=\"refsect2\"\u003e\u003ch3\u003eNotes on Clustering\u003c/h3\u003e\u003cp\u003eIf the \u003ccode class=\"literal\"\u003eUSING INDEX\u003c/code\u003e clause is specified, the rows in the table are physically rearranged according to the ordering implied by the specified index; this is known as \u003cem class=\"firstterm\"\u003eclustering\u003c/em\u003e. This can have performance implications: in cases where you are accessing single rows randomly within a table, the actual order of the data in the table is unimportant. However, if you tend to access some data more than others, and there is an index that groups them together, you will benefit from using clustering. If you are requesting a range of indexed values from a table, or a single indexed value that has multiple matching rows, clustering will help because once the index identifies the table page for the first row that matches, all other rows that match are probably already on the same table page, and so you save disk accesses and speed up the query.\u003c/p\u003e\u003cp\u003eFor B-Tree indexes, the ordering used by clustering is the index's linear sort order. Other clusterable index access methods may use a different ordering strategy, one which may not necessarily correspond to any SQL sort order. If an index name is specified in the command, that index is used and is recorded as the table's clustering index. (This also applies to an index given to the \u003ccode class=\"command\"\u003eCLUSTER\u003c/code\u003e command.) If no index name is specified, then the index that has been configured as the clustering one is used; if none has been configured, an error is thrown. An index can be set manually using \u003ccode class=\"command\"\u003eALTER TABLE ... CLUSTER ON\u003c/code\u003e, and reset with \u003ccode class=\"command\"\u003eALTER TABLE ... SET WITHOUT CLUSTER\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eClustering is a one-time operation: when the table is subsequently updated, the changes are not clustered. That is, no attempt is made to store new or updated rows according to the clustering order. (If one wishes, one can periodically recluster by issuing the command again. Also, setting the table's \u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e storage parameter to less than 100% can aid in preserving cluster ordering during updates, since updated rows are kept on the same page if enough space is available there.)\u003c/p\u003e\u003cp\u003eWhen clustering on a B-Tree index, \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e can rewrite the table using either an index scan on the specified index, or a sequential scan followed by sorting. It will attempt to choose the method that will be faster, based on planner cost parameters and available statistical information. When clustering on an index of an access method other than B-Tree, \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e always uses an index scan.\u003c/p\u003e\u003cp\u003eBecause the planner records statistics about the ordering of tables, it is advisable to specify the \u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e option, or to run \u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\"\u003e\u003ccode class=\"command\"\u003eANALYZE\u003c/code\u003e\u003c/a\u003e on the newly repacked table. Otherwise, the planner might make poor choices of query plans.\u003c/p\u003e\u003cp\u003eIf no table name is specified in \u003ccode class=\"command\"\u003eREPACK USING INDEX\u003c/code\u003e, all tables which have a clustering index defined and which the calling user has privileges for are processed.\u003c/p\u003e\u003c/div\u003e\u003cdiv class=\"refsect2\"\u003e\u003ch3\u003eNotes on Resources\u003c/h3\u003e\u003cp\u003eWhen 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.\u003c/p\u003e\u003cp\u003eWhen 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 \u003ca href=\"/docs/devel/runtime-config-query.html#GUC-ENABLE-SORT\"\u003eenable_sort\u003c/a\u003e to \u003ccode class=\"literal\"\u003eoff\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eIt is advisable to set \u003ca href=\"/docs/devel/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM\"\u003emaintenance_work_mem\u003c/a\u003e to a reasonably large value (but not more than the amount of RAM you can dedicate to the \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e operation) before repacking.\u003c/p\u003e\u003c/div\u003e","key":"description","title":"Description"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name (possibly schema-qualified) of a table.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name of a specific column to analyze. Defaults to all columns. If a column list is specific, \u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e must also be specified.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eindex_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name of an index.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAllow other transactions to use the table while it is being repacked.\u003c/p\u003e\u003cp\u003eInternally, \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 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 \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 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.\u003c/p\u003e\u003cp\u003eWith the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option, the \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 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 (\u003ca href=\"/docs/devel/logicaldecoding.html\" title=\"Chapter 47. Logical Decoding\"\u003eChapter 47\u003c/a\u003e) and applied before the \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 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 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e was waiting for the lock: those changes must be processed just before the files are swapped, while the \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e lock is being held.\u003c/p\u003e\u003cp\u003eNote that \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e with the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option does not try to order the rows inserted into the table after the repacking started. Also note \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e might fail to complete due to DDL commands executed on the table by other transactions during the repacking.\u003c/p\u003e\u003cdiv class=\"note\"\u003e\u003ch3\u003eNote\u003c/h3\u003e\u003cp\u003eIn addition to the temporary space requirements explained in \u003ca href=\"/docs/devel/sql-repack.html#SQL-REPACK-NOTES-ON-RESOURCES\" title=\"Notes on Resources\"\u003eNotes on Resources\u003c/a\u003e, the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 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 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 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.\u003c/p\u003e\u003c/div\u003e\u003cp\u003eThe \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option cannot be used in the following cases:\u003c/p\u003e\u003cdiv class=\"itemizedlist\"\u003e\u003cul class=\"itemizedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe relation is not a table (e.g., it is a materialized view).\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table is \u003ccode class=\"literal\"\u003eUNLOGGED\u003c/code\u003e.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table is partitioned.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table lacks a primary key and index-based replica identity.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table is a system catalog or a \u003cacronym\u003eTOAST\u003c/acronym\u003e table.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table's access method is not \u003ccode class=\"literal\"\u003eheap\u003c/code\u003e.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe table is declared as a catalog table using the \u003ca href=\"/docs/devel/sql-createtable.html#RELOPTION-USER-CATALOG-TABLE\"\u003e\u003ccode class=\"literal\"\u003euser_catalog_table\u003c/code\u003e\u003c/a\u003e storage parameter.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e is executed inside a transaction block.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eThe \u003ca href=\"/docs/devel/runtime-config-replication.html#GUC-MAX-REPACK-REPLICATION-SLOTS\"\u003e\u003ccode class=\"varname\"\u003emax_repack_replication_slots\u003c/code\u003e\u003c/a\u003e configuration parameter does not allow for the creation of an additional replication slot.\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e\u003cdiv class=\"warning\"\u003e\u003ch3\u003eWarning\u003c/h3\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e with the \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e option is not MVCC-safe, see \u003ca href=\"/docs/devel/mvcc-caveats.html\" title=\"13.6. Caveats\"\u003eSection 13.6\u003c/a\u003e for details.\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eVERBOSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003ePrints a progress report as each table is repacked at \u003ccode class=\"literal\"\u003eINFO\u003c/code\u003e level.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e\u003cbr\u003e\u003c/span\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eANALYSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eApplies \u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\"\u003e\u003cspan class=\"refentrytitle\"\u003eANALYZE\u003c/span\u003e\u003c/a\u003e 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 \u003ccode class=\"command\"\u003eDO\u003c/code\u003e block.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eSpecifies whether the selected option should be turned on or off. You can write \u003ccode class=\"literal\"\u003eTRUE\u003c/code\u003e, \u003ccode class=\"literal\"\u003eON\u003c/code\u003e, or \u003ccode class=\"literal\"\u003e1\u003c/code\u003e to enable the option, and \u003ccode class=\"literal\"\u003eFALSE\u003c/code\u003e, \u003ccode class=\"literal\"\u003eOFF\u003c/code\u003e, or \u003ccode class=\"literal\"\u003e0\u003c/code\u003e to disable it. The \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e value can also be omitted, in which case \u003ccode class=\"literal\"\u003eTRUE\u003c/code\u003e is assumed.\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"Parameters"},{"html":"\u003cp\u003eTo repack a table, one must have the \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e privilege on the table.\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e refuses to process a table on which an invalid index exists. Such indexes must be dropped or reindexed by the user ahead of time.\u003c/p\u003e\u003cp\u003eWhile \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e is running, the \u003ca href=\"/docs/devel/runtime-config-client.html#GUC-SEARCH-PATH\"\u003esearch_path\u003c/a\u003e is temporarily changed to \u003ccode class=\"literal\"\u003epg_catalog, pg_temp\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eEach backend running \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e will report its progress in the \u003ccode class=\"structname\"\u003epg_stat_progress_repack\u003c/code\u003e view. See \u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" title=\"27.4.5. REPACK Progress Reporting\"\u003eSection 27.4.5\u003c/a\u003e for details.\u003c/p\u003e\u003cp\u003eRepacking a partitioned table repacks each of its partitions. If an index is specified, each partition is repacked using the partition of that index. \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e on a partitioned table cannot be executed inside a transaction block.\u003c/p\u003e","key":"notes","title":"Notes"},{"html":"\u003cp\u003eRepack the table \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK employees;\n\u003c/pre\u003e\u003cp\u003eRepack the table \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e on the basis of its index \u003ccode class=\"literal\"\u003eemployees_ind\u003c/code\u003e (since an index is specified, this is effectively clustering):\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK employees USING INDEX employees_ind;\n\u003c/pre\u003e\u003cp\u003eRepack the \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e table following the same index as was used before, in concurrent mode:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (CONCURRENTLY) employees USING INDEX;\n\u003c/pre\u003e\u003cp\u003eRepack the table \u003ccode class=\"literal\"\u003ecases\u003c/code\u003e on physical ordering, running an \u003ccode class=\"command\"\u003eANALYZE\u003c/code\u003e on the given columns once repacking is done, showing informational messages:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (ANALYZE, VERBOSE) cases (district, case_nr);\n\u003c/pre\u003e\u003cp\u003eRepack all tables in the database on which you have the \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e privilege:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK;\n\u003c/pre\u003e\u003cp\u003eRepack all tables for which a clustering index has previously been configured on which you have the \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e privilege, showing informational messages:\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (VERBOSE) USING INDEX;\n\u003c/pre\u003e","key":"examples","title":"Examples"},{"html":"\u003cp\u003eThere is no \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e statement in the SQL standard.\u003c/p\u003e","key":"compatibility","title":"Compatibility"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" title=\"27.4.5. REPACK Progress Reporting\"\u003eSection 27.4.5\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"See Also"}],"sections_same_as":"","slug":"devel","synopsis_html":"REPACK [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e [, ...] ) ] [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_and_columns\u003c/code\u003e\u003c/em\u003e [ USING INDEX [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eindex_name\u003c/code\u003e\u003c/em\u003e ] ] ]\nREPACK [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e [, ...] ) ] USING INDEX\n\n\u003cspan class=\"phrase\"\u003ewhere \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e can be one of:\u003c/span\u003e\n\n    VERBOSE [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n    ANALYZE [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n    CONCURRENTLY [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n\n\u003cspan class=\"phrase\"\u003eand \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_and_columns\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) ]","synopsis_text":"REPACK [ ( option [, ...] ) ] [ table_and_columns [ USING INDEX [ index_name ] ] ]\nREPACK [ ( option [, ...] ) ] USING INDEX\n\nwhere option can be one of:\n\nVERBOSE [ boolean ]\nANALYZE [ boolean ]\nCONCURRENTLY [ boolean ]\n\nand table_and_columns is:\ntable_name [ ( column_name [, ...] ) ]"},"ManualEvidence":{},"MeasuredEvidence":{}},"Text":{"Collection":"sql","Key":"repack","SourceDatabase":"pgweb","Version":"20","Locale":"zh-Hans","Title":"REPACK","Summary":"重写表以回收磁盘空间","BodyHTML":"\u003cpre\u003eREPACK [ ( option [, ...] ) ] [ table_and_columns [ USING INDEX [ index_name ] ] ]\nREPACK [ ( option [, ...] ) ] USING INDEX\n\n其中 option 可以是以下之一：\n\nVERBOSE [ boolean ]\nANALYZE [ boolean ]\nCONCURRENTLY [ boolean ]\n\n而 table_and_columns 为：\ntable_name [ ( column_name [, ...] ) ]\u003c/pre\u003e\u003csection\u003e\u003ch2\u003e描述\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eREPACK\u003c/code\u003e 可回收被死元组占用的存储空间。与 \u003ccode\u003eVACUUM\u003c/code\u003e 不同，它通过将 \u003cem\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e 所指定表的全部内容重写到一个没有多余空间的新磁盘文件中来实现这一点（\u003ccode\u003efillfactor\u003c/code\u003e 存储参数所保证的空间除外），从而允许未使用的空间返回给操作系统。\u003c/p\u003e\u003cp\u003e如果没有指定 \u003cem\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e，\u003ccode\u003eREPACK\u003c/code\u003e 会处理当前数据库中当前用户具有 \u003ccode\u003eMAINTAIN\u003c/code\u003e 特权的每一张表和物化视图。此形式的 \u003ccode\u003eREPACK\u003c/code\u003e 不能在事务块中执行。如果使用了 \u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项，则也不允许使用这种形式。\u003c/p\u003e\u003cp\u003e如果指定了 \u003ccode\u003eUSING INDEX\u003c/code\u003e 子句，行会根据索引中的信息在物理上重新排序。有关聚簇的说明，请参见下文注记。\u003c/p\u003e\u003cp\u003e当对一个表执行重整时，会在该表上获取 \u003ccode\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁。这会阻止任何其他数据库操作（包括读和写）在 \u003ccode\u003eREPACK\u003c/code\u003e 完成前访问该表。如果希望在重整期间保持该表可访问，可以考虑使用 \u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项。\u003c/p\u003e\u003cdiv\u003e\u003ch3\u003e聚簇说明\u003c/h3\u003e\u003cp\u003e如果指定了 \u003ccode\u003eUSING INDEX\u003c/code\u003e 子句，表中的行会按指定索引隐含的顺序在物理上重新排列，这称为\u003cem\u003e聚簇\u003c/em\u003e。这可能影响性能：如果是在表内随机访问单行，那么表中数据的实际顺序并不重要。但如果更频繁地访问某些数据，并且有一个能把它们聚集在一起的索引，就能从聚簇中受益。如果从表中请求一个索引值范围，或者请求一个匹配多行的单个索引值，聚簇也会有所帮助，因为一旦索引确定了第一个匹配行所在的表页，其他匹配行很可能已经在同一个表页上，从而节省磁盘访问并加快查询。\u003c/p\u003e\u003cp\u003e对于 B-树索引，聚簇使用索引的线性排序顺序。其他支持聚簇的索引访问方法可能使用不同的排序策略，这种策略不一定对应任何 SQL 排序顺序。如果命令中指定了索引名，则使用该索引，并将其记录为该表的聚簇索引。（这同样适用于传给 \u003ccode\u003eCLUSTER\u003c/code\u003e 命令的索引。）如果未指定索引名，则使用已经被配置为聚簇索引的索引；如果没有这样的索引，就会报错。可以使用 \u003ccode\u003eALTER TABLE ... CLUSTER ON\u003c/code\u003e 手工设置索引，也可以使用 \u003ccode\u003eALTER TABLE ... SET WITHOUT CLUSTER\u003c/code\u003e 清除设置。\u003c/p\u003e\u003cp\u003e聚簇是一次性操作：表随后被更新时，这些更改不会继续保持聚簇。也就是说，并不会尝试根据聚簇顺序存储新行或更新后的行。（如果愿意，可以通过再次发出该命令来定期重新聚簇。此外，把表的 \u003ccode\u003efillfactor\u003c/code\u003e 存储参数设置为低于 100%，有助于在更新期间保持聚簇顺序，因为如果页面上有足够空间，更新后的行会保留在同一页面上。）\u003c/p\u003e\u003cp\u003e在 B-树索引上聚簇时，\u003ccode\u003eREPACK\u003c/code\u003e 可以通过在指定索引上进行索引扫描，或者先执行顺序扫描再排序，来重写表。它会根据规划器代价参数和可用的统计信息，尝试选择速度更快的方法。在使用 B-树以外的访问方法的索引上聚簇时，\u003ccode\u003eREPACK\u003c/code\u003e 始终使用索引扫描。\u003c/p\u003e\u003cp\u003e因为规划器会记录有关表中数据顺序的统计信息，建议指定 \u003ccode\u003eANALYZE\u003c/code\u003e 选项，或者在新近重整过的表上运行 \u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\" rel=\"nofollow\"\u003e\u003ccode\u003eANALYZE\u003c/code\u003e\u003c/a\u003e。否则，规划器可能会选择很差的查询计划。\u003c/p\u003e\u003cp\u003e如果在 \u003ccode\u003eREPACK USING INDEX\u003c/code\u003e 中没有指定表名，那么所有已经定义了聚簇索引、且调用用户有权限访问的表都会被处理。\u003c/p\u003e\u003c/div\u003e\u003cdiv\u003e\u003ch3\u003e资源说明\u003c/h3\u003e\u003cp\u003e当使用索引扫描，或者使用不带排序的顺序扫描时，会创建一个临时副本，其中包含按索引顺序排列的表数据。同时也会为表上的每个索引创建临时副本。因此，你需要至少等于表大小与索引大小之和的磁盘可用空间。\u003c/p\u003e\u003cp\u003e当使用顺序扫描加排序时，还会创建一个临时排序文件，因此峰值临时空间需求最多可达到表大小的两倍，再加上索引大小。这种方法通常比索引扫描方法更快，但如果磁盘空间要求无法接受，可以通过临时将\u003ca href=\"/docs/devel/runtime-config-query.html#GUC-ENABLE-SORT\" rel=\"nofollow\"\u003eenable_sort\u003c/a\u003e设为 \u003ccode\u003eoff\u003c/code\u003e 来禁用这种选择。\u003c/p\u003e\u003cp\u003e建议在重整之前，将\u003ca href=\"/docs/devel/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM\" rel=\"nofollow\"\u003emaintenance_work_mem\u003c/a\u003e设置为一个相当大的值（但不要超过你可为 \u003ccode\u003eREPACK\u003c/code\u003e 操作预留的内存总量）。\u003c/p\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e参数\u003c/h2\u003e\u003cdiv\u003e\u003cdl\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e表的名称（可以带模式限定）。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e要分析的特定列名称。默认是所有列。如果指定了列列表，则还必须同时指定 \u003ccode\u003eANALYZE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eindex_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e索引的名称。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eCONCURRENTLY\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e允许其他事务在重整期间使用该表。\u003c/p\u003e\u003cp\u003e在内部，\u003ccode\u003eREPACK\u003c/code\u003e 会把表内容（忽略死元组）复制到一个新文件中，并按指定索引排序，同时还会为每个索引创建一个新文件。然后它交换表及其所有索引的旧文件和新文件，并删除旧文件。需要 \u003ccode\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁，以确保处理过程中旧文件不会变化，因为这些变化会因交换而丢失。\u003c/p\u003e\u003cp\u003e使用 \u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项时，\u003ccode\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁只会在交换表文件和索引文件时获取。在创建新表和索引文件期间发生的数据更改会通过逻辑解码（\u003ca href=\"/docs/devel/logicaldecoding.html\" rel=\"nofollow\"\u003e第 47 章\u003c/a\u003e）捕获，并在请求 \u003ccode\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁之前应用。因此，该锁通常只会持有完成文件交换所需的时间，应该相当短。不过，如果 \u003ccode\u003eREPACK\u003c/code\u003e 等待锁期间对表做了太多数据更改，那么在持有 \u003ccode\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁时，必须先处理这些更改，然后才能交换文件，因此这段时间仍可能比较明显。\u003c/p\u003e\u003cp\u003e请注意，带 \u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项的 \u003ccode\u003eREPACK\u003c/code\u003e 不会尝试重新排列在重整开始之后插入到表中的行。还要注意，\u003ccode\u003eREPACK\u003c/code\u003e 可能会因为其他事务在重整期间对该表执行的 DDL 命令而无法完成。\u003c/p\u003e\u003cdiv\u003e\u003ch3\u003e注意\u003c/h3\u003e\u003cp\u003e除了\u003ca href=\"/docs/devel/sql-repack.html#SQL-REPACK-NOTES-ON-RESOURCES\" title=\"资源说明\" rel=\"nofollow\"\u003eNotes on Resources\u003c/a\u003e中解释的临时空间要求之外，\u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项还可能会稍微增加一些临时空间的使用。原因是，其他事务可以执行 DML 操作，而这些操作在 \u003ccode\u003eREPACK\u003c/code\u003e 复制完旧文件中的所有现有元组之前无法应用到新文件中。因此，在复制期间插入到旧文件中的那些元组也会被单独存储在一个临时文件中，直到它们能够被处理为止。\u003c/p\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项不能在以下情况下使用：\u003c/p\u003e\u003cdiv\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e该关系不是表（例如，它是物化视图）。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表是 \u003ccode\u003eUNLOGGED\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表是分区表。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表没有主键，也没有基于索引的复制标识。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表是系统目录或 \u003cacronym\u003eTOAST\u003c/acronym\u003e 表。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表的访问方法不是\u003ccode\u003eheap\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e该表通过\u003ca href=\"/docs/devel/sql-createtable.html#RELOPTION-USER-CATALOG-TABLE\" rel=\"nofollow\"\u003e\u003ccode\u003euser_catalog_table\u003c/code\u003e\u003c/a\u003e存储参数被声明为目录表。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eREPACK\u003c/code\u003e 在事务块中执行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"/docs/devel/runtime-config-replication.html#GUC-MAX-REPACK-REPLICATION-SLOTS\" rel=\"nofollow\"\u003e\u003ccode\u003emax_repack_replication_slots\u003c/code\u003e\u003c/a\u003e 配置参数不允许再创建一个额外的复制槽。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e\u003cdiv\u003e\u003ch3\u003e警告\u003c/h3\u003e\u003cp\u003e带 \u003ccode\u003eCONCURRENTLY\u003c/code\u003e 选项的 \u003ccode\u003eREPACK\u003c/code\u003e 不是 MVCC 安全的，详见\u003ca href=\"/docs/devel/mvcc-caveats.html\" rel=\"nofollow\"\u003e第 13.6 节\u003c/a\u003e。\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eVERBOSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e以 \u003ccode\u003eINFO\u003c/code\u003e 级别打印每个表被重整时的进度报告。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eANALYZE\u003c/code\u003e\u003cbr\u003e\u003c/span\u003e\u003cspan\u003e\u003ccode\u003eANALYSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e在重整表之后对该表执行\u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\" rel=\"nofollow\"\u003e\u003cspan\u003eANALYZE\u003c/span\u003e\u003c/a\u003e。目前这只在指定单个（非分区）表时受支持。此选项不能在事务块内使用，也不能从函数、过程或\u003ccode\u003eDO\u003c/code\u003e块中使用。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e指定所选选项应开启还是关闭。可以写 \u003ccode\u003eTRUE\u003c/code\u003e、\u003ccode\u003eON\u003c/code\u003e 或 \u003ccode\u003e1\u003c/code\u003e 来启用该选项，也可以写 \u003ccode\u003eFALSE\u003c/code\u003e、\u003ccode\u003eOFF\u003c/code\u003e 或 \u003ccode\u003e0\u003c/code\u003e 来禁用它。\u003cem\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e 值也可以省略，此时默认视为 \u003ccode\u003eTRUE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e说明\u003c/h2\u003e\u003cp\u003e要重整表，必须对该表具有 \u003ccode\u003eMAINTAIN\u003c/code\u003e 特权。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eREPACK\u003c/code\u003e拒绝处理存在无效索引的表。这类索引必须由用户提前删除或重建。\u003c/p\u003e\u003cp\u003e在 \u003ccode\u003eREPACK\u003c/code\u003e 运行期间，\u003ca href=\"/docs/devel/runtime-config-client.html#GUC-SEARCH-PATH\" rel=\"nofollow\"\u003esearch_path\u003c/a\u003e会临时改为 \u003ccode\u003epg_catalog, pg_temp\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e每个运行 \u003ccode\u003eREPACK\u003c/code\u003e 的后端都会在 \u003ccode\u003epg_stat_progress_repack\u003c/code\u003e 视图中报告其进度。有关详细信息，请参见\u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" rel=\"nofollow\"\u003e第 27.4.5 节\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e重整分区表时，会重整其每个分区。如果指定了索引，则每个分区都会使用该索引的分区来重整。对分区表执行 \u003ccode\u003eREPACK\u003c/code\u003e 不能在事务块中进行。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e示例\u003c/h2\u003e\u003cp\u003e重整表 \u003ccode\u003eemployees\u003c/code\u003e：\u003c/p\u003e\u003cpre\u003eREPACK employees;\n\u003c/pre\u003e\u003cp\u003e基于其索引 \u003ccode\u003eemployees_ind\u003c/code\u003e 重整表 \u003ccode\u003eemployees\u003c/code\u003e（由于指定了索引，这实际上就是聚簇）：\u003c/p\u003e\u003cpre\u003eREPACK employees USING INDEX employees_ind;\n\u003c/pre\u003e\u003cp\u003e以并发模式使用与之前相同的索引重整 \u003ccode\u003eemployees\u003c/code\u003e 表：\u003c/p\u003e\u003cpre\u003eREPACK (CONCURRENTLY) employees USING INDEX;\n\u003c/pre\u003e\u003cp\u003e按物理顺序重整表 \u003ccode\u003ecases\u003c/code\u003e，在重整完成后对给定列执行 \u003ccode\u003eANALYZE\u003c/code\u003e，并显示信息消息：\u003c/p\u003e\u003cpre\u003eREPACK (ANALYZE, VERBOSE) cases (district, case_nr);\n\u003c/pre\u003e\u003cp\u003e重整数据库中所有你具有 \u003ccode\u003eMAINTAIN\u003c/code\u003e 特权的表：\u003c/p\u003e\u003cpre\u003eREPACK;\n\u003c/pre\u003e\u003cp\u003e重整所有此前已配置聚簇索引、且你具有 \u003ccode\u003eMAINTAIN\u003c/code\u003e 特权的表，并显示信息消息：\u003c/p\u003e\u003cpre\u003eREPACK (VERBOSE) USING INDEX;\n\u003c/pre\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e兼容性\u003c/h2\u003e\u003cp\u003eSQL 标准中没有 \u003ccode\u003eREPACK\u003c/code\u003e 语句。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e另见\u003c/h2\u003e\u003cspan\u003e\u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" rel=\"nofollow\"\u003e第 27.4.5 节\u003c/a\u003e\u003c/span\u003e\u003c/section\u003e","SourceRevision":"1b5ca64c","ContentHash":"c085cc387c4e725688285e03adb09184c2cf172e2ad274469f33e7ee71cada0f","Payload":{"purpose_zh":"重写表以回收磁盘空间","sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 可回收被死元组占用的存储空间。与 \u003ccode class=\"command\"\u003eVACUUM\u003c/code\u003e 不同，它通过将 \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e 所指定表的全部内容重写到一个没有多余空间的新磁盘文件中来实现这一点（\u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e 存储参数所保证的空间除外），从而允许未使用的空间返回给操作系统。\u003c/p\u003e\u003cp\u003e如果没有指定 \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e，\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 会处理当前数据库中当前用户具有 \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e 特权的每一张表和物化视图。此形式的 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 不能在事务块中执行。如果使用了 \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项，则也不允许使用这种形式。\u003c/p\u003e\u003cp\u003e如果指定了 \u003ccode class=\"literal\"\u003eUSING INDEX\u003c/code\u003e 子句，行会根据索引中的信息在物理上重新排序。有关聚簇的说明，请参见下文注记。\u003c/p\u003e\u003cp\u003e当对一个表执行重整时，会在该表上获取 \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁。这会阻止任何其他数据库操作（包括读和写）在 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 完成前访问该表。如果希望在重整期间保持该表可访问，可以考虑使用 \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项。\u003c/p\u003e\u003cdiv class=\"refsect2\"\u003e\u003ch3\u003e聚簇说明\u003c/h3\u003e\u003cp\u003e如果指定了 \u003ccode class=\"literal\"\u003eUSING INDEX\u003c/code\u003e 子句，表中的行会按指定索引隐含的顺序在物理上重新排列，这称为\u003cem class=\"firstterm\"\u003e聚簇\u003c/em\u003e。这可能影响性能：如果是在表内随机访问单行，那么表中数据的实际顺序并不重要。但如果更频繁地访问某些数据，并且有一个能把它们聚集在一起的索引，就能从聚簇中受益。如果从表中请求一个索引值范围，或者请求一个匹配多行的单个索引值，聚簇也会有所帮助，因为一旦索引确定了第一个匹配行所在的表页，其他匹配行很可能已经在同一个表页上，从而节省磁盘访问并加快查询。\u003c/p\u003e\u003cp\u003e对于 B-树索引，聚簇使用索引的线性排序顺序。其他支持聚簇的索引访问方法可能使用不同的排序策略，这种策略不一定对应任何 SQL 排序顺序。如果命令中指定了索引名，则使用该索引，并将其记录为该表的聚簇索引。（这同样适用于传给 \u003ccode class=\"command\"\u003eCLUSTER\u003c/code\u003e 命令的索引。）如果未指定索引名，则使用已经被配置为聚簇索引的索引；如果没有这样的索引，就会报错。可以使用 \u003ccode class=\"command\"\u003eALTER TABLE ... CLUSTER ON\u003c/code\u003e 手工设置索引，也可以使用 \u003ccode class=\"command\"\u003eALTER TABLE ... SET WITHOUT CLUSTER\u003c/code\u003e 清除设置。\u003c/p\u003e\u003cp\u003e聚簇是一次性操作：表随后被更新时，这些更改不会继续保持聚簇。也就是说，并不会尝试根据聚簇顺序存储新行或更新后的行。（如果愿意，可以通过再次发出该命令来定期重新聚簇。此外，把表的 \u003ccode class=\"literal\"\u003efillfactor\u003c/code\u003e 存储参数设置为低于 100%，有助于在更新期间保持聚簇顺序，因为如果页面上有足够空间，更新后的行会保留在同一页面上。）\u003c/p\u003e\u003cp\u003e在 B-树索引上聚簇时，\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 可以通过在指定索引上进行索引扫描，或者先执行顺序扫描再排序，来重写表。它会根据规划器代价参数和可用的统计信息，尝试选择速度更快的方法。在使用 B-树以外的访问方法的索引上聚簇时，\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 始终使用索引扫描。\u003c/p\u003e\u003cp\u003e因为规划器会记录有关表中数据顺序的统计信息，建议指定 \u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e 选项，或者在新近重整过的表上运行 \u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\"\u003e\u003ccode class=\"command\"\u003eANALYZE\u003c/code\u003e\u003c/a\u003e。否则，规划器可能会选择很差的查询计划。\u003c/p\u003e\u003cp\u003e如果在 \u003ccode class=\"command\"\u003eREPACK USING INDEX\u003c/code\u003e 中没有指定表名，那么所有已经定义了聚簇索引、且调用用户有权限访问的表都会被处理。\u003c/p\u003e\u003c/div\u003e\u003cdiv class=\"refsect2\"\u003e\u003ch3\u003e资源说明\u003c/h3\u003e\u003cp\u003e当使用索引扫描，或者使用不带排序的顺序扫描时，会创建一个临时副本，其中包含按索引顺序排列的表数据。同时也会为表上的每个索引创建临时副本。因此，你需要至少等于表大小与索引大小之和的磁盘可用空间。\u003c/p\u003e\u003cp\u003e当使用顺序扫描加排序时，还会创建一个临时排序文件，因此峰值临时空间需求最多可达到表大小的两倍，再加上索引大小。这种方法通常比索引扫描方法更快，但如果磁盘空间要求无法接受，可以通过临时将\u003ca href=\"/docs/devel/runtime-config-query.html#GUC-ENABLE-SORT\"\u003eenable_sort\u003c/a\u003e设为 \u003ccode class=\"literal\"\u003eoff\u003c/code\u003e 来禁用这种选择。\u003c/p\u003e\u003cp\u003e建议在重整之前，将\u003ca href=\"/docs/devel/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM\"\u003emaintenance_work_mem\u003c/a\u003e设置为一个相当大的值（但不要超过你可为 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 操作预留的内存总量）。\u003c/p\u003e\u003c/div\u003e","key":"description","title":"描述"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e表的名称（可以带模式限定）。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e要分析的特定列名称。默认是所有列。如果指定了列列表，则还必须同时指定 \u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eindex_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e索引的名称。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e允许其他事务在重整期间使用该表。\u003c/p\u003e\u003cp\u003e在内部，\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 会把表内容（忽略死元组）复制到一个新文件中，并按指定索引排序，同时还会为每个索引创建一个新文件。然后它交换表及其所有索引的旧文件和新文件，并删除旧文件。需要 \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁，以确保处理过程中旧文件不会变化，因为这些变化会因交换而丢失。\u003c/p\u003e\u003cp\u003e使用 \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项时，\u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁只会在交换表文件和索引文件时获取。在创建新表和索引文件期间发生的数据更改会通过逻辑解码（\u003ca href=\"/docs/devel/logicaldecoding.html\" title=\"第 47 章 逻辑解码\"\u003e第 47 章\u003c/a\u003e）捕获，并在请求 \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁之前应用。因此，该锁通常只会持有完成文件交换所需的时间，应该相当短。不过，如果 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 等待锁期间对表做了太多数据更改，那么在持有 \u003ccode class=\"literal\"\u003eACCESS EXCLUSIVE\u003c/code\u003e 锁时，必须先处理这些更改，然后才能交换文件，因此这段时间仍可能比较明显。\u003c/p\u003e\u003cp\u003e请注意，带 \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项的 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 不会尝试重新排列在重整开始之后插入到表中的行。还要注意，\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 可能会因为其他事务在重整期间对该表执行的 DDL 命令而无法完成。\u003c/p\u003e\u003cdiv class=\"note\"\u003e\u003ch3\u003e注意\u003c/h3\u003e\u003cp\u003e除了\u003ca href=\"/docs/devel/sql-repack.html#SQL-REPACK-NOTES-ON-RESOURCES\" title=\"资源说明\"\u003eNotes on Resources\u003c/a\u003e中解释的临时空间要求之外，\u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项还可能会稍微增加一些临时空间的使用。原因是，其他事务可以执行 DML 操作，而这些操作在 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 复制完旧文件中的所有现有元组之前无法应用到新文件中。因此，在复制期间插入到旧文件中的那些元组也会被单独存储在一个临时文件中，直到它们能够被处理为止。\u003c/p\u003e\u003c/div\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项不能在以下情况下使用：\u003c/p\u003e\u003cdiv class=\"itemizedlist\"\u003e\u003cul class=\"itemizedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该关系不是表（例如，它是物化视图）。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表是 \u003ccode class=\"literal\"\u003eUNLOGGED\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表是分区表。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表没有主键，也没有基于索引的复制标识。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表是系统目录或 \u003cacronym\u003eTOAST\u003c/acronym\u003e 表。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表的访问方法不是\u003ccode class=\"literal\"\u003eheap\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e该表通过\u003ca href=\"/docs/devel/sql-createtable.html#RELOPTION-USER-CATALOG-TABLE\"\u003e\u003ccode class=\"literal\"\u003euser_catalog_table\u003c/code\u003e\u003c/a\u003e存储参数被声明为目录表。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 在事务块中执行。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e\u003ca href=\"/docs/devel/runtime-config-replication.html#GUC-MAX-REPACK-REPLICATION-SLOTS\"\u003e\u003ccode class=\"varname\"\u003emax_repack_replication_slots\u003c/code\u003e\u003c/a\u003e 配置参数不允许再创建一个额外的复制槽。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/div\u003e\u003cdiv class=\"warning\"\u003e\u003ch3\u003e警告\u003c/h3\u003e\u003cp\u003e带 \u003ccode class=\"literal\"\u003eCONCURRENTLY\u003c/code\u003e 选项的 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 不是 MVCC 安全的，详见\u003ca href=\"/docs/devel/mvcc-caveats.html\" title=\"13.6. 注意事项\"\u003e第 13.6 节\u003c/a\u003e。\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eVERBOSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e以 \u003ccode class=\"literal\"\u003eINFO\u003c/code\u003e 级别打印每个表被重整时的进度报告。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eANALYZE\u003c/code\u003e\u003cbr\u003e\u003c/span\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eANALYSE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e在重整表之后对该表执行\u003ca href=\"/docs/devel/sql-analyze.html\" title=\"ANALYZE\"\u003e\u003cspan class=\"refentrytitle\"\u003eANALYZE\u003c/span\u003e\u003c/a\u003e。目前这只在指定单个（非分区）表时受支持。此选项不能在事务块内使用，也不能从函数、过程或\u003ccode class=\"command\"\u003eDO\u003c/code\u003e块中使用。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e指定所选选项应开启还是关闭。可以写 \u003ccode class=\"literal\"\u003eTRUE\u003c/code\u003e、\u003ccode class=\"literal\"\u003eON\u003c/code\u003e 或 \u003ccode class=\"literal\"\u003e1\u003c/code\u003e 来启用该选项，也可以写 \u003ccode class=\"literal\"\u003eFALSE\u003c/code\u003e、\u003ccode class=\"literal\"\u003eOFF\u003c/code\u003e 或 \u003ccode class=\"literal\"\u003e0\u003c/code\u003e 来禁用它。\u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e 值也可以省略，此时默认视为 \u003ccode class=\"literal\"\u003eTRUE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"参数"},{"html":"\u003cp\u003e要重整表，必须对该表具有 \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e 特权。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e拒绝处理存在无效索引的表。这类索引必须由用户提前删除或重建。\u003c/p\u003e\u003cp\u003e在 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 运行期间，\u003ca href=\"/docs/devel/runtime-config-client.html#GUC-SEARCH-PATH\"\u003esearch_path\u003c/a\u003e会临时改为 \u003ccode class=\"literal\"\u003epg_catalog, pg_temp\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e每个运行 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 的后端都会在 \u003ccode class=\"structname\"\u003epg_stat_progress_repack\u003c/code\u003e 视图中报告其进度。有关详细信息，请参见\u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" title=\"27.4.5. REPACK 进度报告\"\u003e第 27.4.5 节\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e重整分区表时，会重整其每个分区。如果指定了索引，则每个分区都会使用该索引的分区来重整。对分区表执行 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 不能在事务块中进行。\u003c/p\u003e","key":"other","title":"说明"},{"html":"\u003cp\u003e重整表 \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK employees;\n\u003c/pre\u003e\u003cp\u003e基于其索引 \u003ccode class=\"literal\"\u003eemployees_ind\u003c/code\u003e 重整表 \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e（由于指定了索引，这实际上就是聚簇）：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK employees USING INDEX employees_ind;\n\u003c/pre\u003e\u003cp\u003e以并发模式使用与之前相同的索引重整 \u003ccode class=\"literal\"\u003eemployees\u003c/code\u003e 表：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (CONCURRENTLY) employees USING INDEX;\n\u003c/pre\u003e\u003cp\u003e按物理顺序重整表 \u003ccode class=\"literal\"\u003ecases\u003c/code\u003e，在重整完成后对给定列执行 \u003ccode class=\"command\"\u003eANALYZE\u003c/code\u003e，并显示信息消息：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (ANALYZE, VERBOSE) cases (district, case_nr);\n\u003c/pre\u003e\u003cp\u003e重整数据库中所有你具有 \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e 特权的表：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK;\n\u003c/pre\u003e\u003cp\u003e重整所有此前已配置聚簇索引、且你具有 \u003ccode class=\"literal\"\u003eMAINTAIN\u003c/code\u003e 特权的表，并显示信息消息：\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eREPACK (VERBOSE) USING INDEX;\n\u003c/pre\u003e","key":"examples","title":"示例"},{"html":"\u003cp\u003eSQL 标准中没有 \u003ccode class=\"command\"\u003eREPACK\u003c/code\u003e 语句。\u003c/p\u003e","key":"compatibility","title":"兼容性"},{"html":"\u003cspan class=\"simplelist\"\u003e\u003ca href=\"/docs/devel/progress-reporting.html#REPACK-PROGRESS-REPORTING\" title=\"27.4.5. REPACK 进度报告\"\u003e第 27.4.5 节\u003c/a\u003e\u003c/span\u003e","key":"see_also","title":"另见"}],"sections_same_as":"","synopsis_html":"REPACK [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e [, ...] ) ] [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_and_columns\u003c/code\u003e\u003c/em\u003e [ USING INDEX [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eindex_name\u003c/code\u003e\u003c/em\u003e ] ] ]\nREPACK [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e [, ...] ) ] USING INDEX\n\n\u003cspan class=\"phrase\"\u003e其中 \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoption\u003c/code\u003e\u003c/em\u003e 可以是以下之一：\u003c/span\u003e\n\n    VERBOSE [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n    ANALYZE [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n    CONCURRENTLY [ \u003cem class=\"replaceable\"\u003e\u003ccode\u003eboolean\u003c/code\u003e\u003c/em\u003e ]\n\n\u003cspan class=\"phrase\"\u003e而 \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_and_columns\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003etable_name\u003c/code\u003e\u003c/em\u003e [ ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) ]","synopsis_text":"REPACK [ ( option [, ...] ) ] [ table_and_columns [ USING INDEX [ index_name ] ] ]\nREPACK [ ( option [, ...] ) ] USING INDEX\n\n其中 option 可以是以下之一：\n\nVERBOSE [ boolean ]\nANALYZE [ boolean ]\nCONCURRENTLY [ boolean ]\n\n而 table_and_columns 为：\ntable_name [ ( column_name [, ...] ) ]"}},"RequestedLocale":"zh-Hans","Fallback":false,"Versions":["19","20"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
