PostgreSQL 入门学习教程,从入门到精通,PostgreSQL 16 数据备份与还原详解 —语法、案例与实战(16)

PostgreSQL 16 数据备份与还原详解 ---语法、案例与实战


✅ 一、数据备份(Backup)

PostgreSQL 提供逻辑备份 (SQL/自定义格式)和物理备份 (文件系统级),本章聚焦逻辑备份工具:pg_dump, pg_dumpall, pgAdmin 4


1.1 使用 pgAdmin 4 备份数据库(图形化操作)

适用场景:开发、测试环境,不熟悉命令行的用户

📌 操作步骤:
  1. 打开 pgAdmin 4 → 连接服务器 → 展开数据库
  2. 右键目标数据库 → Backup...
  3. 设置参数:
    • Filename :备份文件路径(如 C:\backup\mydb_backup.sql
    • Format
      • Plain → SQL 脚本(可读,兼容性好)
      • Custom → 二进制格式(支持选择性还原,压缩率高)
      • Directory → 目录格式(大库推荐)
      • Tar → tar 归档格式
    • Encoding:UTF8(推荐)
    • Dump Options
      • Only data → 仅数据
      • Only schema → 仅结构
      • Only schema + data → 默认(全量)
  4. 点击 Backup → 等待完成

优点 :图形化、易用

缺点:不适合自动化、大库效率低


1.2 使用 pg_dump 工具备份数据库(命令行)

核心工具 :备份单个数据库

📌 基本语法:
bash 复制代码
pg_dump [选项] 数据库名 > 备份文件
📌 常用选项:
选项 说明
-h host 主机地址(默认 localhost)
-p port 端口(默认 5432)
-U user 用户名
-F format 格式:p(plain), c(custom), d(directory), t(tar)
-f file 输出文件(替代 > 重定向)
-v 详细模式
-j jobs 并行备份(仅 directory 格式)
--schema-only 仅备份结构
--data-only 仅备份数据
--table=table_name 备份指定表
--exclude-table=table_name 排除表

✅ 案例1:备份为 SQL 脚本(Plain 格式)
bash 复制代码
# 备份整个数据库为 SQL 文件(默认格式)
pg_dump -h localhost -p 5432 -U postgres mydb > mydb_full_backup.sql

# 仅备份结构(无数据)
pg_dump -U postgres --schema-only mydb > mydb_schema.sql

# 仅备份数据(无结构)
pg_dump -U postgres --data-only mydb > mydb_data.sql

# 备份指定表
pg_dump -U postgres -t employees -t departments mydb > mydb_selected_tables.sql

# 排除日志表
pg_dump -U postgres --exclude-table=logs mydb > mydb_no_logs.sql

适用场景

  • 小型数据库
  • 需要人工编辑备份文件
  • 跨版本迁移(SQL 格式兼容性最好)

✅ 案例2:备份为自定义格式(Custom Format - 推荐)
bash 复制代码
# 备份为自定义二进制格式(压缩、支持选择性恢复)
pg_dump -U postgres -F c -f mydb_backup.custom mydb

# 并行备份(PostgreSQL 9.3+,仅 directory 格式)
pg_dump -U postgres -F d -j 4 -f mydb_backup_dir mydb

# 带压缩的自定义格式(-Z 0~9,9为最高压缩)
pg_dump -U postgres -F c -Z 6 -f mydb_compressed.backup mydb

优势

  • 压缩率高(节省空间)
  • 支持 pg_restore 选择性还原
  • 支持并行备份/恢复(加速大库操作)

1.3 使用 pg_dumpall 备份整个服务器

备份所有数据库 + 全局对象(角色、表空间、配置等)

📌 基本语法:
bash 复制代码
pg_dumpall [选项] > 备份文件
✅ 案例3:备份整个 PostgreSQL 实例
bash 复制代码
# 备份所有数据库 + 全局对象(角色、表空间等)
pg_dumpall -U postgres -h localhost > full_server_backup.sql

# 仅备份全局对象(角色、表空间)
pg_dumpall -U postgres --globals-only > globals_backup.sql

# 仅备份某个数据库(等同 pg_dump)
pg_dumpall -U postgres -l mydb > mydb_via_dumpall.sql

# 带清理命令(恢复时先 DROP 再 CREATE)
pg_dumpall -U postgres -c > full_server_with_clean.sql

⚠️ 注意

  • pg_dumpall 只支持 Plain 格式(SQL 脚本)
  • 不能并行备份
  • 恢复时需超级用户权限

✅ 二、数据还原(Restore)


2.1 使用 pgAdmin 4 还原数据库

适用场景:开发、测试环境

📌 操作步骤:
  1. 右键目标数据库 → Restore...
  2. 选择备份文件(必须与备份格式匹配)
  3. 设置参数:
    • Format:自动识别或手动选择
    • Restore options
      • Clean before restore → 先删除现有对象(危险!)
      • Single transaction → 失败则全回滚
      • Include CREATE DATABASE → 从备份创建新库
  4. 点击 Restore

注意事项

  • 还原前确保目标数据库存在(除非勾选 CREATE DATABASE)
  • 还原用户需有目标库的 CREATE 权限
  • 大文件还原可能超时 → 调整 Preferences > Miscellaneous > Process timeout

2.2 使用 psql 还原数据库(SQL 格式)

适用pg_dumppg_dumpall 生成的 .sql 文件

📌 基本语法:
bash 复制代码
psql [选项] 数据库名 < 备份文件
✅ 案例4:还原 SQL 备份
bash 复制代码
# 还原到现有数据库(需先创建空库)
createdb -U postgres mydb_restored
psql -U postgres -d mydb_restored < mydb_full_backup.sql

# 还原 pg_dumpall 备份(需超级用户)
psql -U postgres -f full_server_backup.sql postgres
# 注意:pg_dumpall 备份包含 CREATE DATABASE,会自动创建库

# 带事务还原(失败则回滚)
psql -U postgres -d mydb_restored -v ON_ERROR_STOP=1 < mydb_full_backup.sql

# 详细模式 + 错误停止
psql -U postgres -d mydb_restored -v ON_ERROR_STOP=1 -q -f mydb_full_backup.sql

常用 psql 选项

  • -v ON_ERROR_STOP=1 → 遇错停止(推荐)
  • -q → 静默模式(不显示 SQL)
  • -1 → 单事务模式(等同 --single-transaction

2.3 使用 pg_restore 快速还原数据库(自定义/目录格式)

核心优势 :支持选择性还原并行还原灵活控制

📌 基本语法:
bash 复制代码
pg_restore [选项] -d 数据库名 备份文件
📌 常用选项:
选项 说明
-d dbname 目标数据库
-F format 格式(通常自动识别)
-c 还原前清理(DROP 对象)
-C 创建数据库(备份中需包含 CREATE DATABASE)
-j jobs 并行还原(加速)
-t table 仅还原指定表
-T table 排除表
-s 仅还原结构
-a 仅还原数据
--single-transaction 单事务模式

✅ 案例5:还原自定义格式备份
bash 复制代码
# 创建目标数据库
createdb -U postgres mydb_restored

# 完整还原自定义格式备份
pg_restore -U postgres -d mydb_restored mydb_backup.custom

# 并行还原(4个进程)
pg_restore -U postgres -d mydb_restored -j 4 mydb_backup.custom

# 仅还原结构
pg_restore -U postgres -d mydb_restored -s mydb_backup.custom

# 仅还原数据(需结构已存在)
pg_restore -U postgres -d mydb_restored -a mydb_backup.custom

# 还原指定表
pg_restore -U postgres -d mydb_restored -t employees mydb_backup.custom

# 清理后还原(危险!先 DROP 所有对象)
pg_restore -U postgres -d mydb_restored -c mydb_backup.custom

# 单事务模式(失败全回滚)
pg_restore -U postgres -d mydb_restored --single-transaction mydb_backup.custom

最佳实践

  • 生产环境优先使用 pg_restore(性能好、控制灵活)
  • 大库还原使用 -j 并行加速
  • 重要操作前先 -s 仅还原结构测试

✅ 三、数据库迁移(Migration)


3.1 相同版本 PostgreSQL 之间迁移

最简单场景:直接备份还原

✅ 案例6:同版本迁移(源 → 目标)
bash 复制代码
# 在源服务器备份
pg_dump -U postgres -F c -f mydb_migration.backup mydb

# 拷贝备份文件到目标服务器
scp mydb_migration.backup user@target-server:/tmp/

# 在目标服务器还原
createdb -U postgres mydb
pg_restore -U postgres -d mydb /tmp/mydb_migration.backup

推荐 :使用自定义格式 + pg_restore,支持并行


3.2 不同版本 PostgreSQL 之间迁移

原则从低版本 → 高版本(兼容),高→低需特殊处理

✅ 案例7:从 PostgreSQL 14 → 16 迁移
bash 复制代码
# 在旧版本(14)服务器备份为 SQL 格式(兼容性最好)
pg_dump -U postgres --no-sync -f mydb_v14.sql mydb

# 拷贝到新服务器(16)
scp mydb_v14.sql user@pg16-server:/tmp/

# 在新版本(16)创建数据库并还原
createdb -U postgres mydb
psql -U postgres -d mydb -v ON_ERROR_STOP=1 -f /tmp/mydb_v14.sql

# ✅ 验证数据
psql -U postgres -d mydb -c "SELECT COUNT(*) FROM employees;"

⚠️ 注意

  • 使用 --no-sync 避免旧版本不支持的选项
  • 还原后运行 ANALYZE 更新统计信息
  • 检查扩展是否兼容(如 postgis)
❌ 从高版本 → 低版本?

不推荐 !可能因语法/功能不兼容失败。

替代方案:

  1. 导出为 CSV + 手动建表
  2. 使用中间工具(如 pgloader)
  3. 升级目标服务器版本

3.3 不同数据库之间迁移(如 MySQL → PostgreSQL)

常用工具pgloader, ETL 工具, 手动导出导入

✅ 案例8:使用 pgloader 迁移 MySQL → PostgreSQL
bash 复制代码
# 安装 pgloader(Linux)
sudo apt-get install pgloader

# 创建迁移配置文件 migrate.load
/*
load database
    from mysql://user:pass@localhost/mydb
    into postgresql://postgres:pass@localhost/mydb_pg

with include drop, create tables, create indexes, reset sequences

set MySQL PARAMETERS net_read_timeout = '600';

;*/

# 执行迁移
pgloader migrate.load

# ✅ 验证
psql -U postgres -d mydb_pg -c "\dt"
psql -U postgres -d mydb_pg -c "SELECT COUNT(*) FROM users;"
✅ 案例9:手动 CSV 迁移
sql 复制代码
-- 在源数据库(MySQL)导出 CSV
SELECT * FROM employees INTO OUTFILE '/tmp/employees.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';

-- 在 PostgreSQL 创建表(需手动匹配结构)
CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100),
    salary NUMERIC(10,2)
);

-- 导入 CSV
COPY employees (id, name, email, salary)
FROM '/tmp/employees.csv'
WITH (FORMAT csv, HEADER true, DELIMITER ',', QUOTE '"');

-- ✅ 验证
SELECT COUNT(*) FROM employees;

推荐工具

  • pgloader:自动化迁移,支持多种源
  • AWS DMS / Azure Data Factory:云环境
  • Python pandas + SQLAlchemy:定制化迁移

✅ 四、综合实战案例

🎯 案例1:生产环境每日自动备份脚本

bash 复制代码
#!/bin/bash
# 文件名:daily_backup.sh
# 功能:每日自动备份数据库,保留7天

# 配置
DB_NAME="production_db"
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)
USER="backup_user"  # 需有数据库连接权限

# 创建备份目录
mkdir -p $BACKUP_DIR

# 执行备份(自定义格式 + 压缩)
pg_dump -U $USER -F c -Z 6 -f "$BACKUP_DIR/${DB_NAME}_${DATE}.backup" $DB_NAME

# 记录日志
echo "[$(date)] 备份完成: ${DB_NAME}_${DATE}.backup" >> /var/log/pg_backup.log

# 删除7天前的备份
find $BACKUP_DIR -name "*.backup" -mtime +7 -delete

# 发送通知(可选)
# echo "备份完成" | mail -s "PostgreSQL Backup" admin@company.com

设置定时任务(crontab)

bash 复制代码
# 每天凌晨2点执行
0 2 * * * /path/to/daily_backup.sh

🎯 案例2:灾难恢复演练(完整流程)

bash 复制代码
# 1. 模拟灾难:删除数据库
dropdb -U postgres production_db

# 2. 从最近备份恢复
#    假设最新备份:production_db_20250912_020000.backup

# 3. 创建新数据库
createdb -U postgres production_db

# 4. 并行还原(4进程)
pg_restore -U postgres -d production_db -j 4 \
    /backup/postgresql/production_db_20250912_020000.backup

# 5. 验证关键表
psql -U postgres -d production_db -c "SELECT COUNT(*) FROM orders;"
psql -U postgres -d production_db -c "SELECT COUNT(*) FROM users;"

# 6. 更新统计信息(优化查询计划)
psql -U postgres -d production_db -c "ANALYZE;"

# 7. 通知团队恢复完成
echo "灾难恢复完成!数据已还原至 2025-09-12 02:00" | mail -s "RECOVERY COMPLETE" team@company.com

🎯 案例3:跨云迁移(AWS RDS PostgreSQL → Azure PostgreSQL)

bash 复制代码
# 步骤1:从 AWS RDS 备份
pg_dump -h my-rds-instance.xxxxxx.us-east-1.rds.amazonaws.com \
        -p 5432 -U master_user \
        -F c -Z 6 -f aws_db.backup mydb

# 步骤2:上传到 Azure Blob(或直接下载到本地)
az storage blob upload \
    --account-name mystorage \
    --container-name backups \
    --file aws_db.backup \
    --name aws_db.backup

# 步骤3:从 Azure VM 下载并还原到 Azure PostgreSQL
wget https://mystorage.blob.core.windows.net/backups/aws_db.backup

# 创建数据库
createdb -h my-azure-pg.postgres.database.azure.com \
         -p 5432 -U admin_user@my-azure-pg mydb_restored

# 还原(Azure 需 SSL)
pg_restore -h my-azure-pg.postgres.database.azure.com \
           -p 5432 -U admin_user@my-azure-pg \
           -d mydb_restored \
           --sslmode=require \
           -j 4 \
           aws_db.backup

# ✅ 验证连接
psql "host=my-azure-pg.postgres.database.azure.com port=5432 dbname=mydb_restored user=admin_user@my-azure-pg sslmode=require"

✅ 五、常见问题及解答(FAQ)

❓ 疑问1:pg_dump 备份的文件只能在 PostgreSQL 中使用吗?

答案基本是的,但有例外:

  • Plain 格式(.sql)
    • 可在其他数据库尝试执行(如 MySQL、SQL Server)
    • 但大概率失败 !因为:
      • PostgreSQL 特有语法(如 SERIAL, JSONB, ILIKE
      • 函数不同(NOW() vs CURRENT_TIMESTAMP
      • 数据类型不兼容
  • Custom/Directory/Tar 格式
    • 只能用 pg_restore 还原到 PostgreSQL
    • 是 PostgreSQL 专有二进制格式
      跨数据库迁移正确姿势
  1. 使用 pg_dump --data-only --column-inserts 导出 INSERT 语句
  2. 手动修改 SQL 语法适配目标数据库
  3. 使用 ETL 工具(如 pgloader, Talend, Informatica)
  4. 导出 CSV + 手动建表
bash 复制代码
# 导出为兼容性较好的 INSERT 语句
pg_dump -U postgres --data-only --column-inserts mydb > mydb_inserts.sql

❓ 疑问2:使用 pgAdmin 恢复数据库时需要注意什么问题?

关键注意事项

  1. 目标数据库必须存在 (除非勾选 "Create Database")

    • 否则报错:database "xxx" does not exist
  2. 用户权限不足

    • 需对目标库有 CREATE 权限
    • 全局对象(角色、表空间)需超级用户
  3. 备份格式不匹配

    • Custom 格式备份不能用 "Plain" 格式还原
    • pgAdmin 通常能自动识别,但手动选错会失败
  4. 大文件超时

    • 默认超时 120 秒 → 修改:File > Preferences > Miscellaneous > Process timeout
  5. 编码问题

    • 备份和目标库编码需一致(推荐 UTF8)
    • 否则出现乱码或报错
  6. 对象冲突

    • 表已存在时,需勾选 "Clean before restore"(危险!)
    • 或手动先删除目标表
  7. 扩展依赖

    • 备份中包含 CREATE EXTENSION,目标库需已安装扩展
      安全还原步骤
  8. 创建空数据库:CREATE DATABASE mydb_restored;

  9. 在 pgAdmin 中右键该库 → Restore

  10. 选择备份文件 → Format 选 "Custom"(如适用)

  11. 不勾选 "Clean"(除非确定要删除现有数据)

  12. 点击 Restore → 监控日志


✅ 六、备份还原最佳实践总结

  1. 备份策略

    • 全量备份 + WAL 归档(实现 PITR)
    • 每日全备,保留 7-30 天
    • 关键库增加备份频率
  2. 工具选择

    • 日常备份pg_dump 自定义格式 + pg_restore
    • 全实例备份pg_dumpall
    • 图形化操作:pgAdmin 4(开发环境)
    • 跨库迁移:pgloader / CSV
  3. 还原测试

    • 定期演练灾难恢复(至少每季度一次)
    • 验证备份文件完整性(pg_restore -l file.backup
  4. 安全与监控

    • 备份文件加密存储
    • 监控备份任务是否成功(日志 + 告警)
    • 限制备份用户权限(非超级用户)
  5. 性能优化

    • 大库使用 -j 并行备份/恢复
    • 使用 directory 格式支持并行
    • 避开业务高峰期执行

🚀 黄金法则
没有验证的备份 = 没有备份!

定期测试还原流程,确保关键时刻能救命!

📚 建议结合 pg_basebackup(物理备份)和 WAL-G(云存储归档)构建企业级备份体系!

相关推荐
袋鼠云数栈2 小时前
构建金融级数据防线:数栈 DataAPI 的全生命周期管理实践
java·大数据·数据库·人工智能·api
星幻元宇VR2 小时前
VR科普学习一体机,在学校教育的应用前景
科技·学习·安全·vr·虚拟现实
庭前云落2 小时前
从零开始的OpenZeppelin学习 1| 安装、使用
学习·区块链
四谎真好看2 小时前
Redis学习笔记(实战篇1)
redis·笔记·学习·学习笔记
曲幽2 小时前
🐢 从0到1,FastAPI + PostgreSQL + Tortoise ORM 实战避坑指南
postgresql·fastapi·orm·migration·pythonweb·asyncpg·tortoise·aerich
yc_xym2 小时前
Redis哨兵(Sentinel)机制
数据库·redis·sentinel
数据知道2 小时前
MongoDB复制集部署实战:三节点集群搭建完整步骤详解
数据库·mongodb
@atweiwei2 小时前
MySQL vs MongoDB 深度对比(底层存储数据结构与并发控制篇)
数据结构·数据库·后端·sql·mysql·mongodb·个人开发
nbsaas-boot2 小时前
SQL JOIN 图解说明
android·数据库·sql