SQL COMMAND · 其它对象
REPACK
重写表以回收磁盘空间
REPACK其它对象引入 19现存至 20 devel0 次语法变更
- 动词
REPACK- 对象
—- 分组
- 其它对象
- 引入版本
- 19
- 状态
- 现存
- 语法变更次数
- 0
- 手册小节数
- 6
版本轨迹
相对 PostgreSQL 19 语法未变,正文有更新。
PostgreSQL 20 devel 尚未正式发布;本页来自对应手册快照,内容仍可能变化。
语法铁道图 PostgreSQL 20
沿轨道从左向右阅读,分岔表示选择,绕行表示可选,回环表示重复。方框为参数,点击带下划线的参数可展开子规则。
REPACK · 语法 2
option
table_and_columns
语法概要
REPACK [ (option[, ...] ) ] [table_and_columns[ USING INDEX [index_name] ] ] REPACK [ (option[, ...] ) ] USING INDEX 其中option可以是以下之一: VERBOSE [boolean] ANALYZE [boolean] CONCURRENTLY [boolean] 而table_and_columns为:table_name[ (column_name[, ...] ) ]
描述
REPACK 可回收被死元组占用的存储空间。与 VACUUM 不同,它通过将 table_name 所指定表的全部内容重写到一个没有多余空间的新磁盘文件中来实现这一点 (fillfactor 存储参数所保证的空间除外),从而允许未使用的空间返回给操作系统。
如果没有指定 table_name,REPACK 会处理当前数据库中当前用户具有 MAINTAIN 特权的每一张表和物化视图。此形式的 REPACK 不能在事务块中执行。 如果使用了 CONCURRENTLY 选项,则也不允许使用这种形式。
如果指定了 USING INDEX 子句,行会根据索引中的信息在物理上重新排序。有关聚簇的说明,请参见下文注记。
当对一个表执行重整时,会在该表上获取 ACCESS EXCLUSIVE 锁。这会阻止任何其他数据库操作(包括读和写) 在 REPACK 完成前访问该表。 如果希望在重整期间保持该表可访问,可以考虑使用 CONCURRENTLY 选项。
聚簇说明
如果指定了 USING INDEX 子句,表中的行会按该索引指定的顺序存储;由于行会随后在物理上聚簇,因此称为 聚簇。 如果命令中指定了索引名,则使用该索引隐含的顺序,并将该索引配置为聚簇所用的索引。 (这同样适用于传给 CLUSTER 命令的索引。) 如果未指定索引名,则使用已经被配置为聚簇索引的索引;如果没有这样的索引,就会报错。 可以使用 ALTER TABLE ... CLUSTER ON 手工设置索引,也可以使用 ALTER TABLE ... SET WITHOUT CLUSTER 清除设置。
如果在 REPACK USING INDEX 中没有指定表名,那么所有已经定义了聚簇索引、且调用用户有权限访问的表都会被处理。
聚簇是一次性 操作:表随后被更新时,这些更改不会继续保持聚簇。也就是说,并不会尝试根据索引顺序存储新行或更新后的行。(如果愿意,可以通过 再次发出该命令来定期重新聚簇。此外,把表的 fillfactor 存储参数设置为低于 100%,有助于在更新期间保持聚簇顺序,因为如果 页面上有足够空间,更新后的行会保留在同一页面上。)
如果你是在表内随机访问单行,那么表中数据的实际顺序并不重要。 但如果你倾向于更频繁地访问某些数据,并且有一个能把它们分组在一起的索引,那么使用聚簇就会受益。 如果你从表中请求一个索引值范围,或者请求一个匹配多行的单个索引值,聚簇会有所帮助,因为一旦索引确定了第一个匹配行所在的表页,其他匹配行很可能已经在同一个表页上,因此可以节省磁盘访问并加快查询。
REPACK 可以通过在指定索引上进行索引扫描(如果该索引是 B-树),或者 先执行顺序扫描再排序,来对表重新排序。它会 根据规划器代价参数和可用的统计信息,尝试选择速度更快的方法。
因为规划器会记录有关表中数据顺序的统计信息,建议在新近重整过的表上 运行ANALYZE。 否则,规划器可能会选择很差的查询计划。
资源说明
当使用索引扫描,或者使用不带排序的顺序扫描时,会创建一个临时副本,其中包含按索引顺序排列的表数据。 同时也会为表上的每个索引创建临时副本。因此,你需要至少等于表大小与索引大小之和的磁盘可用空间。
当使用顺序扫描加排序时,还会创建一个临时排序文件,因此峰值临时空间需 求最多可达到表大小的两倍,再加上索引大小。这种方法通常比索引扫 描方法更快,但如果磁盘空间要求无法接受,可以通过临时将 enable_sort 设为 off 来禁用这种选择。
建议在重整之前,将 maintenance_work_mem 设置为一 个相当大的值(但不要超过你可为 REPACK 操作预留的 内存总量)。
参数
table_name表的名称(可以带模式限定)。
column_name要分析的特定列名称。默认是所有列。如果指定了列列表,则还必须同时指定
ANALYZE。index_name索引的名称。
CONCURRENTLY允许其他事务在重整期间使用该表。
在内部,
REPACK会把表内容(忽略死元组)复制到一个新文件中,并按指定索引排序,同时还会为每个索引创建一个新文件。 然后它交换表及其所有索引的旧文件和新文件,并删除旧文件。需要ACCESS EXCLUSIVE锁,以确保处理过程中旧文件不会变化,因为这些变化会因交换而丢失。使用
CONCURRENTLY选项时,ACCESS EXCLUSIVE锁只会在交换表文件和索引文件时获取。 在创建新表和索引文件期间发生的数据更改会通过逻辑解码(Chapter 47)捕获,并在请求ACCESS EXCLUSIVE锁之前应用。 因此,该锁通常只会持有完成文件交换所需的时间,应该相当短。 不过,如果REPACK等待锁期间对表做了太多数据更改,那么在持有ACCESS EXCLUSIVE锁时,必须先处理这些更改,然后才能交换文件,因此这段时间仍可能比较明显。请注意,带
CONCURRENTLY选项的REPACK不会尝试重新排列在重整开始之后插入到表中的行。 还要注意,REPACK可能会因为其他事务在重整期间对该表执行的 DDL 命令而无法完成。Note
除了 Notes on Resources 中解释的临时空间要求之外,
CONCURRENTLY选项还可能会稍微增加一些临时空间的使用。 原因是,其他事务可以执行 DML 操作,而这些操作在REPACK复制完旧文件中的所有现有元组之前无法应用到新文件中。 因此,在复制期间插入到旧文件中的那些元组也会被单独存储在一个临时文件中,直到它们能够被处理为止。CONCURRENTLY选项不能在以下情况下使用:该表是
UNLOGGED。该表是分区表。
该表没有主键,也没有基于索引的副本身份。
该表是系统目录或 TOAST 表。
该表的访问方法不是
heap。该表通过
user_catalog_table存储参数被声明为目录表。REPACK在事务块中执行。max_repack_replication_slots配置参数不允许再创建一个额外的复制槽。
Warning
带
CONCURRENTLY选项的REPACK不是 MVCC 安全的,详见 Section 13.6。VERBOSE以
INFO级别打印每个表被重整时的进度报告。ANALYZEANALYSE在重整表之后对该表执行 ANALYZE。目前这只在指定单个(非分区)表时受支持。 此选项不能在事务块内使用,也不能从函数、过程或
DO块中使用。boolean指定所选选项应开启还是关闭。可以写
TRUE、ON或1来启用该选项,也可以写FALSE、OFF或0来禁用它。boolean值也可以省略,此时默认视为TRUE。
说明
要重整表,必须对该表具有 MAINTAIN 特权。
在 REPACK 运行期间,search_path 会临时改为 pg_catalog, pg_temp。
每个运行 REPACK 的后端都会在 pg_stat_progress_repack 视图中报告其进度。有关详细信息,请参见 Section 27.4.3。
重整分区表时,会重整其每个分区。如果指定了索引,则每个分区都会使用该索引的分区来重整。对分区表执行 REPACK 不能在事务块中进行。
示例
重整表 employees:
REPACK employees;
基于其索引 employees_ind 重整表 employees(由于指定了索引,这实际上就是聚簇):
REPACK employees USING INDEX employees_ind;
以并发模式使用之前相同的索引重整 employees 表:
REPACK (CONCURRENTLY) employees USING INDEX;
按物理顺序重整表 cases,在重整完成后对给定列执行 ANALYZE,并显示信息消息:
REPACK (ANALYZE, VERBOSE) cases (district, case_nr);
重整数据库中所有你具有 MAINTAIN 特权的表:
REPACK;
重整所有此前已配置聚簇索引、且你具有 MAINTAIN 特权的表,并显示信息消息:
REPACK (VERBOSE) USING INDEX;
兼容性
SQL 标准中没有 REPACK 语句。
另见
语法演化
相邻大版本之间的差异,新的在前。版本号链接到对应快照。
PostgreSQL 20← 19正文更新
正文更新PostgreSQL 19← 18新增此命令
同组命令
| 命令 | 动词 | 对象 | 版本变动 | 最近变更 |
|---|---|---|---|---|
COMMENT | COMMENT | — | 203 次 | |
| 定义或修改对象的注释 | 现存 | |||
REPACK | REPACK | — | — | |
| 重写表以回收磁盘空间 | 现存 | |||
ALTER LARGE OBJECT | ALTER | LARGE OBJECT | 141 次 | |
| 更改一个大对象的定义 | 现存 | |||
CREATE PROPERTY GRAPH | CREATE | PROPERTY GRAPH | — | |
| 定义一个新的 SQL 属性图 | 于 20 移除 | |||
ALTER PROPERTY GRAPH | ALTER | PROPERTY GRAPH | — | |
| 更改 SQL 属性图的定义 | 于 20 移除 | |||
DROP PROPERTY GRAPH | DROP | PROPERTY GRAPH | — | |
| 删除 SQL 属性图 | 于 20 移除 | |||