PostgreSQL 数据库备份与恢复:pg_dump 系列工具全解析
前言
在PostgreSQL数据库的日常运维中,数据备份与恢复是保障数据安全性的核心操作。PostgreSQL 原生提供了pg_dump系列工具实现数据库的SQL转储式备份,其核心思想是生成包含SQL命令的转储文件,通过执行该文件即可重建与备份时刻状态一致的数据库。
相较于文件级备份、连续归档等方式,pg_dump具备跨版本兼容、跨架构迁移、非阻塞备份(大部分场景)、细粒度恢复等显著优势,是PostgreSQL运维中最常用的备份工具。本文将全面解析pg_dump、pg_dumpall、pg_restore的使用方法,涵盖基础备份恢复、集群级备份、大型数据库专属解决方案等核心内容,为实际运维提供可落地的操作指南。
1 pg_dump 核心原理与基础用法
1.1 核心原理
pg_dump是PostgreSQL的客户端应用工具,其核心作用是扫描目标数据库并生成包含建库、建表、插入数据等SQL命令的转储文件(支持文本/自定义/目录等格式)。该工具会在备份开始时创建数据库的一致性快照,备份过程中数据库的更新操作不会被写入转储文件,保证了备份的内部一致性。
同时,pg_dump工作时不会阻塞数据库的常规读写操作(仅会阻塞需要排他锁的操作,如ALTER TABLE),适合在生产环境的业务低峰期执行。
1.2 基础命令
pg_dump的最基础用法为将数据库转储为文本格式的SQL文件,结果默认输出到标准输出,通过重定向符>写入指定文件:
# 基础格式:pg_dump 数据库名 > 转储文件路径
pg_dump mydb > /backup/mydb_dump.sql
1.3 连接参数配置
pg_dump作为PostgreSQL客户端,需通过参数指定目标数据库服务器的连接信息,核心参数如下(若使用默认值可省略):
| 参数 | 作用 | 默认值 |
|---|---|---|
-h host | 指定数据库服务器的主机名/IP | 本地主机(或PGHOST环境变量) |
-p port | 指定数据库服务器的端口号 | 5432(或PGPORT环境变量) |
-U username | 指定连接数据库的用户名 | 当前操作系统用户名(或PGUSER环境变量) |
示例:从远端服务器备份数据库,指定用户名和端口:
pg_dump -h 192.168.1.100 -p 5433 -U postgres mydb > /backup/mydb_remote_dump.sql
1.4 权限要求
pg_dump无特殊执行权限,仅需对目标备份对象拥有读权限:
- 备份整个数据库时,通常需要以数据库超级用户(如postgres)执行;
- 若仅备份数据库的部分对象,使用
-n 模式名(指定schema)或-t 表名(指定单表)选项,仅需拥有对应对象的读权限即可。
示例:仅备份public模式下的user表:
pg_dump -t public.user mydb > /backup/mydb_user_dump.sql
1.5 核心优势
相较于PostgreSQL其他备份方法,pg_dump的核心优势体现在:
- 跨版本兼容:转储文件可轻松载入更高版本的PostgreSQL,而文件级备份、连续归档强绑定服务器版本;
- 跨架构迁移:是唯一支持不同硬件架构迁移的方法(如32位服务器→64位服务器);
- 灵活的输出格式:支持文本、自定义、目录等格式,适配不同的备份/恢复需求;
- 非阻塞备份:不影响数据库常规业务操作,适合生产环境;
- 细粒度控制:可指定备份单个表、schema,恢复时也可选择性恢复对象。
2 从转储文件恢复数据库
根据pg_dump生成的转储文件格式不同,恢复方式分为**文本格式(psql执行)和非文本格式(pg_restore执行)**两种,恢复前需做好前置准备工作。
2.1 恢复前置条件
- 需手动创建目标数据库,且必须从
template0模板创建。template0是PostgreSQL内置的纯净模板数据库,集群初始化时自动生成,包含数据库运行必需的系统对象,且不允许用户添加自定义内容,能始终保持初始纯净状态。与之相对的template1可被用户修改(如添加扩展、公共表结构),新建数据库默认以template1为模板。恢复时选用template0,可避免template1中的自定义内容污染恢复结果,确保数据库结构、权限与原始备份完全一致,无额外冗余对象,创建命令如下: - 转储文件中对象的拥有者、权限被授予的用户必须已存在于目标服务器,否则无法恢复原有的所属关系和权限。
2.2 文本格式转储恢复(psql)
pg_dump基础命令生成的文本格式转储文件是标准的SQL脚本,需通过psql工具执行恢复,通用命令格式:
# -X:忽略psql的配置文件,使用默认设置执行
psql -X 目标数据库名 < 转储文件路径
示例:恢复mydb_dump.sql到新建的mydb_restore数据库:
# 1. 新建数据库
createdb -T template0 mydb_restore
# 2. 执行恢复
psql -X mydb_restore < /backup/mydb_dump.sql
2.2.1 增强恢复的容错性/原子性
默认情况下,psql执行脚本时遇到SQL错误会继续执行,可能导致部分恢复,可通过以下两种方式优化:
-
遇错即停:设置
ON_ERROR_STOP变量,错误时以退出状态3终止,快速发现问题:-
psql -X --set ON_ERROR_STOP=on mydb_restore < /backup/mydb_dump.sql
-
-
单事务恢复:通过
-1/--single-transaction将整个恢复过程作为单个事务执行,实现要么完全恢复,要么完全回滚,避免部分恢复的脏数据:-
psql -X -1 mydb_restore < /backup/mydb_dump.sql -
【注意】单事务恢复的弊端是:若恢复过程持续数小时,一个微小错误会导致整个过程回滚,需根据业务场景选择。
-
2.3 非文本格式转储恢复(pg_restore)
当pg_dump使用**自定义格式(-Fc)或目录格式(-Fd)**生成转储文件时,文件并非标准SQL脚本,无法通过psql执行,必须使用pg_restore工具恢复,基础命令:
# -d:指定目标数据库(需提前创建)
pg_restore -d 目标数据库名 转储文件路径
2.4 跨服务器直接迁移(管道方式)
pg_dump和psql支持读写管道,可跳过本地转储文件,直接将一个服务器的数据库转储并恢复到另一个服务器,适合数据库的跨机迁移,命令格式:
pg_dump -h 源服务器IP 源数据库名 | psql -X -h 目标服务器IP 目标数据库名
示例:将192.168.1.100的mydb迁移到192.168.1.200的mydb(目标库需提前创建):
createdb -T template0 -h 192.168.1.200 -U postgres mydb
pg_dump -h 192.168.1.100 -U postgres mydb | psql -X -h 192.168.1.200 -U postgres mydb
2.5 恢复后优化
恢复完成后,建议在目标数据库上执行ANALYZE命令,更新数据库的统计信息,让PostgreSQL查询优化器生成更高效的执行计划:
# 分析单个数据库
psql -U postgres -d mydb_restore -c "ANALYZE;"
# 分析整个集群的所有数据库
analyzedb -U postgres
3 pg_dumpall 集群级全量备份
pg_dump仅能备份单个数据库,且不会导出集群级全局数据(如角色、表空间、权限等,这些属于整个PostgreSQL集群,而非单个数据库)。PostgreSQL提供pg_dumpall工具实现整个数据库集群的全量备份,涵盖集群中所有数据库及全局数据。
3.1 核心作用
- 备份PostgreSQL集群中的所有数据库,每个数据库自身保持一致性;
- 导出集群级全局数据:角色(用户/组)、表空间定义、集群级权限等;
- 生成的转储文件为文本格式,可直接通过psql恢复。
【注意】pg_dumpall仅保证单个数据库的快照一致性,不同数据库的快照不同步,若需跨数据库的一致性备份,需结合事务或停写操作。
3.2 基础用法
3.2.1 集群全量备份
# 基础格式:pg_dumpall > 转储文件路径
pg_dumpall -U postgres > /backup/pg_cluster_dump.sql
3.2.2 集群全量恢复
恢复时需使用超级用户执行(因需重建角色、表空间等全局数据),指定postgres数据库作为恢复起点(空集群恢复的默认选择):
# -f:指定要执行的SQL脚本文件
psql -X -U postgres -f /backup/pg_cluster_dump.sql postgres
3.3 单独备份集群级全局数据
若仅需备份角色、表空间等全局数据,而非整个集群的数据库,可使用--globals-only选项,这是配合pg_dump单库备份实现集群完整备份的必要步骤:
# 仅备份集群全局数据(角色、表空间)
pg_dumpall -U postgres --globals-only > /backup/pg_cluster_globals.sql
4 大型数据库的备份与恢复解决方案
针对大尺寸数据库,直接使用pg_dump基础命令可能遇到文件系统最大文件限制、备份速度慢、恢复效率低等问题,可通过压缩、文件分割、自定义格式、并行备份等方式解决,可单独使用或组合使用。
4.1 压缩转储(适配普通大数据库)
利用Unix压缩工具(如gzip)对pg_dump的输出进行实时压缩,大幅减小转储文件体积,适合磁盘空间有限的场景。
4.1.1 压缩备份
# pg_dump输出通过管道实时gzip压缩
pg_dump mydb | gzip > /backup/mydb_dump.sql.gz
4.1.2 解压恢复
# 方式1:gunzip解压后通过管道恢复
gunzip -c /backup/mydb_dump.sql.gz | psql mydb_restore
# 方式2:cat结合gunzip恢复(效果一致)
cat /backup/mydb_dump.sql.gz | gunzip | psql mydb_restore
4.2 分割大转储文件(适配超大型文件)
若操作系统对文件大小有严格限制(如单文件最大2G),使用split命令将pg_dump的输出分割为指定大小的小文件,解决大文件存储问题。
4.2.1 分割备份(按2G分割)
# -b 2G:指定每个分割文件的大小为2G;-:表示从标准输入读取;filename:分割文件前缀
pg_dump mydb | split -b 2G - /backup/mydb_dump_
执行后会生成mydb_dump_aa、mydb_dump_ab、mydb_dump_ac等分割文件。
4.2.2 合并恢复
# 通过cat合并所有分割文件,再通过管道恢复
cat /backup/mydb_dump_* | psql mydb_restore
4.2.3 压缩+分割(GNU split专属)
若使用GNU版本的split,可结合gzip实现实时压缩+分割,进一步节省磁盘空间:
# --filter:指定对每个分割文件执行gzip压缩
pg_dump mydb | split -b 2G --filter='gzip > $FILE.gz' - /backup/mydb_dump_
恢复时使用zcat直接解压并合并:
zcat /backup/mydb_dump_*.gz | psql mydb_restore
4.3 自定义转储格式(-Fc,推荐中型数据库使用)
若服务器安装了zlib压缩库,pg_dump的自定义格式(-Fc)会在备份时实时压缩数据,生成的文件体积与gzip压缩相当,且支持细粒度恢复(可选择性恢复单个表/schame),是平衡压缩比和灵活性的优选方案。
4.3.1 自定义格式备份
# -Fc:指定自定义转储格式
pg_dump -Fc mydb > /backup/mydb_dump_custom
4.3.2 自定义格式恢复
自定义格式文件需通过pg_restore恢复,支持指定恢复单个对象,核心参数-d指定目标数据库:
# 完整恢复
pg_restore -d mydb_restore /backup/mydb_dump_custom
# 仅恢复public模式下的user表
pg_restore -d mydb_restore -t public.user /backup/mydb_dump_custom
4.4 并行备份与恢复(适配超大型数据库,推荐生产使用)
pg_dump支持并行转储特性,通过-j参数指定并行度,同时备份多个表,大幅提升超大型数据库的备份速度;配合pg_restore的并行恢复,可进一步缩短恢复时间。
4.4.1 并行备份
并行转储仅支持目录格式(-Fd) ,需通过-f指定输出目录(目录会自动创建,且不能为空):
# -j 4:指定4个并行进程;-Fd:目录格式;-f:输出目录
pg_dump -j 4 -Fd -f /backup/mydb_dump_dir mydb
执行后会在mydb_dump_dir中生成多个备份文件,每个文件对应部分表的数据/结构。
4.4.2 并行恢复
pg_restore的并行恢复支持自定义格式(-Fc)和目录格式(-Fd) ,无需依赖并行备份的源文件,通过-j指定并行度即可:
# -j 4:4个并行进程;-d:目标数据库;目录格式备份的恢复
pg_restore -j 4 -d mydb_restore /backup/mydb_dump_dir
# 自定义格式备份的并行恢复
pg_restore -j 4 -d mydb_restore /backup/mydb_dump_custom
4.5 超大型数据库的组合方案
对于TB级别的超大型数据库,可将并行备份与压缩/分割结合使用,例如:先通过并行备份生成目录格式文件,再对目录进行压缩打包,或对并行输出进行分割,兼顾备份速度、文件体积和存储限制。
5 总结与最佳实践
5.1 核心知识点总结
pg_dump是单库备份工具,生成一致性快照,非阻塞常规业务,跨版本/跨架构兼容;- 文本格式备份用
psql恢复,非文本格式(自定义/目录)用pg_restore恢复,恢复前需从template0创建目标库; pg_dumpall实现集群级全量备份,包含所有数据库和全局数据(角色、表空间),恢复需超级用户;- 大型数据库可通过压缩、分割、自定义格式、并行备份解决存储和速度问题,其中并行备份是超大型库的优选。
5.2 不同场景最佳实践
| 数据库规模 | 业务场景 | 推荐备份方式 | 推荐恢复方式 |
|---|---|---|---|
| 小型库(<10G) | 开发/测试环境、低重要性业务 | pg_dump基础文本格式 | psql基础恢复(可加-1保证原子性) |
| 中型库(10G-100G) | 生产环境普通业务,需细粒度恢复 | pg_dump -Fc自定义格式 | pg_restore按需恢复单个对象 |
| 大型库(100G-1T) | 生产环境核心业务,磁盘空间有限 | pg_dump -Fc+gzip压缩 | pg_restore并行恢复(-j 2-4) |
| 超大型库(>1T) | 生产环境核心大库,要求备份速度 | pg_dump -j N -Fd并行备份 | pg_restore -j N并行恢复 |
| 集群级备份 | 整库迁移、集群灾备 | pg_dumpall全量备份 + pg_dump单库增量 | psql恢复全局数据后,再恢复单库 |
5.3 生产环境注意事项
- 备份操作建议在业务低峰期执行,避免与高并发业务竞争资源;
- 定期验证备份文件的有效性,通过恢复测试确保可正常恢复;
- 备份文件需异地存储,避免本地磁盘故障导致备份丢失;
- 恢复时根据业务需求选择单事务恢复(追求原子性)或遇错即停(追求问题排查效率);
- 并行备份的并行度(-j)建议不超过数据库服务器的CPU核心数,避免服务器负载过高。