pg_repack报“must be superuser to use”错误是因为其命令行工具和数据库扩展均强制要求superuser权限,即使已创建扩展,调用时仍校验;非superuser需加--no-superuser-check(不推荐),rds等云环境须确认高权限账号开启。

pg_repack 能在线释放表的物理空间,但必须满足主键或唯一索引、足够磁盘空间、超级用户权限这三个硬性条件,否则直接报错退出。
为什么 pg_repack 会报 “must be superuser to use” 错误
这是最常卡住的第一步。pg_repack 命令行工具和数据库内扩展都要求执行用户具备 SUPERUSER 权限,哪怕你用 CREATE EXTENSION pg_repack 成功了,命令行调用时仍会校验权限。
- 非 superuser 用户必须加
--no-superuser-check参数(不推荐,有功能限制) - 在 RDS 或云服务上,部分实例默认禁用 superuser,需确认是否已开启高权限账号或联系平台支持
- 即使你是表所有者,没有
SUPERUSER也会失败 ——pg_repack不接受OWNER级别降级
表必须有主键或 NOT NULL 的唯一索引
pg_repack 依赖唯一排序键来保证数据迁移顺序和一致性。没有它,连第一步日志表同步都会失败,报错类似 ERROR: no primary key or unique index found。
- 检查语句:
SELECT constraint_name, constraint_type FROM information_schema.table_constraints WHERE table_name = 'your_table'; - 临时补救:添加
ALTER TABLE your_table ADD PRIMARY KEY (id);(确保id列无 NULL 且唯一) - 不能用普通索引替代;
UNIQUE索引也必须建在NOT NULL列上
执行全表重组并真正释放磁盘空间
仅运行 pg_repack 命令本身不会立即腾出空间 —— 它只是把数据搬到新表,旧表残留仍占空间,直到原子交换完成且 WAL 刷盘后系统才回收。
- 基础命令:
pg_repack -d your_db -t your_table -U postgres -h localhost -p 5432 - 加
--no-order可跳过按主键排序(节省时间,但无法恢复聚集顺序) - 指定表空间迁移:
--tablespace new_tspace --moveidx,避免原表空间写满 - 大表务必加
-j 4(并行度),否则单线程同步日志可能拖慢 replay 阶段 - 执行中查进度:
SELECT query FROM pg_stat_activity WHERE query LIKE '%pg_repack%';
容易被忽略的关键点
最后阶段交换表名是原子操作,但会生成大量 WAL,可能瞬间打满 wal_keep_size 或触发从库延迟;如果表上有长事务未结束,pg_repack 会一直等待,表现为卡在 “waiting for concurrent transactions to finish”。
- 运行前先查:
SELECT pid, now() - backend_start, state, query FROM pg_stat_activity WHERE state = 'active' AND query NOT ILIKE '%pg_repack%'; - 磁盘空间不是“1倍表大小”就够 —— 是“表 + 所有索引”的总大小再乘以 2,很多线上事故源于只算了主表
- 完成后立刻执行
VACUUM ANALYZE your_table;,否则查询计划器仍可能沿用旧统计信息










