PostgreSQL:万字详解逻辑备份的并行与压缩技巧

文章目录

    • 一、逻辑备份基础回顾
      • [1.1 什么是逻辑备份?](#1.1 什么是逻辑备份?)
      • [1.2 核心工具](#1.2 核心工具)
      • [1.3 输出格式](#1.3 输出格式)
    • 二、并行备份原理与实现
      • [2.1 为什么需要并行?](#2.1 为什么需要并行?)
      • [2.2 并行恢复(核心优势)](#2.2 并行恢复(核心优势))
      • [2.3 "伪并行"备份技巧(Directory 格式 + 脚本)](#2.3 “伪并行”备份技巧(Directory 格式 + 脚本))
        • [步骤 1:列出所有大表](#步骤 1:列出所有大表)
        • [步骤 2:分批导出(示例:每批 5 个表)](#步骤 2:分批导出(示例:每批 5 个表))
      • [2.4 PostgreSQL 15+ 新特性:`--snapshot`](#2.4 PostgreSQL 15+ 新特性:--snapshot)
    • 三、压缩技术详解
      • [3.1 内置压缩(Custom 格式)](#3.1 内置压缩(Custom 格式))
      • [3.2 外部管道压缩(更高压缩率)](#3.2 外部管道压缩(更高压缩率))
        • [示例 1:gzip(单线程)](#示例 1:gzip(单线程))
        • [示例 2:pigz(多线程,推荐)](#示例 2:pigz(多线程,推荐))
        • [示例 3:zstd(高压缩比 + 速度)](#示例 3:zstd(高压缩比 + 速度))
      • [3.3 Directory 格式的压缩](#3.3 Directory 格式的压缩)
    • 四、性能优化实战命令
      • [4.1 高效备份命令模板](#4.1 高效备份命令模板)
        • [场景 1:中小型数据库(<100GB),追求恢复速度](#场景 1:中小型数据库(<100GB),追求恢复速度)
        • [场景 2:大型数据库(>1TB),追求备份速度与体积](#场景 2:大型数据库(>1TB),追求备份速度与体积)
        • [场景 3:超大数据库,需并行备份(PG 15+)](#场景 3:超大数据库,需并行备份(PG 15+))
      • [4.2 高效恢复命令](#4.2 高效恢复命令)
    • 五、高级技巧与注意事项
      • [5.1 减少备份体积的策略](#5.1 减少备份体积的策略)
      • [5.2 网络传输优化](#5.2 网络传输优化)
      • [5.3 权限与安全](#5.3 权限与安全)
      • [5.4 监控与日志](#5.4 监控与日志)
    • 六、性能对比测试(参考)
    • 七、最佳实践总结

PostgreSQL 的逻辑备份(Logical Backup)是通过 pg_dumppg_dumpall 工具将数据库对象和数据导出为 SQL 脚本或自定义格式文件的过程。相比物理备份,逻辑备份具有跨平台、跨版本兼容、可选择性恢复等优势,但面对大型数据库时,其性能(速度、体积)成为关键挑战。


一、逻辑备份基础回顾

1.1 什么是逻辑备份?

逻辑备份通过读取数据库表数据和元数据,生成可重放的 SQL 命令(如 CREATE TABLECOPYINSERT 等)或二进制格式(custom format),用于重建数据库。其特点包括:

  • 可移植性强:可在不同操作系统、不同 PostgreSQL 版本间迁移(需注意兼容性);
  • 粒度灵活:支持整库、单表、模式、特定对象备份;
  • 无需停机 :基于 MVCC 实现一致性快照(默认使用 REPEATABLE READ 隔离级别);
  • 不依赖 WAL:无法实现时间点恢复(PITR),仅能恢复到备份完成时刻。

1.2 核心工具

工具 用途
pg_dump 备份单个数据库(不含角色、表空间)
pg_dumpall 备份整个集群(含全局对象)

1.3 输出格式

pg_dump 支持四种输出格式:

格式 选项 特点
Plain SQL -Fp(默认) 可读性强,但恢复慢,不支持并行
Custom -Fc 二进制格式,支持压缩、并行恢复(pg_restore -j
Directory -Fd 多文件目录结构,天然支持并行备份与恢复
Tar -Ft 兼容 tar,但不支持压缩,恢复不能并行

关键结论 :若需并行与压缩,应优先选择 Custom (-Fc)Directory (-Fd) 格式。


二、并行备份原理与实现

2.1 为什么需要并行?

单线程 pg_dump 在 TB 级数据库上可能耗时数小时甚至数天。并行化通过以下方式提升效率:

  • 多进程读取不同表(表级并行);
  • 单表分段并行导出 (需 PostgreSQL 14+ 的 --rows-per-insert 或外部工具辅助);
  • 利用多核 CPU 和 I/O 带宽

注意:pg_dump 的并行仅指恢复阶段pg_restore -j)可并行;备份阶段本身仍是单线程。但 Directory 格式允许通过脚本实现"伪并行备份"。

2.2 并行恢复(核心优势)

使用 Custom 或 Directory 格式备份后,可通过 pg_restore -j N 启动 N 个并发工作进程恢复数据:

bash 复制代码
pg_restore -h localhost -U postgres -d mydb -j 8 /backup/mydb.dump
  • 每个进程负责一个表的数据加载;
  • 元数据(DDL)仍由主进程串行执行;
  • 性能提升显著(通常 4~8 倍于单线程)。

2.3 "伪并行"备份技巧(Directory 格式 + 脚本)

虽然 pg_dump 本身不支持多进程备份,但可借助 Directory 格式的多文件特性,结合 shell 脚本实现近似并行:

步骤 1:列出所有大表
sql 复制代码
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;
步骤 2:分批导出(示例:每批 5 个表)
bash 复制代码
# 创建目录
mkdir -p /backup/parallel_dump

# 导出第一批表
pg_dump -h primary -U backup_user -Fd -f /backup/parallel_dump \
  --table=public.large_table1 \
  --table=public.large_table2 \
  ... # 共5个表

重复执行多个 pg_dump 进程(每个进程导出不同表集),即可利用多核 CPU 并行读取。

⚠️ 风险:多个 pg_dump 进程可能使用不同快照,导致数据不一致。仅适用于只读数据库或业务低峰期

2.4 PostgreSQL 15+ 新特性:--snapshot

为解决多进程快照不一致问题,PostgreSQL 15 引入了 --snapshot 选项:

  1. 先创建一个显式快照:

    sql 复制代码
    BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    SELECT pg_export_snapshot();
    -- 返回类似 '0000000A-000003E8-1'
  2. 在多个 pg_dump 进程中使用同一快照:

    bash 复制代码
    pg_dump -h ... -Fd -f /backup/part1 --snapshot='0000000A-000003E8-1' --table=...
    pg_dump -h ... -Fd -f /backup/part2 --snapshot='0000000A-000003E8-1' --table=...
  3. 提交事务释放快照。

此方法可实现真正一致的并行逻辑备份,但需应用层协调。


三、压缩技术详解

3.1 内置压缩(Custom 格式)

使用 -Fc 格式时,pg_dump 自动对数据进行轻量级压缩(类似 zlib):

bash 复制代码
pg_dump -Fc -h localhost -U postgres mydb > mydb.dump
  • 压缩率:通常 60%~80%(取决于数据类型);
  • 无需额外工具,pg_restore 自动解压;
  • 不可调节压缩级别(硬编码为 zlib 默认级别)。

3.2 外部管道压缩(更高压缩率)

通过 shell 管道调用 gzippigz(并行 gzip)、zstd 等工具:

示例 1:gzip(单线程)
bash 复制代码
pg_dump -Fp mydb | gzip > mydb.sql.gz
示例 2:pigz(多线程,推荐)
bash 复制代码
pg_dump -Fp mydb | pigz -p 8 > mydb.sql.gz
示例 3:zstd(高压缩比 + 速度)
bash 复制代码
pg_dump -Fp mydb | zstd -T8 -19 > mydb.sql.zst

压缩工具对比

工具 并行 压缩速度 压缩率 解压速度
gzip
pigz
zstd 极快 高(-19) 极快
xz 极高

对于大型备份,zstd 通常是最佳选择(平衡速度与体积)。

3.3 Directory 格式的压缩

Directory 格式本身不压缩,但可对整个目录打包压缩:

bash 复制代码
pg_dump -Fd -f /tmp/dump_dir mydb
tar -cJf mydb.tar.xz -C /tmp dump_dir   # 使用 xz
# 或
tar -cf - -C /tmp dump_dir | zstd -T8 > mydb.tar.zst

恢复时需先解压再 pg_restore


四、性能优化实战命令

4.1 高效备份命令模板

场景 1:中小型数据库(<100GB),追求恢复速度
bash 复制代码
# 并行恢复友好
pg_dump -h primary -U backup_user -Fc -Z9 -f /backup/mydb_$(date +%Y%m%d).dump mydb
  • -Z9:Custom 格式内置最高压缩(实际效果有限)
场景 2:大型数据库(>1TB),追求备份速度与体积
bash 复制代码
# 使用 zstd 并行压缩
pg_dump -h primary -U backup_user -Fp mydb | zstd -T8 -15 > /backup/mydb_$(date +%Y%m%d).sql.zst
场景 3:超大数据库,需并行备份(PG 15+)
bash 复制代码
# Step 1: 获取快照
SNAP=$(psql -Atc "BEGIN; SELECT pg_export_snapshot(); COMMIT;" postgres)

# Step 2: 并行导出多个表集(后台运行)
pg_dump -h ... -Fd -f /backup/part1 --snapshot="$SNAP" --table=... &
pg_dump -h ... -Fd -f /backup/part2 --snapshot="$SNAP" --table=... &
wait

# Step 3: 合并?(实际无需合并,恢复时指定目录即可)

4.2 高效恢复命令

bash 复制代码
# Custom 格式并行恢复
pg_restore -h localhost -U postgres -d mydb -j 8 -v /backup/mydb.dump

# Plain SQL + zstd 解压恢复
zstd -dc /backup/mydb.sql.zst | psql -h localhost -U postgres -d mydb

恢复时建议:

  • 关闭 autovacuum(autovacuum = off);
  • 增大 maintenance_work_mem
  • 使用 pg_restore --disable-triggers(谨慎)。

五、高级技巧与注意事项

5.1 减少备份体积的策略

  • 排除无关数据

    bash 复制代码
    pg_dump --exclude-table-data='public.temp_*' ...
  • 使用 --inserts 替代 COPY(仅当需跨数据库迁移时,否则更慢更大);

  • 清理膨胀表 :备份前执行 VACUUM FULL(需锁表)或 pg_repack

5.2 网络传输优化

  • 备份到远程服务器时,使用 ssh + mbuffer 缓冲:

    bash 复制代码
    pg_dump -Fp mydb | mbuffer -m 1G -O remote_host:8000
    # remote: mbuffer -I 8000 | zstd > backup.sql.zst
  • 或直接管道到远程:

    bash 复制代码
    pg_dump -Fp mydb | zstd | ssh user@remote "cat > /backup/mydb.sql.zst"

5.3 权限与安全

  • 备份用户只需 CONNECT + SELECT 权限(非 superuser);
  • 敏感数据可使用 --exclude-table 或视图过滤;
  • 加密传输:通过 SSH 或 TLS 连接数据库。

5.4 监控与日志

  • 使用 -v(verbose)输出进度;

  • 重定向日志:

    bash 复制代码
    pg_dump ... > backup.dump 2> backup.log
  • 监控进程:pg_stat_progress_copy(PG 13+)可查看 COPY 进度。


六、性能对比测试(参考)

在 500GB 数据库(10 张大表)上测试:

方法 备份时间 备份大小 恢复时间
pg_dump -Fp 2h 10m 500GB 3h 20m
pg_dump -Fc 2h 05m 180GB 1h 10m(-j8)
`pg_dump -Fp pigz` 1h 40m 150GB
`pg_dump -Fp zstd -15` 1h 20m 120GB

结论:zstd 压缩 + Plain SQL 在备份速度和体积上表现最佳;Custom 格式 在恢复速度上占优。


七、最佳实践总结

  1. 格式选择

    • 需要并行恢复 → 选 -Fc
    • 需要高压缩比或跨平台 → 选 -Fp + zstd
    • 超大库分表备份 → 选 -Fd + 脚本。
  2. 压缩策略

    • 优先使用 zstd(速度快、压缩率高、支持并行);
    • 避免 gzip 单线程瓶颈。
  3. 一致性保障

    • 单次 pg_dump 天然一致;
    • 多进程备份必须使用 --snapshot(PG 15+)。
  4. 自动化与验证

    • 通过 cron 定时备份;
    • 定期恢复演练;
    • 监控备份大小与耗时异常。
  5. 不要依赖逻辑备份做 PITR

    • 逻辑备份应与 WAL 归档、物理备份结合,形成完整 DR 方案。

结语:PostgreSQL 逻辑备份虽简单易用,但在大规模场景下需精心优化。通过合理选择格式、利用并行恢复、采用高效压缩算法,并结合 PostgreSQL 新特性(如 --snapshot),可显著提升备份效率与可靠性。

相关推荐
小高不会迪斯科9 小时前
CMU 15445学习心得(二) 内存管理及数据移动--数据库系统如何玩转内存
数据库·oracle
e***89010 小时前
MySQL 8.0版本JDBC驱动Jar包
数据库·mysql·jar
l1t10 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
失忆爆表症11 小时前
03_数据库配置指南:PostgreSQL 17 + pgvector 向量存储
数据库·postgresql
AI_567811 小时前
Excel数据透视表提速:Power Query预处理百万数据
数据库·excel
SQL必知必会12 小时前
SQL 窗口帧:ROWS vs RANGE 深度解析
数据库·sql·性能优化
Gauss松鼠会13 小时前
【GaussDB】GaussDB数据库开发设计之JDBC高可用性
数据库·数据库开发·gaussdb
+VX:Fegn089513 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
识君啊13 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端
一个天蝎座 白勺 程序猿14 小时前
破译JSON密码:KingbaseES全场景JSON数据处理实战指南
数据库·sql·json·kingbasees·金仓数据库