
# 使用pg_repack插件
#### 操作场景
pg_repack可以使用最小的锁资源来重新整理表和索引的物理页面，从而实现物理页面的碎片整理。相较于使用cluster和vacuum full重写表，pg_repack不需要在整个处理期间持有表级排他锁，因此能提供近似的在线服务。
#### 约束限制
- 只有root用户才能使用pg_repack。
- 目标表必须存在主键，或在非空列上存在唯一索引。
- 至少需要两倍于目标表（及索引）的磁盘空间。
- 无法在temp表和存在gist索引的表上操作。
- 在pg_repack运行期间，目标表上不能执行除vacuum和analyze之外的任何DDL指令。
- 需要在本地部署客户端才能使用pg_repack，详见官方文档： <https://reorg.github.io/pg_repack/>。
 
#### 插件使用
- 安装插件
  ```
  select control_extension('create', 'pg_repack');
  ```
  
- 删除插件
  ```
  select control_extension('drop', 'pg_repack');
  ```
  
更多信息，请参见[通过界面安装和卸载插件](https://support.huaweicloud.com/usermanual-rds-pg/rds_09_0070.html)和[通过SQL命令安装和卸载插件](https://support.huaweicloud.com/usermanual-rds-pg/rds_09_0043.html)。
#### 使用示例
使用pg_repack插件清理表。
1. **创建测试表**
   ```
   create table pg_repack_test(id bigint primary key, name varchar);
   ```
   ```
   insert into pg_repack_test select i , to_char(random()*100000, 'FM000000') from generate_series(1, 1000000) i;
   ```
   ```
   delete from pg_repack_test where id in (select i  from generate_series(1, 600000, 2) i);
   ```
   ```
   select pg_size_pretty(pg_relation_size('pg_repack_test'));
   ```
   
2. **清理测试表**
   ```
   pg_repack --host=<RDS_ADDRESS> --port=<DB_PORT> --dbname=<DB_NAME> --username=root --no-superuser-check --no-kill-backend -t pg_repack_test
   ```
   - RDS_ADDRESS：RDS实例的IP地址。
   
   - DB_PORT：数据库实例的端口。
   
   - DB_NAME：表pg_repack_test所在的数据库。
    
3. **查看清理后的表大小**
   ```
   select pg_size_pretty(pg_relation_size('pg_repack_test'));
   ```
   
 
#### 常见问题
表1常见报错信息及解决方案 
| 使用pg_repack报错信息                                                                                                 | 解决方案                                                  |
|:---|:---|
| ERROR: pg_repack failed with error: ERROR: permission denied for schema repack                                  | 需要使用root用户执行才能执行pg_repack。                            |
| ERROR: pg_repack failed with error: You must be a superuser to use pg_repack                                    | 执行pg_repack时加上--no-superuser-check，跳过超级用户检查。          |
| NOTICE: Waiting for 1 transactions to finish. First PID: xxxx                                                   | 清理过程中有长事务，pg_repack会等待事务执行完成。                         |
| ERROR: pg_repack failed with error: program 'pg_repack 1.5.2' does not match database library 'pg_repack 1.5.0' | 使pg_repack客户端工具版本与PostgreSQL服务器上安装的pg_repack插件版本保持一致。 |
   
