

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 pg\_repack 移除膨胀
<a name="pg-repack"></a>

您可以使用 `pg_repack` 扩展程序以最少的数据库锁定来移除表和索引膨胀。您可以在数据库实例中创建此扩展程序，然后从 Amazon Elastic Compute Cloud（Amazon EC2）或可以连接到您的数据库的计算机上运行 `pg_repack` 客户端（客户端版本与扩展版本相匹配的位置）。

与 `VACUUM FULL` 不同的是，`pg_repack` 不需要停机时间或维护窗口，也不会阻止其他会话。

`pg_repack` 在 `VACUUM FULL`、`CLUSTER`、或 `REINDEX` 可能不起作用的情况下起到帮助作用。它会创建一个包含膨胀表数据的新表，跟踪原始表中的更改，然后用新表替换原始表。在构建新表时，它不会锁定原始表来防止读取或写入操作。

您可以将 `pg_repack` 用于完整表或索引。要查看任务列表，请参阅 [pg\_repack 文档](https://reorg.github.io/pg_repack/)。

限制：
+ 要运行 `pg_repack`，您的表必须具有主键或唯一索引。
+ `pg_repack ` 不适用于临时表。
+ `pg_repack` 不适用于具有全局索引的表。
+ 当 `pg_repack` 正在进行时，您不能对表执行 DDL 操作。

下表介绍了 `pg_repack` 与 `VACUUM FULL` 之间的区别。


|  |  | 
| --- |--- |
| `VACUUM FULL` | `pg_repack` | 
| 内置命令 | 您从 Amazon EC2 或本地计算机中运行的扩展程序 | 
| 对表格执行操作时需要 `ACCESS EXCLUSIVE` 锁 | 仅在短时间内需要 `ACCESS EXCLUSIVE` 锁 | 
| 适用于所有表 | 适用于仅具有主键和唯一键的表 | 
| 所需存储空间是表和索引所消耗空间的两倍 | 所需存储空间是表和索引所消耗空间的两倍 | 

要在表上运行 `pg_repack`，请使用以下命令：

```
pg_repack -h <host> -d <dbname> --table <tablename> -k
```

要在索引上运行 `pg_repack`，请使用以下命令：

```
pg_repack -h <host> -d <dbname> --index <index name>
```

有关更多信息，请参阅 AWS 博客文章[使用 pg\_repack 移除 Amazon Aurora 和 RDS for PostgreSQL 中的膨胀](https://aws.amazon.com/blogs/database/remove-bloat-from-amazon-aurora-and-rds-for-postgresql-with-pg_repack/)。

**注意事项**  
`pg_repack` 中的 `error-on-invalid-index` 错误通常意味着表中的一个或多个索引已损坏或无效。`pg_repack` 无法安全地对具有无效索引的表进行操作，因为它在重新打包过程中依赖索引来保持数据一致性。  
此错误发生在以下情况下：  
索引被标记为无效（例如，由于 `CREATE INDEX CONCURRENTLY` 语句失败）。
索引损坏（可能是由于硬件问题或突然关闭所致）。
使用以下查询来识别无效的索引，并在找到无效索引时先将其删除。  

```
SELECT indexrelid::regclass, indisvalid FROM pg_index WHERE indrelid = 'orders'::regclass AND NOT indisvalid; Drop the invalid index: DROP INDEX index_name;
```