PostgreSQL 备份与恢复 #
备份概述 #
备份是数据安全的重要保障,PostgreSQL 提供多种备份方式。
text
┌─────────────────────────────────────────────────────────────┐
│ 备份类型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 逻辑备份 │
│ ├── pg_dump - 单数据库备份 │
│ ├── pg_dumpall - 所有数据库备份 │
│ ├── 可跨版本恢复 │
│ └── 适合小型数据库 │
│ │
│ 物理备份 │
│ ├── pg_basebackup - 基础备份 │
│ ├── 文件系统级别备份 │
│ ├── 恢复速度快 │
│ └── 适合大型数据库 │
│ │
│ 时间点恢复(PITR) │
│ ├── 结合基础备份和 WAL 日志 │
│ ├── 可以恢复到任意时间点 │
│ └── 适合关键业务系统 │
│ │
└─────────────────────────────────────────────────────────────┘
pg_dump 逻辑备份 #
基本用法 #
bash
# 备份单个数据库
pg_dump -U postgres -d mydb > mydb_backup.sql
# 备份到压缩文件
pg_dump -U postgres -d mydb | gzip > mydb_backup.sql.gz
# 备份为自定义格式(推荐)
pg_dump -U postgres -d mydb -F c -f mydb_backup.dump
# 备份为目录格式
pg_dump -U postgres -d mydb -F d -f /backup/mydb/
# 备份为 tar 格式
pg_dump -U postgres -d mydb -F t -f mydb_backup.tar
常用选项 #
bash
# 只备份表结构
pg_dump -U postgres -d mydb --schema-only > schema.sql
# 只备份数据
pg_dump -U postgres -d mydb --data-only > data.sql
# 备份特定表
pg_dump -U postgres -d mydb -t employees > employees.sql
# 备份特定模式
pg_dump -U postgres -d mydb -n sales > sales_schema.sql
# 排除特定表
pg_dump -U postgres -d mydb -T audit_logs > mydb_backup.sql
# 包含创建数据库语句
pg_dump -U postgres -d mydb -C > mydb_backup.sql
# 压缩级别(0-9)
pg_dump -U postgres -d mydb -F c -Z 6 -f mydb_backup.dump
# 并行备份(目录格式)
pg_dump -U postgres -d mydb -F d -j 4 -f /backup/mydb/
# 完整选项示例
pg_dump -U postgres \
-h localhost \
-p 5432 \
-d mydb \
-F c \
-Z 6 \
-v \
-f mydb_backup.dump
格式对比 #
text
┌─────────────┬─────────────────────────────────────────────────┐
│ 格式 │ 说明 │
├─────────────┼─────────────────────────────────────────────────┤
│ -F p (plain)│ 纯 SQL 文本,可直接执行 │
│ -F c (custom)│ 自定义格式,支持并行恢复,可选择恢复对象 │
│ -F d (directory)│ 目录格式,支持并行备份和恢复 │
│ -F t (tar) │ tar 归档格式,不支持并行 │
└─────────────┴─────────────────────────────────────────────────┘
pg_dumpall 全库备份 #
bash
# 备份所有数据库
pg_dumpall -U postgres > all_databases.sql
# 只备份角色和表空间定义
pg_dumpall -U postgres --globals-only > globals.sql
# 只备份角色
pg_dumpall -U postgres --roles-only > roles.sql
# 只备份表空间
pg_dumpall -U postgres --tablespaces-only > tablespaces.sql
# 备份所有(包含数据)
pg_dumpall -U postgres -f all_backup.sql
pg_restore 恢复 #
基本用法 #
bash
# 从自定义格式恢复
pg_restore -U postgres -d mydb mydb_backup.dump
# 从目录格式恢复
pg_restore -U postgres -d mydb /backup/mydb/
# 从 tar 格式恢复
pg_restore -U postgres -d mydb mydb_backup.tar
# 创建数据库后恢复
pg_restore -U postgres -C -d postgres mydb_backup.dump
常用选项 #
bash
# 只恢复表结构
pg_restore -U postgres -d mydb --schema-only mydb_backup.dump
# 只恢复数据
pg_restore -U postgres -d mydb --data-only mydb_backup.dump
# 恢复特定表
pg_restore -U postgres -d mydb -t employees mydb_backup.dump
# 恢复特定模式
pg_restore -U postgres -d mydb -n sales mydb_backup.dump
# 并行恢复
pg_restore -U postgres -d mydb -j 4 mydb_backup.dump
# 清理后恢复(先删除再创建)
pg_restore -U postgres -d mydb --clean mydb_backup.dump
# 如果存在则跳过
pg_restore -U postgres -d mydb --if-exists mydb_backup.dump
# 禁用触发器
pg_restore -U postgres -d mydb --disable-triggers mydb_backup.dump
# 详细输出
pg_restore -U postgres -d mydb -v mydb_backup.dump
# 列出备份内容
pg_restore -l mydb_backup.dump
# 使用列表文件选择性恢复
pg_restore -U postgres -d mydb -L restore.list mydb_backup.dump
SQL 文本恢复 #
bash
# 从 SQL 文本恢复
psql -U postgres -d mydb < mydb_backup.sql
# 从压缩文件恢复
gunzip -c mydb_backup.sql.gz | psql -U postgres -d mydb
# 恢复全局对象
psql -U postgres -f globals.sql
pg_basebackup 物理备份 #
基本用法 #
bash
# 基础备份
pg_basebackup -U postgres -D /backup/base
# 压缩备份
pg_basebackup -U postgres -D /backup/base -z
# 指定压缩格式
pg_basebackup -U postgres -D /backup/base --format=tar --gzip
# 包含 WAL 文件
pg_basebackup -U postgres -D /backup/base --xlog-method=stream
# 检查点模式
pg_basebackup -U postgres -D /backup/base --checkpoint=fast
# 完整选项示例
pg_basebackup -U postgres \
-h localhost \
-p 5432 \
-D /backup/base \
--format=tar \
--gzip \
--xlog-method=stream \
--checkpoint=fast \
--progress \
--verbose
备份选项说明 #
text
┌─────────────────────┬─────────────────────────────────────────┐
│ 选项 │ 说明 │
├─────────────────────┼─────────────────────────────────────────┤
│ -D, --pgdata │ 备份目录 │
│ -F, --format │ 输出格式:plain, tar │
│ -z, --gzip │ 启用 gzip 压缩 │
│ -Z, --compress │ 压缩级别(0-9) │
│ -X, --xlog-method │ WAL 方法:none, fetch, stream │
│ -c, --checkpoint │ 检查点:fast, spread │
│ -P, --progress │ 显示进度 │
│ -v, --verbose │ 详细输出 │
│ -R, --write-recovery-conf │ 创建 standby.signal 和配置 │
└─────────────────────┴─────────────────────────────────────────┘
PITR 时间点恢复 #
配置 WAL 归档 #
ini
# postgresql.conf
wal_level = replica
archive_mode = on
archive_command = 'cp %p /archive/%f'
# 或使用更可靠的归档命令
archive_command = 'rsync -a %p backup_server:/archive/%f'
执行基础备份 #
bash
# 创建基础备份
pg_basebackup -U postgres -D /backup/base_$(date +%Y%m%d) --xlog-method=stream
恢复到指定时间点 #
bash
# 1. 停止 PostgreSQL 服务
pg_ctl stop
# 2. 备份当前数据目录
mv /var/lib/postgresql/16/main /var/lib/postgresql/16/main.old
# 3. 恢复基础备份
tar -xf /backup/base_20260329.tar -C /var/lib/postgresql/16/main
# 4. 创建恢复配置
cat > /var/lib/postgresql/16/main/postgresql.auto.conf << EOF
restore_command = 'cp /archive/%f %p'
recovery_target_time = '2026-03-29 14:30:00'
recovery_target_action = 'promote'
EOF
# 5. 创建恢复信号文件
touch /var/lib/postgresql/16/main/recovery.signal
# 6. 启动 PostgreSQL
pg_ctl start
恢复目标选项 #
ini
# 恢复到指定时间
recovery_target_time = '2026-03-29 14:30:00'
# 恢复到指定事务 ID
recovery_target_xid = '12345'
# 恢复到指定 WAL 位置
recovery_target_lsn = '0/5000000'
# 恢复到指定恢复点
recovery_target_name = 'before_upgrade'
# 恢复到最早一致点
recovery_target = 'immediate'
# 恢复后操作
recovery_target_action = 'promote' # 提升为主库
recovery_target_action = 'pause' # 暂停
recovery_target_action = 'shutdown' # 关闭
创建恢复点 #
sql
-- 创建命名恢复点
SELECT pg_create_restore_point('before_critical_operation');
-- 切换 WAL 文件
SELECT pg_switch_wal();
备份策略 #
备份策略设计 #
text
┌─────────────────────────────────────────────────────────────┐
│ 备份策略示例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 小型数据库(< 100GB) │
│ ├── 每日全量备份(pg_dump) │
│ ├── 保留 7 天 │
│ └── 异地存储 │
│ │
│ 中型数据库(100GB - 1TB) │
│ ├── 每周全量备份(pg_basebackup) │
│ ├── 每日增量备份 │
│ ├── WAL 归档 │
│ └── PITR 支持 │
│ │
│ 大型数据库(> 1TB) │
│ ├── 基础备份 + WAL 归档 │
│ ├── 流复制热备 │
│ ├── 定期测试恢复 │
│ └── 自动化监控 │
│ │
└─────────────────────────────────────────────────────────────┘
自动化备份脚本 #
bash
#!/bin/bash
# backup.sh
# 配置
DB_NAME="mydb"
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
pg_dump -U postgres -d $DB_NAME -F c -f "$BACKUP_DIR/${DB_NAME}_${DATE}.dump"
# 检查备份是否成功
if [ $? -eq 0 ]; then
echo "Backup completed: ${DB_NAME}_${DATE}.dump"
# 删除旧备份
find $BACKUP_DIR -name "${DB_NAME}_*.dump" -mtime +$RETENTION_DAYS -delete
# 发送通知
echo "Backup successful" | mail -s "PostgreSQL Backup" admin@example.com
else
echo "Backup failed!"
exit 1
fi
定时任务 #
bash
# crontab -e
# 每天凌晨 2 点执行备份
0 2 * * * /scripts/backup.sh >> /var/log/backup.log 2>&1
# 每周日凌晨 3 点执行全库备份
0 3 * * 0 /scripts/full_backup.sh >> /var/log/backup.log 2>&1
验证备份 #
测试恢复 #
bash
# 创建测试数据库
createdb -U postgres test_restore
# 恢复到测试数据库
pg_restore -U postgres -d test_restore mydb_backup.dump
# 验证数据
psql -U postgres -d test_restore -c "SELECT COUNT(*) FROM employees;"
# 清理测试数据库
dropdb -U postgres test_restore
检查备份完整性 #
bash
# 检查备份文件
pg_verifybackup /backup/base_20260329
# 列出备份内容
pg_restore -l mydb_backup.dump
# 检查 SQL 备份语法
head -100 mydb_backup.sql
学习路径 #
text
运维阶段
├── 用户权限管理
├── 备份与恢复(本文)
└── 性能优化
下一步 #
掌握了备份与恢复后,接下来学习 性能优化,了解如何优化数据库性能!
最后更新:2026-03-29