作者介绍:简历上没有一个精通的运维工程师,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。

数据库是一个系统(应用)最重要的资产之一,所以我们的数据库将从以下几个数据库来进行介绍。
MySQL
PostgreSQL(本章节)
Redis
Etcd
我们前面介绍了MySQL使用xtrabackup来进行物理备份(增量备份),今天介绍使用PostgreSQL自带的工具和特性来进行物理备份。
# 停止 PostgreSQL 服务
sudo systemctl stop postgresql
# 备份整个数据目录
tar -czf /backup/pg_backup_$(date +%Y%m%d).tar.gz /var/lib/pgsql/14/*
# 启动服务
sudo systemctl start postgresql# 创建基础备份
pg_basebackup -D /backup/pg_basebackup -Fp -P -R
# 常用参数:
# -D: 备份目录
# -Fp: 纯格式(文件系统格式)
# -Ft: tar 格式
# -P: 显示进度
# -R: 创建恢复配置
# -X: WAL 日志包含方式3.增量备份
PostgreSQL 没有像 MySQL 或 Oracle 那样的传统块级增量备份功能。取而代之的是基于 WAL(预写日志)的连续归档机制,这实际上提供了一种更强大的"增量"备份方式。
pg_basebackup 获得完整的数据目录快照3.1 启用 WAL 归档
# 启用归档模式(需重启数据库生效)
archive_mode = on
# WAL 日志的保留策略(确保归档完成前不被覆盖)
# 推荐设置为:max_wal_senders + 1(流复制场景)或根据归档速度调整
wal_keep_size = 1GB # 或使用 wal_keep_segments(旧版本,单位:8KB 块)
# 归档命令:将 WAL 文件复制到归档目录(需确保目录存在且权限正确)
# %p:当前 WAL 文件的路径(相对 $PGDATA)
# %f:当前 WAL 文件的文件名
archive_command = 'cp %p /path/to/archive/%f' # 基础示例(本地归档)
# 生产环境推荐:使用 rsync 同步到远程存储,或结合脚本确保归档成功
# archive_command = 'rsync -a %p user@backup-server:/path/to/archive/%f'如果权限不足,则会出现下面的错误。

3.2 创建基础备份(全量)
bash-4.2$ pg_basebackup -D /var/lib/pgsql/14/base_backup/$(date +%Y%m%d) -Fp -Xs
bash-4.2$ cd /var/lib/pgsql/14/
bash-4.2$ ls -l
total 8
drwx------ 2 postgres postgres 6 Aug 13 17:23 backups
drwx------ 3 postgres postgres 22 Nov 10 22:20 base_backup
drwx------ 20 postgres postgres 4096 Nov 10 22:18 data
-rw------- 1 postgres postgres 921 Oct 28 23:04 initdb.log3.3 插入数据,确认WAL归档是否正常
从数据库里面查看:
postgres=# SELECT * FROM pg_stat_archiver;
archived_count | last_archived_wal | last_archived_time | failed_count | last_failed_wal | last_failed_time | stats_reset
----------------+--------------------------+-------------------------------+--------------+--------------------------+-------------------------------+-------------------------------
4 | 00000002000000000000000E | 2025-11-10 22:26:30.613117+08 | 22 | 00000002000000000000000C | 2025-11-10 22:26:27.040373+08 | 2025-11-10 21:55:25.934074+08
(1 row)从文件查看:
bash-4.2$ ls -l backups/
total 49156
-rw------- 1 postgres postgres 16777216 Nov 10 22:26 00000002000000000000000C
-rw------- 1 postgres postgres 16777216 Nov 10 22:26 00000002000000000000000D
-rw------- 1 postgres postgres 338 Nov 10 22:26 00000002000000000000000D.00000028.backup
-rw------- 1 postgres postgres 16777216 Nov 10 22:26 00000002000000000000000E
bash-4.2$ recovery.signal文件,告知 PostgreSQL 启动时进入恢复模式,所以这里需要提前把我们的完整备份放到现在的数据库位置。# 切换到 postgres 用户操作,避免权限问题
su - postgres
# 在数据目录创建恢复触发文件
touch /var/lib/pgsql/14/data/recovery.signal
exit编辑数据目录下的postgresql.conf,配置 WAL 归档读取路径和恢复目标(可选):
vi /var/lib/pgsql/14/data/postgresql.conf# 从归档目录读取 WAL 日志用于恢复
restore_command = 'cp /path/to/archive/%f %p'
# 可选:指定恢复到特定时间点(按需配置,不配置则恢复到最新)
recovery_target_time = '2025-11-10 10:00:00'
# 可选:指定恢复到特定 WAL 位置
recovery_target_lsn = '0/1234ABCD'启动服务后,PostgreSQL 会自动识别recovery.signal并进入恢复模式,通过restore_command读取归档的 WAL 日志重演事务。
注意:这里我这里给大家留了一个坑,看你们能不能发现。