pg_restore的-j参数仅对-Fd和-Fc格式备份有效,因其将对象拆分为独立文件或归档条目以支持并发调度;-Fp为单SQL文件,无法并行。

pg_restore 支持并行恢复,但不是所有场景都能开多线程——它只对 -Fd(目录格式)和 -Fc(自定义格式)备份有效,且必须配合 -j 参数;用 -Fp(纯 SQL)时加 -j 会被忽略,还可能报错。
为什么 -j 只在 -Fd / -Fc 下生效
因为只有这两种格式把表、索引、函数等对象拆成独立文件或归档条目,pg_restore 才能真正并发调度。而 -Fp 是单一大 SQL 文件,顺序执行 INSERT / CREATE 语句,没法拆分任务。
- 你用
pg_dump -Fc mydb > backup.dump或pg_dump -Fd mydb -f backup_dir生成的备份,才具备并行基础 - 如果误用
pg_dump -Fp mydb > backup.sql,后续无论加不加-j 4,都只会单线程执行 - 检查备份类型:运行
pg_restore -l backup.dump | head -5,能看到 TOC 表;而head backup.sql显示的是 SQL 语句
实际并行恢复命令怎么写
核心是三要素:格式匹配 + 并发数合理 + 连接资源到位。下面是最常用安全写法:
pg_restore -h localhost -p 5777 -U pguser -d targetdb -j 4 -v backup_dir/
-
-j 4表示启用 4 个并行 job,建议 ≤ 服务器 vCPU 数(如 8 核机器最多设-j 8) - 必须用目录路径(
backup_dir/)或.dump文件(backup.dump),不能是.sql -
-v建议加上,方便看到哪个对象卡住或失败 - 如果目标库已存在且要清空重来,加
-c(drop 再建),但注意它不加IF EXISTS,若对象不存在会报错;可补--if-exists
容易被忽略的性能瓶颈和坑
并行数设高 ≠ 恢复更快,反而可能因资源争抢拖慢整体速度。真实瓶颈常在以下几处:
-
数据库连接数不够:
-j 4实际需要至少 5 个连接(1 主控 + 4 worker),检查max_connections是否 ≥j + 1,否则进程会卡在“waiting for connection” -
磁盘 I/O 吃紧:SSD 上
-j 4~6通常最优;机械盘上-j 2可能比-j 4更快,因寻道延迟翻倍 -
shared_buffers 和 maintenance_work_mem 太小:恢复过程大量用到排序和哈希,
maintenance_work_mem建议设为 512MB~2GB(根据内存总量按 10%~25% 配) -
没关 fsync:临时恢复库可加
-o "fsync=off"(即pg_restore --no-sync),但仅限可信环境;生产恢复后务必手动pg_switch_wal()并验证
最后提醒一句:并行恢复不会自动处理依赖顺序(比如外键、物化视图刷新),如果备份里有复杂依赖,-j 越大越容易遇到 ERROR: insert or update on table "xxx" violates foreign key constraint。这时得先用 -s 导出结构,手工删掉约束,恢复完再加回去。


















