在数据库运维里,有一件事怎么强调都不过分:备份。 对于 PostgreSQL 来说,物理备份(Physical Backup)不只是倒个 SQL 文件那么简单。它直接关系到你的高可用架构能不能跑起来、灾难恢复能不能兜住底、搭建从库(Standby)能不能丝滑上手。可以说,物理备份是生产环境中保证数据
在数据库运维里,有一件事怎么强调都不过分:备份。
对于 PostgreSQL 来说,物理备份(Physical Backup)不只是倒个 SQL 文件那么简单。它直接关系到你的高可用架构能不能跑起来、灾难恢复能不能兜住底、搭建从库(Standby)能不能丝滑上手。可以说,物理备份是生产环境中保证数据安全的核心手段。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

说白了,物理备份就是直接把 PostgreSQL 的数据文件整份拷走。具体来说,包括 $PGDATA 目录里的这些东西:
base/)pg_wal/)global/pg_control)postgresql.conf、pg_hba.conf 等)和逻辑备份(pg_dump)比,物理备份的差异非常明显:
要想顺利执行物理备份,有几点必须提前确认:
wal_level >= replica(默认就是 replica,基本不用动);pg_basebackup -X stream;pg_basebackup 是 PostgreSQL 自带的备份工具,专为基础备份(Base Backup)而设计。它支持流式传输 WAL,操作简单又安全,官方出品,值得信赖。
pg_basebackup [选项] -D <目标目录>
| 选项 | 说明 |
|---|---|
-h | 主库 IP 或主机名 |
-U | 复制用户(需要有 REPLICATION 权限) |
-D | 备份输出目录 |
-Fp / -Ft | 输出格式:plain(默认)或 tar |
-X stream | 同时流式接收 WAL,防止备份期间 WAL 被清理 |
-P | 显示进度,看着踏实 |
-v | 详细输出,方便排查 |
-R | 自动生成 standby 配置,搭建从库时省不少事 |
-C | 在主库创建复制槽,防止 WAL 过早回收 |
-S | 指定复制槽名称 |
# 创建备份目录 mkdir -p /backup/base_$(date +%Y%m%d) # 执行备份 pg_basebackup -h 192.168.10.50 -U repuser -D /backup/base_$(date +%Y%m%d) -Fp -P -v -X stream
这份备份以后拿来做 PITR 恢复完全没问题。但要注意,它不能直接启动为从库,因为少了
standby.signal文件,从库不会认它。
如果你的存储系统支持快照(比如 LVM、ZFS、Btrfs),那备份速度简直起飞——几乎是瞬时的,而且对数据库性能影响极小。
创建快照卷
lvcreate -L 10G -s -n pgdata_snap /dev/vg0/pgdata
快照大小要留够,至少能容下备份期间的写入量。
挂载快照并拷贝
mkdir /mnt/snap mount /dev/vg0/pgdata_snap /mnt/snap rsync -aHAXx /mnt/snap/ /backup/base_$(date +%Y%m%d)/ umount /mnt/snap
删除快照
lvremove /dev/vg0/pgdata_snap
pg_start_backup() / pg_stop_backup() 使用。注意:PostgreSQL 15+ 已经弃用了
pg_start_backup(),现在更推荐用pg_basebackup,或者存储快照+WAL 归档的组合。
物理备份还是搭建从库最标准、最高效的方式。下面的操作,堪称标准流程。
| 节点 | IP | 角色 |
|---|---|---|
| node1 | 192.168.10.50 | Primary |
| node2 | 192.168.10.51 | Standby |
前提条件:
listen_addresses = '*' wal_level = replica max_wal_senders = 10 wal_keep_size = 1GB # PG 13+,旧版用 wal_keep_segments hot_standby = on
# 允许复制连接 host replication repuser 192.168.10.51/32 md5
CREATE USER repuser WITH REPLICATION ENCRYPTED PASSWORD 'replpass123';
pg_ctl reload -D $PGDATA
sudo systemctl stop postgresql-14
rm -rf /var/lib/pgsql/14/data/*
sudo -u postgres pg_basebackup -h 192.168.10.50 -U repuser -D /var/lib/pgsql/14/data -P -v -R -X stream -C -S standby_slot_1
这里几个选项作用很大:
-R:自动帮你生成 standby.signal 和 postgresql.auto.conf(里面会包含 primary_conninfo);-C -S:在主库创建名为 standby_slot_1 的复制槽,避免 WAL 被过早清理导致从库断连。/var/lib/pgsql/14/data/standby.signal(这是一个空文件,但它的存在告诉 Pg:你是从库);postgresql.auto.conf 里会类似这样:primary_conninfo = 'user=repuser password=replpass123 host=192.168.10.50 port=5432 sslmode=prefer sslcompression=0 gssencmode=prefer krbsrvname=postgres target_session_attrs=any' primary_slot_name = 'standby_slot_1'
sudo systemctl start postgresql-14
-- 确认处于恢复模式 SELECT pg_is_in_recovery(); -- 应返回 true -- 查看是否只读 SHOW hot_standby; -- on
-- 查看复制状态 SELECT * FROM pg_stat_replication;
这里有几个关键字段得看:
application_name:默认是 pg_basebackup,可以通过 -E 指定名字;state:显示 streaming 说明复制正常;sync_state:async(异步)还是 sync(同步)。如果你只是想做灾难恢复,不打算搭建从库,那物理备份配合 WAL 归档就能实现任意时间点恢复。
# postgresql.conf archive_mode = on archive_command = 'cp %p /archive/wal/%f'
记得确保 /archive/wal/ 目录存在,并且 PostgreSQL 进程有写权限。
停止 PostgreSQL
pg_ctl stop -D $PGDATA
清理原数据目录
rm -rf $PGDATA/*
还原物理备份
cp -r /backup/base_20260210/* $PGDATA/
创建 recovery.signal
touch $PGDATA/recovery.signal
配置恢复目标(可选)
在 $PGDATA/postgresql.auto.conf 中加上:
restore_command = 'cp /archive/wal/%f %p' recovery_target_time = '2026-02-10 18:00:00'
启动数据库
pg_ctl start -D $PGDATA
数据库会重放 WAL 直到目标时间点,然后自动转为主库模式。
复制槽是一个非常有用的机制:它能让主库知道,从库还没收到哪些 WAL。即便从库断连了,主库也不会覆盖它还没消费的 WAL,这就避免了从库再也追不上的情况。
在主库创建槽:
SELECT pg_create_physical_replication_slot('standby1');
postgresql.auto.conf 里指定 primary_slot_name。注意:复制槽是双刃剑。如果从库长期断连,主库就会攒下大量 WAL,磁盘爆满的风险是真实存在的。所以务必盯着点 slot 的 lag。
pg_basebackup ... -Ft | gzip > backup.tar.gz
pg_basebackup ... -D - | ssh user@remote "cat > backup.tar"
#!/bin/bash
BACKUP_DIR="/backup/base_$(date +%Y%m%d)"
pg_basebackup -h 192.168.10.50 -U repuser -D "$BACKUP_DIR" -Fp -P -X stream
if [ $ -eq 0 ]; then
echo "Backup succeeded: $BACKUP_DIR"
# 清理7天前的备份
find /backup -name "base_*" -mtime +7 -exec rm -rf {} \;
else
echo "Backup failed!"
exit 1
fi
| 问题 | 原因 | 解决方案 |
|---|---|---|
pg_basebackup: could not connect to server | 主库没监听、防火墙挡了、认证失败 | 仔细检查 listen_addresses、pg_hba.conf、网络连通性 |
| 从库启动报错 “WAL ends before end of backup” | 备份期间主库重启了,导致 WAL 不连续 | 使用 -X stream 或者确保 WAL 归档完整 |
| 从库延迟高 | 网络慢、主库负载太大 | 监控 pg_stat_replication,优化硬件配置 |
| 无法写入从库 | 这是正常行为 | 从库本来就是只读的,想写入得先 promote 它 |
| 维度 | 物理备份 | 逻辑备份 |
|---|---|---|
| 恢复速度 | 极快(文件拷贝) | 慢(SQL 重放) |
| 备份体积 | 大(含所有文件) | 小(只有数据+DDL) |
| 跨版本迁移 | 不支持(主版本必须相同) | 支持(版本兼容即可) |
| 搭建从库 | 唯一标准方式 | 不可行 |
| PITR 支持 | 是(需要 WAL) | 否 |
| 存储开销 | 高 | 低 |
结论:生产环境的高可用架构,物理备份是绕不开的基石。逻辑备份适合跨版本迁移或单表导出的场景。
总结下来,PostgreSQL 物理备份就是构建高可用、实现灾难恢复的基石。借助 pg_basebackup,你可以一站式完成:
最后,几个关键点值得反复提醒自己:
wal_level = replica 和复制权限;-R -X stream -C 选项组合,能省掉很多手动操作;掌握物理备份技术,是每个 PostgreSQL DBA 的基本功,也是生产环境高可用的起点。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述