必须用-Fd目录格式+ -j并行+ -Z压缩,因-Fp纯文本不支持并行(-j无效且报错),-Fc虽支持并行但压缩为整体打包;-Fd将对象拆为独立文件,可真正并行读写与逐文件压缩,恢复粒度细、内存占用低。

对大型数据库做并发压缩导出,必须用 -Fd(directory)格式 + -j 并行 + -Z 压缩,-Fp(纯文本)不支持并行,-Fc 支持并行但压缩是整体打包,无法在 dump 过程中逐文件压缩。
为什么不能用 -Fp 做并发导出
纯文本格式(-Fp 或默认)本质是单流 SQL 输出,-j 参数对其完全无效 —— 执行时会直接报错或静默忽略。即使加了 -j 4,实际仍是单线程写入一个大 SQL 文件,毫无提速效果。很多用户卡在这一步,反复调参却没变化,根源就在这里。
常见错误现象:pg_dump: warning: ignoring --jobs option with plain format
-
-Fp只适合小库、调试、需人工审阅 SQL 的场景 - 它生成的文件不可被
pg_restore使用,恢复只能靠psql - 不支持按对象选择性恢复(比如只恢复某张表)
-Fd 目录格式 + -j 并行的实际效果
目录格式把每个表、序列、函数等拆成独立文件,-j 让 pg_dump 启动多个 worker 进程并行读取和写入这些文件,I/O 和 CPU 利用率明显提升。实测在 32 核机器上,-j 16 比 -j 1 快 5–8 倍(取决于磁盘随机读性能)。
使用要点:
- 目标路径必须是**空目录**,pg_dump 不会清空已有内容,冲突直接报错
-
-j值建议设为 CPU 核心数的 0.75 倍(如 24 核配-j 18),避免过度争抢 I/O - 必须搭配
-f指向目录路径,例如-f /backup/mydb_20260930,不能是文件名 - 导出后整个目录就是备份单元,不能只拷其中几个文件
压缩不是加个 -Z 就完事
-Z 只对 -Fc 和 -Fd 生效,且行为不同:
-
-Fc -Z 9:整个归档文件被 gzip 压缩,恢复时需解压全部再读取 -
-Fd -Z 9:每个内部文件单独压缩(如2578.dat.gz),pg_restore恢复时按需解压,内存占用低、恢复更灵活
所以对大型库,-Fd -Z 6 是更优组合 —— 并行快 + 压缩比合理 + 恢复粒度细。别用 -Z 9,压缩时间陡增但体积只省 3%~5%,不值。
示例命令:
pg_dump -h db-prod -U backup_user -d my_large_db \ -Fd -j 12 -Z 6 \ -f /backup/my_large_db_$(date +%Y%m%d) \ --lock-wait-timeout=30s \ --verbose
容易被忽略的权限与锁问题
大型库导出期间若遇到长事务或 DDL,pg_dump 默认会卡在锁等待上,直到超时失败。必须显式加 --lock-wait-timeout,否则半夜跑备份突然中断,第二天才发现。
另外注意:
- 运行用户需有
SELECT权限,对所有要导出的表、序列、类型都得能读;pg_dump -s还需要USAGEon schema - 如果库启用了 RLS(行级安全),且当前用户无权访问某些行,
pg_dump -a会漏数据,需确认是否加--enable-row-security - 不要在备份过程中执行
TRUNCATE或大事务UPDATE,否则可能触发长时间锁等待
真正影响大型库导出成败的,往往不是参数组合,而是对锁等待、权限边界和目录结构完整性的预判 —— 这些细节不检查,再快的并发也救不回一次中断的备份。











