更新时间:2024-09-05 GMT+08:00

使用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插件清理表。

  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 常见报错信息及解决方案

详细报错信息

解决方案

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会等待事务执行完成。