概述
数据丢了,再好的代码也救不回来。
很多开发者觉得备份是运维的事,自己搭个环境跑通就完事了。等到删库跑路的那一刻,才追悔莫及。PostgreSQL 内置了成熟的备份方案,不需要额外买工具,今天就把这3种最常用的备份方式讲清楚。
准备工作
需要满足以下条件:
- 一台已安装 PostgreSQL 的服务器。可以用
apt install postgresql(Ubuntu)或yum install postgresql-server(CentOS)搞定。 - 足够的磁盘空间。备份文件至少预留原始数据 1.5 倍的空间。
- 基本的命令行操作能力。所有操作都在终端完成。
搭建步骤
方法一:pg_dump 逻辑备份(最常用)
pg_dump 是 PostgreSQL 自带的逻辑备份工具。它会导出 SQL 语句,兼容性最好,跨版本也没问题。
备份单个数据库
sudo -u postgres pg_dump mydb > mydb_backup.sql
这条命令会把 mydb 数据库的全部数据导出成 SQL 文件。
备份所有数据库
sudo -u postgres pg_dumpall > all_databases_backup.sql
压缩备份,节省空间
sudo -u postgres pg_dump -Fc mydb > mydb_backup.dump
-Fc 是自定义压缩格式。比 SQL 文本小很多,而且支持并行恢复。
指定备份时间点(PITR 前置)
sudo -u postgres pg_dump -F c -b -v -f full_backup.dump --blobs mydb
-b 表示同时备份大对象(如图片附件),-v 显示详细进度。
恢复备份
# 创建目标数据库
sudo -u postgres createdb mydb_restored
# 从 SQL 文件恢复
psql -U postgres -d mydb_restored -f mydb_backup.sql
# 从自定义格式恢复
pg_restore -U postgres -d mydb_restored mydb_backup.dump
方法二:pg_basebackup 物理备份(全库热备)
pg_basebackup 是直接复制数据文件的物理备份。适合大规模数据库,备份速度快,恢复也更快。
执行全量备份
sudo -u postgres pg_basebackup -D /backup/postgresql/full -Fp -Xs -P -h 127.0.0.1 -p 5432
参数说明:
-D指定备份目录-Fp使用平面文件(不是 tar 包)-Xs同时复制 WAL 日志-P显示进度
配置流复制(持续备份基础)
# 编辑 postgresql.conf
sudo vim /etc/postgresql/16/main/postgresql.conf
找到并修改以下配置:
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1GB
# 编辑 pg_hba.conf 允许流复制
sudo vim /etc/postgresql/16/main/pg_hba.conf
添加一行:
host replication all 0.0.0.0/0 md5
# 重启生效
sudo systemctl restart postgresql
方法三:crontab 自动化备份(推荐配置)
手工备份容易忘。用 crontab 自动跑,省心。
编写备份脚本
sudo vim /opt/scripts/pg_backup.sh
写入以下内容:
#!/bin/bash
BACKUP_DIR="/backup/postgresql/cron"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="mydb"
KEEP_DAYS=7
mkdir -p $BACKUP_DIR
# 使用自定义格式压缩备份
sudo -u postgres pg_dump -Fc $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.dump
# 删除7天前的旧备份
find $BACKUP_DIR -name "*.dump" -mtime +${KEEP_DAYS} -delete
echo "$(date): $DB_NAME backup completed" >> $BACKUP_DIR/backup.log
# 添加执行权限
sudo chmod +x /opt/scripts/pg_backup.sh
配置定时任务
crontab -e
添加这一行,每天凌晨3点备份:
0 3 * * * /opt/scripts/pg_backup.sh
验证自动备份
# 查看备份文件
ls -lh /backup/postgresql/cron/
# 查看备份日志
tail -f /backup/postgresql/cron/backup.log
验证部署
按以下方式确认备份有效:
- 检查备份文件大小:
ls -lh /backup/postgresql/cron/,文件不能是0字节。 - 恢复测试:在测试环境创建新库,导入备份,确认数据完整。
- 检查 crontab 状态:
crontab -l,确认定时任务已保存。
# 快速验证:导入备份到一个测试库
sudo -u postgres createdb test_restore
pg_restore -U postgres -d test_restore /backup/postgresql/cron/$(ls /backup/postgresql/cron/ | tail -1)
sudo -u postgres psql -d test_restore -c "SELECT count(*) FROM your_table;"
常见问题
Q1:备份时数据库正在写入数据,会不会出错?
不会。pg_dump 在备份开始时获取一个快照,后续写入不会影响备份一致性。如果数据量特别大,可以考虑用 -j 参数并行备份:pg_dump -j 4 -Fc mydb > backup.dump。
Q2:备份文件太大了怎么办?
用 -Fc 压缩格式,通常能缩小到原始大小的 30%-50%。如果还不够,可以加 -Z 9 开到最大压缩:pg_dump -Fc -Z 9 mydb > backup.dump。
Q3:如何备份到远程服务器?
最简单的方式是用 rsync:
rsync -avz /backup/postgresql/cron/ user@remote-server:/backup/postgresql/
如果想一步到位,pg_dump 直接输出到远程:
sudo -u postgres pg_dump -Fc mydb | ssh user@remote-server "cat > /backup/mydb.dump"
Q4:PostgreSQL 版本升级时备份还可用吗?
pg_dump 导出的 SQL 文件跨版本兼容性好。从 PG 14 导出,导入到 PG 16 完全没问题。但 pg_basebackup 不行,升级前一定要用 pg_dump 做一次逻辑备份,以防万一。
数据这东西,用的时候没感觉,丢了才知道多要命。花10分钟配好自动备份,能省去后面10小时的补救。
选一种方式先跑起来,明天再来后悔也来得及。