使用pg_repack插件
操作场景
pg_repack可以使用最小的锁资源来重新整理表和索引的物理页面,从而实现物理页面的碎片整理。相较于使用cluster和vacuumn 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');
更多信息,请参见通过界面安装和卸载插件和通过SQL命令安装和卸载插件。
使用示例
使用pg_repack插件清理表。
- 创建测试表
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'));
- 清理测试表
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所在的数据库。
- 查看清理后的表大小
select pg_size_pretty(pg_relation_size('pg_repack_test'));
常见问题
详细报错信息 |
解决方案 |
---|---|
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会等待事务执行完成。 |