pg_basebackup
pg_basebackup 是 PostgreSQL 官方提供的、用于获取基础备份(base backup)的客户端工具。它通过复制协议(replication protocol)连接到一个正在运行的主库或备库,向服务端请求一次完整的基础备份,并把结果写到本地目录(或服务端目录,或直接丢弃)。
它最大的价值在于「省心」:备份开始时自动进入备份模式、结束时自动退出、自动处理备份期间产生的 WAL、自动生成 backup_manifest 校验清单。你不需要手工调用 pg_backup_start() / pg_backup_stop(),也不用担心「文件扫描时刻」与「WAL 起点」是否配套——这些都是工具在协议层替你保证的。
代价是它有一些使用前提(需要 REPLICATION 权限、需要 pg_hba.conf 放行复制连接、需要足够的 walsender),以及它永远只能做集簇级备份、不能选择性备份单库单表。本页按「连接 → 格式 → WAL → 压缩 → 槽 → 表空间 → 进度 → 校验 → 增量 → 性能」的顺序,把它的全部关键选项讲清楚。
基础概念
pg_basebackup 是什么
pg_basebackup 是一个普通的 PostgreSQL 客户端程序,它使用复制协议(而不是 SQL)与服务端通信:
- 连接时在启动参数里带上
replication=true,让后端进入 walsender 模式; - 通过复制命令(如
BASE_BACKUP)请求服务端开始一次基础备份; - 服务端自行执行「开始备份 → 传输文件 → 结束备份」的全过程;
- 客户端把收到的文件写到目标目录(或 tar 包、stdout)。
因此,备份的一致性由服务端保证,客户端只负责传输与落盘。
使用前提
| 前提 | 说明 |
|---|---|
| 连接用户 | 需具备 REPLICATION 属性或超级用户身份 |
pg_hba.conf | 必须放行该用户的复制连接 |
max_wal_senders | 至少留出一个 walsender 给备份,使用 -X stream 时还要再多一个 |
wal_level | 需为 replica 或更高(logical) |
| 目标目录 | -D 指定的目录可以不存在(会自动创建),但若存在则必须为空 |
# 创建一个专用备份用户(最小权限:仅 REPLICATION)
psql -c "CREATE ROLE backup_user WITH LOGIN REPLICATION PASSWORD 'strong_password';"# pg_hba.conf 中放行复制连接
host replication backup_user 10.0.0.0/24 scram-sha-256核心选项速览
| 选项 | 作用 |
|---|---|
-D / --pgdata | 目标目录(tar 格式可写 - 表示 stdout) |
-F / --format | 输出格式:p / plain(默认)、t / tar |
-X / --wal-method | WAL 收集方式:n / none、f / fetch、s / stream(默认) |
-Z / --compress | 压缩:[{client|server}-]method[:detail] |
-z / --gzip | 等价于客户端 gzip 压缩(仅 tar 格式) |
-c / --checkpoint | 检查点模式:fast / spread(默认) |
-R / --write-recovery-conf | 生成 standby.signal 并写入连接配置 |
-C / --create-slot | 备份前创建 --slot 指定的复制槽 |
-S / --slot | 备份时使用指定复制槽 |
-l / --label | 备份标签(写入 backup_label) |
-T / --tablespace-mapping | 重定位表空间的落地路径 |
--waldir | 指定 WAL 落盘目录(仅 plain 格式) |
-P / --progress | 打印进度 |
-r / --max-rate | 限制数据传输速率 |
-i / --incremental | 增量备份(PG17+),需提供参考备份的 manifest |
输出格式:plain 与 tar
| 格式 | -F 取值 | 产物 | 特点 |
|---|---|---|---|
| 平铺文件 | p / plain | 与源数据目录相同布局的目录树 | 默认;可直接启动、可增量、可用 --tablespace-mapping |
| tar 归档 | t / tar | base.tar(+ 各表空间 OID 命名的 tar、pg_wal.tar) | 便于打包传输;-D - 可管道输出 |
WAL 收集方式
| 方式 | -X 取值 | 何时获取 WAL | 关键约束 |
|---|---|---|---|
| 不含 | n / none | 不获取 | 恢复必须依赖外部 WAL 归档 |
| 结束时收集 | f / fetch | 备份结束后一次性拉取 | 需 wal_keep_size 足够大,否则 WAL 可能已被回收 |
| 流式获取 | s / stream | 备份期间并行接收 | 默认;需额外一个 walsender |
-X stream 是默认值,也是三者在「可靠性」上最优的选择:WAL 从备份一开始就持续接收,不留任何窗口。
-X none 与归档的关系
-X none 产出的备份不含 WAL,它只有在「你另有连续的 WAL 归档」时才可恢复。若既没有归档、又选了 none,这个备份不完整。
backup_manifest
除 --no-manifest 外,pg_basebackup 默认会生成 backup_manifest:一份列出备份内所有文件(路径、大小、修改时间、校验和)的 JSON 清单,并放在备份根目录(tar 格式下位于 base.tar 内)。
它是 pg_verifybackup 校验备份的依据,也是 PG17 原生增量备份的基础——增量备份必须引用一份「参考备份的 manifest」。
语法与用法
基本语法
pg_basebackup [选项...]最简用法
# plain 格式 + 流式 WAL + 进度
pg_basebackup -h 127.0.0.1 -p 5432 -U backup_user \
-D /backup/base_20260930 -Fp -Xs -P 0/2290400 kB (0%), 0/1 tablespace (...)
600260/1200520 kB (50%), 0/1 tablespace (...)
1200520/1200520 kB (100%), 0/1 tablespace (...)tar 格式 + 压缩
# tar 格式,客户端 gzip,写到一个目录
pg_basebackup -h 127.0.0.1 -U backup_user \
-D /backup/base_tar -Ft -Xs -z -P直出 stdout(仅 tar 格式)
# tar 到 stdout,管道给压缩程序(要求无额外表空间且不使用 WAL 流)
pg_basebackup -h 127.0.0.1 -U backup_user \
-D - -Ft -Xn | gzip > /backup/base_20260930.tar.gz校验备份
pg_verifybackup /backup/base_20260930backup successfully verified详细说明
连接参数与权限
pg_basebackup 复用 libpq 的连接参数,同时支持命令行选项与连接字符串:
| 选项 | 含义 |
|---|---|
-h / --host | 主机名或 socket 目录 |
-p / --port | 端口 |
-U / --username | 连接用户 |
-d / --dbname | 连接字符串或数据库名(可携带完整参数) |
-w / --no-password | 不提示密码 |
-W / --password | 强制提示密码 |
-s / --status-interval | 向源服务器发送状态包的间隔秒数 |
# 用连接字符串携带全部参数
pg_basebackup \
-d "host=10.0.0.11 port=5432 user=backup_user dbname=postgres" \
-D /backup/base_20260930 -Fp -Xs -P权限方面有两点必须确认:
-- 1) 用户是否有 REPLICATION 属性
SELECT rolname, rolreplication, rolsuper
FROM pg_roles WHERE rolname = 'backup_user'; rolname | rolreplication | rolsuper
-------------+----------------+----------
backup_user | t | f
(1 row)-- 2) max_wal_senders 是否留有余量
SELECT name, setting FROM pg_settings WHERE name = 'max_wal_senders'; name | setting
-----------------+---------
max_wal_senders | 10
(1 row)复制连接走的是 replication 伪数据库
复制连接不落在某个具体数据库上,pg_hba.conf 里的 replication 关键字(或 all)必须匹配到。只放行了普通 host 规则而没有放行 host replication,pg_basebackup 会直接报连接被拒绝。
输出格式:plain 与 tar
plain 格式(-Fp,默认)产出的目录布局与源数据目录一致:
/backup/base_20260930/
├── PG_VERSION
├── base/
├── global/
├── pg_control
├── pg_wal/ # 若使用 -X stream/fetch,含所需 WAL 段
├── backup_label # 备份标签
├── backup_manifest # 校验清单
├── tablespace_map # 若有额外表空间
└── postgresql.auto.conf # 若使用 -R当集簇有额外表空间时,plain 格式会把主数据目录放进目标目录,而其他表空间仍按源服务器上的绝对路径落地——这意味着目标机器上必须有对应的目录结构。要改变这一点用 -T(见下文)。
tar 格式(-Ft)把主数据目录打包为 base.tar,每个额外表空间打包为以该表空间 OID 命名的 tar 文件;配合 -X stream/fetch 时 WAL 单独打包为 pg_wal.tar。
# 查看 tar 格式的产物
ls -lh /backup/base_tar/-rw-r--r-- 1 postgres postgres 182M Sep 30 02:12 base.tar
-rw-r--r-- 1 postgres postgres 6.4M Sep 30 02:12 pg_wal.tar
-rw-r--r-- 1 postgres postgres 12M Sep 30 02:12 16385.tar-D - 只在 tar 格式下可用,且要求「集簇没有额外表空间」并且「不使用 WAL 流」(即必须显式指定 -Xn 或 -Xf)。
WAL 收集方式:-X
三种方式的行为差异,直接影响恢复时是否还需要归档:
# 1) stream:备份期间并行接收 WAL(默认,最可靠)
pg_basebackup -D /backup/base_stream -Fp -Xs -P
# 2) fetch:备份结束后一次性拉取所需 WAL
pg_basebackup -D /backup/base_fetch -Fp -Xf -P
# 3) none:不收集 WAL,完全依赖外部归档
pg_basebackup -D /backup/base_none -Fp -Xn -P-X fetch 的隐患是「时间窗口」:WAL 在备份结束时才被请求,如果备份耗时长而 wal_keep_size 不够,备份起点所需的 WAL 段可能已经被回收,备份直接失败:
# fetch 模式下的必要配置(示例值,需按备份时长与写入量估算)
wal_keep_size = 2GB-X stream 需要额外的 walsender 与网络带宽,但换来的是「无窗口」。此外 -X stream 有一个附加特性:它顺带把备份期间的 WAL 一并写进备份包,使得备份成为完全独立可启动的(standalone)。
-Xstream 与 --target 不能同时使用
--target=server:/path 表示备份由服务端自行落盘,而 WAL 流式接收是客户端实现的功能,二者矛盾。使用 --target 时必须改写 -Xfetch 或 -Xnone。
压缩:-z 与 -Z
-z 是 -Z 的简化形式(仅 tar 格式 + 客户端 gzip)。完整的 -Z 语法为:
-Z [{client|server}-]method[:detail]
--compress=[{client|server}-]method[:detail]| 部分 | 取值 | 说明 |
|---|---|---|
| 执行位置 | client / server | 省略时默认 client;使用 --target 时只有 server 有意义 |
| 方法 | gzip / lz4 / zstd / none | 也可写整数(0 表示不压缩,>0 表示 gzip 及等级) |
| 细节 | 整数等级,或 level= / workers= 等关键字 | 方法写成整数时不能再带 detail |
# 服务端 zstd 压缩(省带宽,耗服务端 CPU)
pg_basebackup -D /backup/base_s -Fp -Xs --compress=server-zstd:level=3
# 客户端 lz4 压缩(快、压缩率一般)
pg_basebackup -D /backup/base_c -Fp -Xs --compress=client-lz4
# tar 格式 + 客户端 zstd:文件名自动加 .zst 后缀
pg_basebackup -D /backup/base_t -Ft -Xs -Z zstd:3压缩与 WAL 的交互有一条容易踩的规则:使用 -X stream 时,服务端压缩不会作用于 WAL;若使用客户端 gzip 压缩,pg_wal.tar 也会被 gzip 压缩,而其他压缩算法或服务端压缩下 pg_wal.tar 不压缩。要压缩 WAL 中的内容,应改用客户端压缩或 -X fetch。
plain 格式的压缩
plain 格式下不能用客户端压缩(文件需要直接落地),但可以请求服务端压缩:服务端压缩后传输,客户端接收时解压并落盘。
检查点模式:-c fast 与 spread
备份开始前,服务端必须做一次检查点。-c 控制这次检查点的行为:
| 取值 | 行为 | 适用场景 |
|---|---|---|
spread(默认) | 尽量摊薄检查点的 I/O 冲击,尽快完成但不过度影响在线业务 | 绝大多数在线业务场景 |
fast | 立即强制完成检查点 | 停机窗口、对备份启动时延敏感的场景 |
# 在线备份:保持默认
pg_basebackup -D /backup/base_online -Fp -Xs
# 停机窗口:加速检查点
pg_basebackup -D /backup/base_window -Fp -Xs -c fastfast 会一次性把累积的脏页全部刷盘,产生明显的写 I/O 尖峰;spread 让 I/O 更平滑,代价是备份的「启动时间」稍长。
复制槽与 -C / -S / --no-slot
使用复制槽的好处是:服务端会为这个槽保留备份所需的 WAL,避免因 wal_keep_size 不足导致 -X fetch 失败。
# 备份前创建槽,并在备份中使用它
pg_basebackup -D /backup/base_slot -Fp -Xf \
-S basebackup_slot -C -P
# 已存在槽时直接使用(若用 -C 且槽已存在会报错)
pg_basebackup -D /backup/base_slot2 -Fp -Xf \
-S basebackup_slot -P相关选项:
| 选项 | 作用 |
|---|---|
-S slotname / --slot | 指定要使用的复制槽 |
-C / --create-slot | 备份前创建该槽(已存在则报错) |
--no-slot | 不使用槽(默认行为,与 -S 互斥) |
槽会被 postgresql.auto.conf 记录下来(配合 -R 时),便于后续流复制复用同一份设置。
用槽之后要记得清理
使用 -C 创建的临时槽,如果备份结束后不再需要,应在主库上删除,否则它会持续保留 WAL,长期占用磁盘:
SELECT pg_drop_replication_slot('basebackup_slot');表空间处理:-T 与 --waldir
-T olddir=newdir 把源服务器上位于 olddir 的表空间重定位到接收端的 newdir:
pg_basebackup -D /backup/base_reloc -Fp -Xs \
-T /data/tblspc/reporting=/backup/tblspc/reporting \
-T /data/tblspc/archive=/backup/tblspc/archive \
-P要点:
olddir必须与源服务器上表空间的定义逐字一致(若源上不存在该路径,不算错误);newdir不必预先存在,若存在必须为空;- 两个路径都必须是绝对路径;路径中含
=时用反斜杠转义; - 可重复指定多个
-T; - 重定位后,主数据目录内的符号链接会被更新指向新位置;
- 只对 plain 格式有效,tar 格式下会被忽略。
--waldir 用于把 WAL 写到别处(默认写进目标目录下的 pg_wal):
pg_basebackup -D /backup/base_wal -Fp -Xs \
--waldir=/backup/base_wal/wal -P它要求绝对路径、目标必须为空,且仅 plain 格式可用。
直接生成备库配置:-R
-R(--write-recovery-conf)会在目标目录(tar 格式下写入 base.tar)里:
- 创建一个
standby.signal文件; - 把连接设置追加到
postgresql.auto.conf。
pg_basebackup -h 10.0.0.11 -p 5432 -U backup_user \
-D /var/lib/postgresql/18/main \
-Fp -Xs -R -P# postgresql.auto.conf 中被追加的内容(示意)
primary_conninfo = 'user=backup_user passfile=''/var/lib/postgresql/.pgpass'' channel_binding=prefer host=10.0.0.11 port=5432 sslmode=prefer sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'若同时用 -S 指定了槽,槽名也会被记录进去。这样备份产物就是「拿来即用的备库目录」,只需补上 pg_hba.conf 等无关恢复的配置即可启动。
恢复目录也要清空
用 -R 恢复到已有实例的数据目录时,目标必须为空(与 -D 的规则一致)。若原有数据目录非空,先改名挪走,避免工具报错或产生混合内容。
进度观察与状态上报
客户端侧用 -P 打印进度;服务端侧可以查 pg_stat_progress_basebackup:
SELECT
pid,
phase,
backup_total,
backup_streamed,
tablespaces_total,
tablespaces_streamed
FROM pg_stat_progress_basebackup; pid | phase | backup_total | backup_streamed | tablespaces_total | tablespaces_streamed
-------+--------------------------+--------------+-----------------+-------------------+----------------------
21483 | streaming database files | 1200520 | 600260 | 1 | 0
(1 row)phase 的典型取值依次为:initializing → waiting for checkpoint to finish → estimating backup size → streaming database files → transferring wal files。
相关选项:
| 选项 | 作用 |
|---|---|
-P / --progress | 客户端打印进度(近似值,可能不到 100%) |
-s / --status-interval | 状态上报间隔(秒);0 表示禁用周期性上报 |
--no-estimate-size | 不做体积预估,backup_total 恒为 NULL |
-v / --verbose | 输出更多细节 |
# 关闭体积预估:避免在超大库上多花一次全目录扫描
pg_basebackup -D /backup/base_big -Fp -Xs -P --no-estimate-size当备份包内含 WAL 时,总量无法事先精确估算,进度百分比可能超过 100% 或提前「到 100%」。
清单与校验:manifest 相关选项
| 选项 | 作用 |
|---|---|
--no-manifest | 不生成 backup_manifest |
--manifest-checksums=method | 指定 manifest 中的校验算法(如 NONE、CRC32C、SHA224、SHA256、SHA384、SHA512) |
--no-verify-checksums | 不校验服务端计算的文件校验和(只在 archive_mode 关闭等特殊情形下使用) |
# 生成 SHA256 校验的 manifest
pg_basebackup -D /backup/base_sha -Fp -Xs \
--manifest-checksums=SHA256 -P
# 备份后校验
pg_verifybackup /backup/base_sha校验清单的价值在「备份成功 ≠ 备份可用」这个老问题上:文件写出来了不代表没被截断或损坏。pg_verifybackup 会比对文件列表、重算校验和,并用 pg_waldump 解析备份携带的 WAL。
# 若备份未携带 WAL,跳过 WAL 解析
pg_verifybackup --no-parse-wal /backup/base_sha
# 若 manifest 不完整(例如从备库备份),可跳过校验和检查
pg_verifybackup --skip-checksums /backup/base_sha--no-manifest 的代价
不生成 manifest 会让备份无法被 pg_verifybackup 校验,也会让这个备份无法作为 PG17 增量备份的参考备份。除非有明确的特殊理由,不要关闭 manifest。
增量备份:-i(PostgreSQL 17+)
PostgreSQL 17 为物理备份引入了原生增量备份。pg_basebackup -i old_manifest_file 会用「上一次备份的 manifest」作为参考,让服务端只传输自那次备份以来被修改的块:
# 1) 先做一次全量备份(会生成 backup_manifest)
pg_basebackup -D /backup/full_20260930 -Fp -Xs -P
# 2) 做增量备份:引用全量备份的 manifest
pg_basebackup -D /backup/incr_20261001 -Fp -Xs -P \
-i /backup/full_20260930/backup_manifest关键限制:
- 增量备份不能直接使用,必须先与它所依赖的备份合并;
- 合并用
pg_combinebackup:
# 把全量 + 增量合并成一份完整备份
pg_combinebackup /backup/full_20260930 /backup/incr_20261001 \
-o /backup/combined_20261001- 合并后的产物才是可恢复的完整备份;也可以把多个增量一起传入
pg_combinebackup按顺序合并。
# 全量 + 两个增量合并
pg_combinebackup /backup/full_20260930 \
/backup/incr_20261001 \
/backup/incr_20261002 \
-o /backup/combined_20261002它的意义在于:全量备份体积大、耗时长,而日常数据变化通常只占一小部分;增量备份只传变化块,能显著降低每日备份的时长与带宽。第三方工具(pgBackRest / Barman)多年来提供的正是这类能力,PG17 把它做进了核心。
性能与限速
pg_basebackup 是重 I/O 操作,对源库的影响来自三处:起始检查点的刷盘、全目录的顺序读取、以及 WAL 流式传输(-X stream)。
| 选项 | 作用 |
|---|---|
-r / --max-rate | 限制从服务端读取数据的速率(单位 KB/s,可用 M 后缀表示 MB/s,范围 32KB/s ~ 1024MB/s) |
-N / --no-sync | 不等待文件安全落盘就返回(更快,但系统崩溃可能导致备份损坏,生产不推荐) |
--sync-method | 落盘方式:fsync(默认)或 syncfs |
-n / --no-clean | 出错时不清理已创建的目录(便于调试) |
--compress | 压缩传输,降低带宽占用、增加 CPU 开销 |
# 限制速率为 200MB/s,避免挤占在线业务 I/O
pg_basebackup -D /backup/base_limited -Fp -Xs -P -r 200M# 用 syncfs 减少 fsync 调用次数(适合大目录、现代文件系统)
pg_basebackup -D /backup/base_syncfs -Fp -Xs --sync-method=syncfs不要在生产使用 -N
-N(--no-sync)让工具不等待文件落盘就返回。此时若操作系统崩溃,备份可能处于不一致状态。它只适合测试。
从备库做基础备份
pg_basebackup 也能从备库取备份,这对降低主库压力非常有价值:
pg_basebackup -h 10.0.0.12 -p 5432 -U backup_user \
-D /backup/base_from_standby -Fp -Xs -P备库备份的限制需要在设计时考虑到:
- 备份中不会生成备份历史文件;
- 备份结束时无法强制备库切换 WAL 段;使用
-X none且主库写入很低时,可能长时间等待最后一个段被切换归档,此时可在主库上执行pg_switch_wal()主动触发; - 若备库在备份期间被提升为主库,备份会失败;
- 主库必须开启
full_page_writes,保证备份所需 WAL 记录包含完整页镜像。
同时,备库侧要允许复制连接(max_wal_senders、hot_standby、pg_hba.conf)——备库本身也是「会接受复制连接的服务端」。
实战示例
示例一:生产环境标准备份脚本
#!/usr/bin/env bash
set -euo pipefail
BACKUP_ROOT=/backup
STAMP=$(date +%F_%H%M)
TARGET="${BACKUP_ROOT}/full_${STAMP}"
mkdir -p "${TARGET}"
pg_basebackup \
-h 127.0.0.1 -p 5432 -U backup_user \
-D "${TARGET}" \
-Fp -Xs -P -c spread \
-l "full_${STAMP}" \
--compress=server-zstd:level=3 \
--manifest-checksums=SHA256
# 立即校验,失败则以非 0 退出
pg_verifybackup "${TARGET}"
echo "backup ok: ${TARGET}" 0/2290400 kB (0%), 0/1 tablespace (...)
1200520/1200520 kB (100%), 0/1 tablespace (...)
backup successfully verified
backup ok: /backup/full_2026-09-30_0200示例二:从备库备份并带复制槽
# 从备库取备份,使用复制槽保证 WAL 不被提前回收
pg_basebackup \
-h 10.0.0.12 -p 5432 -U backup_user \
-D /backup/from_standby_20260930 \
-Fp -Xf -P \
-S standby_backup_slot -C# 备份结束后在主库/备库上清理临时槽
psql -h 10.0.0.12 -U postgres \
-c "SELECT pg_drop_replication_slot('standby_backup_slot');"示例三:带表空间重定位的备份
# 先把源库的表空间列出来
psql -Atc "SELECT spcname, pg_tablespace_location(oid) FROM pg_tablespace WHERE spcname NOT IN ('pg_default','pg_global');"reporting|/data/tblspc/reporting
archive|/data/tblspc/archive# 备份时把两个表空间重定位到备份盘
pg_basebackup -h 127.0.0.1 -U backup_user \
-D /backup/reloc_20260930 -Fp -Xs -P \
-T /data/tblspc/reporting=/backup/reloc_20260930/tblspc/reporting \
-T /data/tblspc/archive=/backup/reloc_20260930/tblspc/archive# 确认 targets 落到了新位置
cat /backup/reloc_20260930/tablespace_map16385 /backup/reloc_20260930/tblspc/reporting
16386 /backup/reloc_20260930/tblspc/archive示例四:一键生成备库目录
# 直接把备份写成可启动的备库目录
pg_basebackup -h 10.0.0.11 -p 5432 -U replicator \
-D /var/lib/postgresql/18/main \
-Fp -Xs -R -P \
-S standby1_slot -C# 查看生成的信号文件与自动配置
ls /var/lib/postgresql/18/main/standby.signal
grep -n 'primary_conninfo' /var/lib/postgresql/18/main/postgresql.auto.conf/var/lib/postgresql/18/main/standby.signal
5:primary_conninfo = 'user=replicator host=10.0.0.11 port=5432'# 启动并确认处于恢复状态
pg_ctl -D /var/lib/postgresql/18/main start
psql -c "SELECT pg_is_in_recovery();" pg_is_in_recovery
-------------------
t
(1 row)示例五:tar 格式备份 + 全量校验 + 归档
# 1) tar 备份,客户端 zstd 压缩
pg_basebackup -h 127.0.0.1 -U backup_user \
-D /backup/tarpkg_20260930 -Ft -Xs -Z zstd:3 -P 0/2290400 kB (0%), 0/1 tablespace (...)
1200520/1200520 kB (100%), 0/1 tablespace (...)# 2) 打包校验:先把 base.tar 解开再校验
mkdir -p /tmp/verify_tar
tar -C /tmp/verify_tar -xf /backup/tarpkg_20260930/base.tar
pg_verifybackup /tmp/verify_tarbackup successfully verified# 3) 归档到异地
rsync -a --delete /backup/tarpkg_20260930/ backup-host:/archive/pg/tarpkg_20260930/示例六:PG17 增量备份与合并
# 周日:全量
pg_basebackup -D /backup/full_20260928 -Fp -Xs -P
# 周一:增量,引用周日的 manifest
pg_basebackup -D /backup/incr_20260929 -Fp -Xs -P \
-i /backup/full_20260928/backup_manifest
# 周二:增量,引用周一的 manifest
pg_basebackup -D /backup/incr_20260930 -Fp -Xs -P \
-i /backup/incr_20260929/backup_manifest# 需要恢复时,先合并成完整备份
pg_combinebackup /backup/full_20260928 \
/backup/incr_20260929 \
/backup/incr_20260930 \
-o /backup/combined_20260930
# 校验合并结果
pg_verifybackup /backup/combined_20260930backup successfully verified对比一下体积差异:
du -sh /backup/full_20260928 /backup/incr_20260929 /backup/incr_20260930 /backup/combined_202609301.2G /backup/full_20260928
96M /backup/incr_20260929
104M /backup/incr_20260930
1.2G /backup/combined_20260930注意事项
-D 目录必须为空。 目标目录不存在时会自动创建;存在且非空则直接报错。不要把它指向一个正在运行的实例的数据目录。
备份不是「可启动的数据库」的代名词。 只有配合了 -X stream/fetch 或外部连续 WAL 归档,备份才具备完整的恢复能力;-X none 的备份需要归档才能用。
-X fetch 依赖 wal_keep_size 足够大。 备份耗时长、写入量大的库,务必调大 wal_keep_size,或改用复制槽、-X stream。
tar 格式下 -T 会被忽略。 表空间重定位只在 plain 格式生效。如果必须要重定位,就不要用 tar。
-D - 有限制。 只有在 tar 格式、无额外表空间、且不用 WAL 流(必须显式 -Xn 或 -Xf)时才允许把备份写到 stdout。
增量备份不能单独恢复。 必须用 pg_combinebackup 与其依赖的全量(以及中间增量)合并,产物才是完整备份。链条中任何一环丢失,增量都用不了。
-N(--no-sync)不要用于生产。 它不等待落盘,系统崩溃可能导致备份文件损坏。
使用 -C 创建的槽要清理。 忘记删除的槽会持续保留 WAL,最终可能撑满磁盘。
从备库备份有其特性。 无备份历史文件、无法强制切换 WAL 段、备库被提升会让备份失败;主库必须开 full_page_writes。
并发备份要谨慎。 官方建议同一时间只做一次备份,然后复制结果——多个 pg_basebackup 并发会同时压榨源库的 I/O 与 walsender 资源。
备份不能替代归档。 pg_basebackup 只解决「起点」问题,恢复时间点的能力来自持续的 WAL 归档。两者必须配套。
最佳实践
- 把
-P与校验做成标准动作。 每次备份都显示进度,并在备份结束后立刻用pg_verifybackup校验;校验失败立即告警,不要让坏备份进入保留周期:
pg_basebackup -D /backup/full_$(date +%F) -Fp -Xs -P \
&& pg_verifybackup /backup/full_$(date +%F)默认使用
-X stream。 它是默认值,也是唯一没有「WAL 已被回收」时间窗口的方式。只有在明确知道有归档兜底或存储受限时,才考虑-Xf/-Xn。统一使用摊薄式检查点。 在线业务保持
-c spread(默认),只在停机窗口或对备份启动时延敏感时才用-c fast。对备份进程限速。 生产库上用
-r限制读取速率,避免备份挤占在线业务的 I/O 带宽:
pg_basebackup -D /backup/full_latest -Fp -Xs -P -r 150M大库把备份放在备库上执行。 用
-h <standby>从备库取备份,避免主库承担文件读取开销;同时注意备库备份不生成备份历史文件、且主库需开full_page_writes。需要 WAL 保底时使用复制槽。 通过
-S slot -C让服务端为备份保留 WAL,避免-X fetch因wal_keep_size不足而失败;备份后及时pg_drop_replication_slot()清理。为备份的 manifest 指定强校验算法。 用
--manifest-checksums=SHA256代替默认的低成本校验,让pg_verifybackup更有说服力;不要随意关闭 manifest。用
-R直接产出备库目录。 新建备库时用-R一次性生成standby.signal与primary_conninfo,减少手工配置出错:
pg_basebackup -h 10.0.0.11 -U replicator -D /var/lib/postgresql/18/main \
-Fp -Xs -R -P -S standby1_slot -C表空间在备份时就重定位到干净的路径。 用 plain 格式配合
-T,让备份产物自带正确的tablespace_map,恢复时不必再手工修补路径。大库/高频备份考虑 PG17 原生增量。 全量 + 多个增量可以显著缩短每日备份窗口、降低带宽占用;但必须保证整条链(全量 + 全部中间增量)都完整保存,并在需要时用
pg_combinebackup合并。备份命名规范且不可覆盖。 目录名带日期与类型(
full_20260930_0200),不要复用固定目录名,避免「写了一半」的目录被误当成完整备份。把备份产物同步到独立存储。 备份落在与数据库不同的机器/机房,才具备灾难恢复意义;用
rsync/对象存储网关定期外送,并校验传输完整性。
下一节
参考链接
- PostgreSQL 官方文档:pg_basebackup
- PostgreSQL 官方文档:pg_combinebackup
- PostgreSQL 官方文档:pg_verifybackup
- PostgreSQL 官方文档:Continuous Archiving and Point-in-Time Recovery (PITR)
- PostgreSQL 官方文档:Backup Manifest Format
- PostgreSQL 官方文档:Streaming Replication Protocol
- PostgreSQL 官方文档:Monitoring Progress of Base Backups
- PostgreSQL 官方文档:Role Attributes(REPLICATION)
- PostgreSQL 官方文档:The pg_hba.conf File
- PostgreSQL 官方文档:Release 17(原生增量备份)