PostgreSQL 数据库备份与恢复:pg_dump 详解

17 阅读13分钟

PostgreSQL 数据库备份与恢复:pg_dump 系列工具全解析

前言

在PostgreSQL数据库的日常运维中,数据备份与恢复是保障数据安全性的核心操作。PostgreSQL 原生提供了pg_dump系列工具实现数据库的SQL转储式备份,其核心思想是生成包含SQL命令的转储文件,通过执行该文件即可重建与备份时刻状态一致的数据库。

相较于文件级备份、连续归档等方式,pg_dump具备跨版本兼容、跨架构迁移、非阻塞备份(大部分场景)、细粒度恢复等显著优势,是PostgreSQL运维中最常用的备份工具。本文将全面解析pg_dumppg_dumpallpg_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无特殊执行权限,仅需对目标备份对象拥有读权限

  1. 备份整个数据库时,通常需要以数据库超级用户(如postgres)执行;
  2. 若仅备份数据库的部分对象,使用-n 模式名(指定schema)或-t 表名(指定单表)选项,仅需拥有对应对象的读权限即可。

示例:仅备份public模式下的user表:

pg_dump -t public.user mydb > /backup/mydb_user_dump.sql

1.5 核心优势

相较于PostgreSQL其他备份方法,pg_dump的核心优势体现在:

  1. 跨版本兼容:转储文件可轻松载入更高版本的PostgreSQL,而文件级备份、连续归档强绑定服务器版本;
  2. 跨架构迁移:是唯一支持不同硬件架构迁移的方法(如32位服务器→64位服务器);
  3. 灵活的输出格式:支持文本、自定义、目录等格式,适配不同的备份/恢复需求;
  4. 非阻塞备份:不影响数据库常规业务操作,适合生产环境;
  5. 细粒度控制:可指定备份单个表、schema,恢复时也可选择性恢复对象。

2 从转储文件恢复数据库

根据pg_dump生成的转储文件格式不同,恢复方式分为**文本格式(psql执行)非文本格式(pg_restore执行)**两种,恢复前需做好前置准备工作。

2.1 恢复前置条件

  1. 需手动创建目标数据库,且必须从template0模板创建。template0是PostgreSQL内置的纯净模板数据库,集群初始化时自动生成,包含数据库运行必需的系统对象,且不允许用户添加自定义内容,能始终保持初始纯净状态。与之相对的template1可被用户修改(如添加扩展、公共表结构),新建数据库默认以template1为模板。恢复时选用template0,可避免template1中的自定义内容污染恢复结果,确保数据库结构、权限与原始备份完全一致,无额外冗余对象,创建命令如下:
  2. 转储文件中对象的拥有者、权限被授予的用户必须已存在于目标服务器,否则无法恢复原有的所属关系和权限。

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错误会继续执行,可能导致部分恢复,可通过以下两种方式优化:

  1. 遇错即停:设置ON_ERROR_STOP变量,错误时以退出状态3终止,快速发现问题:

    1. psql -X --set ON_ERROR_STOP=on mydb_restore < /backup/mydb_dump.sql
      
  2. 单事务恢复:通过-1/--single-transaction将整个恢复过程作为单个事务执行,实现要么完全恢复,要么完全回滚,避免部分恢复的脏数据:

    1. psql -X -1 mydb_restore < /backup/mydb_dump.sql
      
    2.   【注意】单事务恢复的弊端是:若恢复过程持续数小时,一个微小错误会导致整个过程回滚,需根据业务场景选择。

2.3 非文本格式转储恢复(pg_restore)

pg_dump使用**自定义格式(-Fc)目录格式(-Fd)**生成转储文件时,文件并非标准SQL脚本,无法通过psql执行,必须使用pg_restore工具恢复,基础命令:

# -d:指定目标数据库(需提前创建)
pg_restore -d 目标数据库名 转储文件路径

2.4 跨服务器直接迁移(管道方式)

pg_dumppsql支持读写管道,可跳过本地转储文件,直接将一个服务器的数据库转储并恢复到另一个服务器,适合数据库的跨机迁移,命令格式:

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 核心作用

  1. 备份PostgreSQL集群中的所有数据库,每个数据库自身保持一致性;
  2. 导出集群级全局数据:角色(用户/组)、表空间定义、集群级权限等;
  3. 生成的转储文件为文本格式,可直接通过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_aamydb_dump_abmydb_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 核心知识点总结

  1. pg_dump是单库备份工具,生成一致性快照,非阻塞常规业务,跨版本/跨架构兼容;
  2. 文本格式备份用psql恢复,非文本格式(自定义/目录)用pg_restore恢复,恢复前需从template0创建目标库;
  3. pg_dumpall实现集群级全量备份,包含所有数据库和全局数据(角色、表空间),恢复需超级用户;
  4. 大型数据库可通过压缩、分割、自定义格式、并行备份解决存储和速度问题,其中并行备份是超大型库的优选。

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 生产环境注意事项

  1. 备份操作建议在业务低峰期执行,避免与高并发业务竞争资源;
  2. 定期验证备份文件的有效性,通过恢复测试确保可正常恢复;
  3. 备份文件需异地存储,避免本地磁盘故障导致备份丢失;
  4. 恢复时根据业务需求选择单事务恢复(追求原子性)或遇错即停(追求问题排查效率);
  5. 并行备份的并行度(-j)建议不超过数据库服务器的CPU核心数,避免服务器负载过高。