很多DBA做PostgreSQL备份第一反应就是写个 cron 脚本定时调 pg_dump。这套逻辑在几十 GB 的小库上确实够用但当你手里管着几百 GB 甚至上 TB 的生产库还要回答“我能恢复到什么时间点”“备份到底能不能用”这两个问题时pg_dump 方案就会露怯。Barman 就是专门解决这个问题的老牌开源工具它帮你把全量备份、WAL 归档、保留过期、恢复演练这些日常操作全部串成一套可管理的工作流这也是我这两年给 PostgreSQL 项目搭备份体系时最常用的方案。这篇内容面向的是正在从“手动备份”过渡到“自动化备份管理”的 DBA、运维工程师以及被一纸备份方案搞得头大的后端开发者。我会从环境规划、配置项含义、备份执行、恢复演练到问题排查全程按生产环境的操作习惯来讲。每个参数为什么这样配、踩过哪些坑我会直接写在对应的位置你照着搭基本不会走弯路。1. 选择 Barman 之前先想清楚三个问题工具选型这事儿最怕一上来就照着文档堆配置。你得先明确自己的备份目标到底属于哪一层Barman 擅长解决什么不擅长解决什么心里有数再动手。1.1 逻辑备份和物理备份差别在哪儿PostgreSQL 的备份方式粗分两类。pg_dump 属于逻辑备份它把数据用 SQL 语句的形式导出来恢复时需要把语句重新执行一遍本质上是在“抄写笔记”。物理备份则是直接复制数据库的底层文件相当于把整本笔记本拿去复印店复印一份。区别在于逻辑备份只能恢复到命令执行那一刻的状态备份之后产生的新数据全部丢失。物理备份配合 WAL预写日志可以把数据库恢复到任意一个历史时间点这就是常说的时间点恢复PITR。Barman 做的是物理备份。它在底层调用 pg_basebackup 或 rsync在备份期间协调 PostgreSQL 的 WAL 状态让备份目录和 WAL 形成一个完整一致的还原点。恢复的时候Barman 再把对应的 WAL 重放到指定时间戳做到“随便挑一分钟恢复”。我见过不少团队用 pg_dump 做“全量备份”恢复时才发现备份文件是好的但业务数据已经丢了一个小时因为全量备份和业务高峰之间有窗口期间的数据谁也没办法补回来。物理备份 WAL 的方案才真正把恢复点目标RPO降到了分钟级甚至秒级。1.2 Barman 和常见替代方案的真实差距拿几种我实际接触过的方案做个横向对比这样你判断起来会更快。方案是否支持 PITR是否自动管理 WAL是否集中管理恢复操作复杂度适用阶段自写脚本 pg_dump否否否简单但恢复点陈旧几十 GB 以内小库自写脚本 pg_basebackup 手工归档 WAL勉强靠自己写逻辑否恢复要手工拼接容易错有经验但没工具链的团队pgBackRest支持支持支持配置偏复杂学习曲线陡对备份速度和并行压缩有强需求Barman支持支持支持命令简洁上手快大多数 PostgreSQL 生产环境Barman 的强项是“集中管理”。你可以在单独的备份服务器上管理多个 PostgreSQL 实例每个实例一个配置文件备份状态、WAL 接收、过期清理都由 Barman 统一调度。相比之下自写脚本的方式最大的问题不是写不出来而是每个人写的都不一样接手的人完全看不懂上一任留下的脚本逻辑。pgBackRest 在并行、压缩、增量备份上也有自己的优势但如果是传统运维团队Barman 的命令风格更贴近 PostgreSQL 社区习惯文档齐全遇到问题搜一下基本都有答案。我是建议中小团队优先考虑 Barman它把很多脏活累活都封装好了。1.3 什么时候不适合上 Barman不是所有场景都适合 Barman遇到下面这些情况我会明确劝退只有一个几 GB 的开发库丢一天数据也无所谓。那直接 pg_dump 就行别为它单独养一台服务器。你的需求是做表级恢复而不是整库恢复。Barman 恢复的最小粒度是完整实例如果你想误删了一张表后快速找回那还是要靠 pg_dump 按表备份兜底。跨机房网络质量差到连 SSH 都不稳定。Barman 的备份和 WAL 传输依赖可靠的网络链路网络丢包严重时备份会频繁失败反而增加运维压力。搞清楚这些边界你才知道 Barman 应该摆在自己的备份体系里的哪个位置。通常我的做法是Barman 负责整库物理备份 时间点恢复pg_dump 作为表级导出工具在需要时手动执行两者并不冲突。2. 环境准备与安装两台机器的基础设施Barman 天生是“主备分离”的架构备份服务器独立于数据库服务器。这样设计的好处是数据库服务器挂了备份还在另一台机器上不会“一锅端”。我见过有人把 Barman 装在数据库服务器本机上真出事的时候两台服务一起宕备份全废这个坑千万不要踩。2.1 拓扑规划和目录设计推荐的最小拓扑是一台 PostgreSQL 生产服务器加一台 Barman 备份服务器两台机器放在同一个机房或同一个可用区网络延迟要低。备份服务器不需要很高的 CPU但磁盘容量要按备份策略提前算清楚。我一般这样规划目录Barman 程序安装目录/usr/bin或虚拟环境目录Barman 主配置/etc/barman.conf实例配置目录/etc/barman.d/备份数据根目录/var/lib/barman/实例名/Barman 日志/var/log/barman/barman.log其中/var/lib/barman一定要单独挂一块数据盘不要和系统盘共用。原因很简单备份文件增长快如果系统盘被备份占满操作系统本身就会出问题到时候连排查的空间都没有。磁盘容量估算我给一个实际例子。假设库大小 500GB数据库每天产生 20GB 的 WAL我的策略是保留 2 个全量备份WAL 保留 7 天。那么需要的空间大约是全备 500GB × 2 份 1000GBWAL 20GB × 7 天 140GB总需求约 1140GB再预留 20% 余量实际要准备大概 1400GB 的备份盘。如果启用了压缩实际占用会小一些但余量建议不要省Barman 在做恢复演练时需要额外空间存放恢复出来的数据目录。2.2 安装 Barman 的三种方式Barman 是 Python 写的安装方式灵活我用过的有三种。第一种用发行版自带的包管理器。在 Debian/Ubuntu 上执行apt install barman在 CentOS/RHEL 上执行yum install barman。这种方式最省事但要注意发行版自带的版本可能偏老。Barman 的版本直接影响它支持的 PostgreSQL 版本如果生产库是 PostgreSQL 15 或更高建议用较新的 Barman 3.x。第二种从 PostgreSQL 官方软件源安装。这个源会持续更新 Barman版本比较新兼容性也好。添加官方源后再执行包管理器安装即可。第三种用 pip 装在独立虚拟环境里。适合那些不想动系统 Python 环境的机器。创建虚拟环境后执行pip install barman然后手动创建 barman 用户和目录结构。安装完成第一件事是检查版本barman --version。我建议至少用 3.5 以上版本PG 13 之后的版本特性支持得更完整比如流式 WAL 压缩、基于时间线的恢复等能力都更稳。2.3 SSH 免密配置第一步最容易错Barman 和 PostgreSQL 之间通过 SSH 执行远程命令比如拉取备份、执行归档命令。所以必须配置从 Barman 服务器的barman用户到 PostgreSQL 服务器上的postgres用户的免密登录。配置步骤# 在 Barman 服务器上以 barman 用户执行 su - barman ssh-keygen -t ed25519 -C barman-backup cat ~/.ssh/id_ed25519.pub把生成的公钥追加到 PostgreSQL 服务器的postgres用户的~/.ssh/authorized_keys文件里权限要严格设置为chmod 700 ~/.ssh chmod 600 ~/.ssh/authorized_keys然后回到 Barman 服务器验证连通性su - barman ssh postgrespg服务器IP echo ok如果输出不是 ok优先检查 authorized_keys 权限和 SELinux 配置。这个环节我踩过太多次坑最常见的就是公钥文件权限是 644SSH 直接拒绝使用错误信息还没写清楚很容易让人误判成网络问题。另外建议在 Barman 配置文件里给 SSH 加上连接复用参数减少反复握手带来的延迟ssh_options -o ConnectTimeout10 -o ControlMasterauto -o ControlPath/tmp/barman-ssh-%r-%h-%p -o ControlPersist300这样连续执行备份、归档、检查命令时SSH 连接可以复用备份窗口能缩短不少。3. PostgreSQL 侧配置让数据库先把 WAL 交出来Barman 的核心优势在于 WAL 的自动归档和保留所以 PostgreSQL 侧的配置目标很明确让数据库能够安全地生成 WAL 并把它们传出去同时允许 Barman 通过流复制协议读取数据。3.1 关键参数设置与含义在postgresql.conf里以下几项必须重点确认wal_level replica archive_mode on archive_command ssh barman备份服务器IP barman receive-wal --get-wal 实例名 %p archive_timeout 300 max_wal_senders 5 wal_keep_size 512MB逐个说一下为什么这么配。wal_level至少要replica只有这个级别才会在 WAL 里写够恢复所需的信息。逻辑复制场景下还要用logical但纯备份用replica就够了。archive_command是一条外部命令。当 PostgreSQL 决定归档一个 WAL 文件时会把%pWAL 文件的完整路径传给这条命令。这里的写法是通过 SSH 把 WAL 文件交给 Barman 服务器上的receive-wal进程由 Barman 统一保存。如果你更习惯用 rsync也可以写成 rsync 推送但 SSH 方式更干净不依赖额外组件。archive_timeout设成 300 秒意思是即使业务完全空闲最多 5 分钟也会切一次 WAL。这么做的好处是 Barman 接收 WAL 的延迟不会太久。代价是会多产生少量空 WAL 文件但每个文件默认 16MB一天多几十个也不是大问题。这个参数很多人忽略结果就是备份机看到的 WAL 一直不更新恢复时才发现最新数据根本没归档。max_wal_senders是允许的 WAL 发送进程数。Barman 的流式接收至少要占 1 个 slot如果你还有从库要在这个数字上多留几个。3.2 pg_hba.conf 授权设计Barman 有两种方式获取数据一种是基于流复制的pg_basebackup另一种是基于文件复制的rsync。无论哪种都需要数据库允许远端连接。在pg_hba.conf里加两条规则host replication postgres 备份服务器IP/32 md5 host all postgres 备份服务器IP/32 md5第一条放行复制协议连接这是pg_basebackup和流式 WAL 接收必需的第二条放行普通的数据库连接用于 Barman 查询数据库状态、执行pg_start_backup()这类函数。我习惯在postgresql.conf里把监听地址也显式写出来listen_addresses 0.0.0.0默认只监听 localhost如果你发现 Barman 一直连不上第一反应检查这个参数然后是 pg_hba.conf 的规则顺序。pg_hba.conf 是自上而下匹配的如果前面有拒绝规则后面的允许规则不会生效。改完两个文件后记得重启或pg_ctl reload。archive_command 不需要重启但 wal_level、listen_addresses 这些需要。3.3 验证 WAL 归档链路配置完之后先别急着让 Barman 做全量备份验证一下 WAL 能不能正确流过去。手动切换一次 WALSELECT pg_switch_wal();然后在 Barman 服务器上查看su - barman barman list-files --wal 实例名 | tail -10如果能看到刚生成的 WAL 文件出现在列表里说明归档链路已经通了。如果迟迟看不到去 PostgreSQL 服务器上看 PostgreSQL 日志里面会记录 archive_command 的具体报错。这一步是后面所有操作的基础宁可在这里多花十分钟也不要在恢复演练时才追查。4. Barman 侧配置把备份策略落实到配置文件Barman 的配置分两层全局配置和实例配置。全局配置写公共项实例配置写每个数据库特有的连接信息。我强烈建议每个 PostgreSQL 实例一个独立配置文件放在/etc/barman.d/下文件名就是实例名。4.1 一份可以直接抄作业的全局配置/etc/barman.conf长这样[barman] barman_home /var/lib/barman barman_user barman log_file /var/log/barman/barman.log compression zstd reuse_backup link retention_policy retention RECOVERY WINDOW OF 7 DAYS ; 让 Barman 定期自动执行调度任务 ; 配合 cron 里的 barman cron 使用 parallel_jobs 4compression zstd是我目前最推荐的压缩算法。gzip 压缩率高但非常吃 CPU备份 500GB 的库能把 CPU 跑满很长时间。zstd 在压缩速度和压缩率之间取得了很好的平衡实测比 gzip 快一倍以上压缩率差距只有几个百分点。如果你用的 Barman 版本较老不认识 zstd退而求其次选 lz4速度也快但压缩率略低。reuse_backup link是针对 rsync 备份方法的优化选项它会在新备份和旧备份之间复用相同内容的文件用硬链接代替复制能显著节省磁盘和备份时间。但要注意如果你用的是backup_method postgres这个参数会被忽略这是版本差异下面会细说。retention_policy retention RECOVERY WINDOW OF 7 DAYS表示要保证能恢复到过去 7 天内的任意时间点。Barman 会自动据此判断哪些全量备份可以删、哪些 WAL 可以清不用你手动干预。4.2 备份方法选型rsync 还是 postgres这是配置时一定会遇到的选择题。Barman 支持两种全量备份方法backup_method rsyncBarman 在数据库服务器上通过 SSH 执行 rsync直接把数据目录拉过来。配合reuse_backup link可以做增量硬链接备份对磁盘空间敏感的环境非常友好。backup_method postgresBarman 在数据库服务器上调用pg_basebackup这是 PostgreSQL 官方的物理备份工具标准、稳定、兼容性最好。我的建议是如果是 PostgreSQL 13 以上版本默认选postgres。原因有两条。第一pg_basebackup 是官方持续维护的工具对各种新特性的兼容性有保障第二rsync 方式需要 Barman 对数据目录进行文件级遍历数据库文件特别多时元数据扫描本身就慢备份窗口会被拉长。postgres 方法整体更干净。如果你确实依赖硬链接增量特性来省空间那可以用 rsync 方法但要在配置里打开reuse_backup link。这个模式下备份速度和空间占用都有优势只是牺牲一点兼容性生产环境只要测试充分也能接受。4.3 实例配置连接信息和流式 WAL每个实例的配置文件/etc/barman.d/pg-server.conf[pg-server] description 生产主库 ssh_command ssh postgrespg服务器IP conninfo hostpg服务器IP userpostgres dbnamepostgres backup_method postgres streaming_archiver on streaming_conninfo hostpg服务器IP userpostgres dbnamepostgres slot_name barman_slotssh_command是 Barman 远程执行命令的方式对应第二节里的免密配置。conninfo是 Barman 连接 PostgreSQL 数据库的连接串。streaming_archiver on开启流式 WAL 接收它会在 Barman 服务器上启动一个类似pg_receivewal的进程主动接收 WAL而不是完全依赖 PostgreSQL 的 archive_command 推送。slot_name barman_slot让 Barman 在 PostgreSQL 上注册一个复制槽。复制槽的作用是告诉 PostgreSQL“这个备份端还在消费 WAL别把我需要的 WAL 删掉。”这是防止 WAL 被提前清理的关键机制否则业务高峰期 WAL 产生太快PostgreSQL 可能还没来得及归档就把旧 WAL 覆盖了备份链条就断了。启用流式接收后首次要给 Barman 创建这个复制槽su - barman barman receive-wal --create-slot pg-server创建完成后Barman 的 cron 任务会在后台拉起 receive-wal 进程持续消费 WAL。这里要提一句archive_command作为第二通道也不要关掉它是一种“双保险”。即使流式进程意外挂了归档命令还能把 WAL 推过来避免缝隙。4.4 barman check 全项体检配置写完后第一件事不是急着备份而是先体检barman check pg-server输出会逐项列出 PostgreSQL 版本、系统标识、目录权限、replication slot、归档策略等信息。每一项出现WARNING都值得多看一眼。常见的 WARNING 集中在archiver警告说明 archive_command 没配好或者是 pg_hba.conf 没放行。replication slot警告说明复制槽没创建流式接收不会工作。directory警告说明备份目录权限不对barman 用户无法写入。我的原则是barman check不出现任何WARNING和ERROR之前坚决不做第一次全量备份。否则你会在一个不健康的基础上叠加更多问题排查起来会很痛苦。5. 第一次完整备份与 WAL 流式接入到这一步基础设施已经齐了。第一次备份我建议以交互式命令执行不要急着写进 cron因为你需要在终端里盯着备份过程感受它的耗时、输出和潜在问题。5.1 执行首次全量备份su - barman barman backup pg-server命令执行期间会有进度输出显示备份开始时间、结束时间、备份大小、耗时、WAL 数量等。整个过程的长度取决于数据库大小、磁盘 IO 和网络带宽。第一次跑出来后记下耗时后面做备份窗口规划和容量估算都用得上。备份完成后查看状态barman list-backups pg-server barman show-backup pg-server latestshow-backup的输出里重点看Status字段必须是DONE。如果看到FAILED直接去看 Barman 日志/var/log/barman/barman.log里面会记录失败的具体原因。首次备份最常见的失败原因是权限问题比如 pg_hba.conf 没放行、postgres 用户无法读数据目录等。顺便说一句Barman 的全量备份默认是“透明地”结合 PostgreSQL 的检查点机制备份开始时会请求一个检查点确保文件系统快照和 WAL 位置一致。所以备份期间数据库的性能会有轻微波动这在正常范围不用太紧张。5.2 解读备份目录结构备份完成后/var/lib/barman/pg-server/下大致是这个结构base/存放每个全量备份的子目录命名是时间戳比如20250115T100000。wal/存放从 PostgreSQL 接收到的 WAL 文件。incoming/归档命令推送 WAL 时临时落地的目录。recovery/某些恢复操作产生的中间文件。理解这个结构对排查问题很有帮助。比如你发现 WAL 一直不过来可以先看incoming/有没有文件堆积。如果文件堆积而不消失说明 Barman 的接收进程或后续的处理逻辑有问题常见原因是文件所有权不对或收到的文件校验失败。5.3 流式 WAL 接收的验证与日常观察配置了streaming_archiver之后Barman 的 cron 任务会自动启动接收进程。验证它是否正常工作barman status pg-server输出里应该有一行显示 receive-wal 进程的状态。如果显示未运行可以用手工方式启动接收barman receive-wal pg-server这个命令会以前台方式启动接收进程方便观察日志。确认正常后按 CtrlC 退出再交给 cron 管理。日常观察 WAL 是否持续流入最简单的办法是看 wal 目录里的文件变化watch -n 5 ls -l /var/lib/barman/pg-server/wal/ | tail -5文件时间戳应该持续更新。如果长时间没有新文件先去数据库服务器上执行SELECT pg_switch_wal();手动切换一次再观察 Barman 侧有没有反应。没有反应的话按第八节的排查思路走。5.4 备份完整性和一致性校验Barman 每次备份完成后都会自动执行一致性检查确保备份数据目录和 WAL 的衔接是完整的。你想主动验证也可以barman check-backup pg-server它会模拟一次恢复前的校验报告备份是否一致、是否缺少 WAL 文件。我建议把check-backup也纳入定期任务比如每天的 cron 里跑一次早发现问题早处理别等到恢复时才傻眼。6. 恢复实战能把备份救回来才是真本事备份做了一百次恢复没练过一次等于没做备份。这是我一直跟团队强调的话。恢复操作本身不难但里面有几个细节都是你在真实故障现场才会体会到的重要程度。6.1 基础恢复流程 barman recover把最新备份恢复到本地目录barman recover pg-server latest /data/restore_dir这条命令会把全量备份往目标目录还原同时把需要的 WAL 也拷贝过去最终得到一个可以直接启动的 PostgreSQL 数据目录。恢复完成后检查目录权限chown -R postgres:postgres /data/restore_dir然后启动 PostgreSQL设好data_directory指向恢复目录即可。这里要说一个最常见的误解barman recover恢复出来的是数据目录不是整个操作系统PostgreSQL 软件本身还需要在目标机器上预先安装好版本要和生产环境一致。很多第一次用的人会以为恢复完就万事大吉结果发现起不来日志里报数据目录版本不匹配那就是软件版本的问题。6.2 时间点恢复 PITR精确到分钟的操作Barman 真正的杀手锏是时间点恢复。假设业务侧报告“今天下午 14:30 有人误删了数据”你想恢复到 14:25 的状态barman recover --target-time 2025-01-15 14:25:0008 pg-server latest /data/restore_dir在recover命令后带上--target-timeBarman 会自动重放 WAL 到指定时间点然后停下生成一个可见恢复标记。除了时间还可以按事务 ID 或 LSN 定位恢复点。遇到“误操作发生在某一笔事务之后”的场景--target-xid更精确barman recover --target-xid 208546 pg-server latest /data/restore_dir这两个参数在日常运维中各有适用场景。时间点恢复简单直观但事务量特别密集时可能没法精确到“某条语句之前”。事务 ID 恢复更精准但需要你先知道目标事务 ID这个数字通常要在问题发生后从日志或别的途径获取。恢复完成后我会建议先不要直接切业务。在 PostgreSQL 日志里确认recovery stopping before/at的行看时间点和预想是否一致。然后把应用以只读模式连上去让业务侧验证数据确认无误后再说切换的事。6.3 恢复到异机注意路径和配置差异真实故障中生产服务器可能整个挂掉恢复目标是一台新机器。barman recover可以通过--remote-ssh-command直接把数据恢复到远程机器barman recover --remote-ssh-command ssh postgres新服务器IP pg-server latest /var/lib/postgresql/data这里要留意几点新机器上 PostgreSQL 版本和编译选项要尽量一致否则数据目录虽然能拷贝过去但启动时会报软件版本问题。恢复目录路径最好和生产保持一致。如果路径变了检查postgresql.conf里是否有绝对路径配置需要修正比如unix_socket_directories、log_directory等。恢复出来的数据目录所有权要改成新机器上的 postgres 用户。异机恢复一定要提前演练一次。我见过最典型的问题是生产环境数据目录挂在一个自定义路径/data/pgdata恢复演练时目标机器默认路径是/var/lib/postgresql/data结果恢复完启动失败排查半天发现是配置里的绝对路径没改。6.4 恢复后必须做的四项检查恢复完成后我有一套固定的检查清单按顺序执行第一确认数据库能正常启动pg_controldata查看状态或用pg_ctl start观察日志。第二确认恢复终止点执行SELECT pg_is_in_recovery();正常恢复完成后返回f表示已经脱离恢复模式可以接受读写。第三抽查关键业务表的数据量和最新记录时间和故障前的预期比对。第四检查 PostgreSQL 日志中是否有FATAL级别的错误。这套检查 10 分钟内能跑完但能省掉后续无数麻烦。7. 自动化与监控没有定时任务就没有备份Barman 本身不会自动做任何事情。它提供了完整的命令集但你必须用 cron 或 systemd timer 把它调度起来。这里只要配置不对前面的所有工作都会变成摆设。7.1 cron 调度与 barman cron 机制Barman 官方推荐的调度方式是把barman cron设为每分钟执行一次* * * * * barman cron --barman-cron-check /dev/null 21barman cron会负责执行这几类工作启动或维持每个实例的流式 WAL 接收进程执行到达调度时间的全量备份执行备份保留策略清理过期全量备份和 WAL执行备份完整性校验把这一切交给barman cron统一管理而不是在 crontab 里写barman backup原因是它可以避免任务重叠和目录锁冲突。如果你自己再额外加一个凌晨 1 点的barman backup任务可能和 Barman 内部的调度打架备份目录会锁死导致备份失败。这是新手容易踩的坑明明配置了 cron又自己加了一行备份命令结果两边撞车。关于全量备份的频率我用的是每天全备一次加上持续流式 WAL。备份时间放在凌晨业务低谷用 Barman 的barman cron内置时间表就够了。如果你业务高峰期数据量巨大也可以把全备频率降到两天一次但要确保 WAL 持续流入和保留策略符合你的 RPO 要求。7.2 监控集成与自建脚本Barman 自带barman check命令输出也是稳定的文本格式很适合被监控系统采集。我习惯在备份服务器上放一个脚本内容很简单#!/bin/bash barman check pg-server /tmp/barman_check.log 21 if [ $? -ne 0 ]; then # 调用告警接口 curl -X POST 你的告警平台地址 -d codebarman_check_failed echo $(date): unhealthy /var/log/barman_check_history.log fi监控系统只要能执行命令基本都可以这样接入。如果你用 Prometheus也可以把 Barman 的指标通过文本采集器暴露出去但没有现成 exporter 的情况下脚本 curl 是成本最低的方式。监控指标我建议关注这几项最后一次全量备份的状态和时间最新 WAL 文件的时间戳超过 10 分钟没更新要警惕备份目录磁盘剩余空间复制槽的active状态确认没有断掉7.3 容量预估与告警阈值容量监控不能等磁盘满了才告警。我一般按这个公式设置阈值安全线 全备大小 × 保留份数 日均 WAL 量 × 保留天数 恢复演练需要的临时空间然后加 20% 余量。告警阈值设在这里一旦磁盘占用超过安全线 80%就触发告警。别只看剩余多少 GB因为你不知道 Barman 会在什么时候开始执行下一次全备。如果全备跑到一半磁盘满了这个备份基本报废而且清理起来还要花不少时间。我还建议定期清理恢复演练产生的临时目录。有些人演练完就把恢复目录放在备份盘上忘了删一次演练可能吃掉几百 GB再加上常规备份增长磁盘很容易告警。演练结束后立刻清理这是我从实践中总结出来的小小教训。8. 常见问题与排查实录Barman 用久了该遇到的问题我基本都碰过一轮。挑几个出现频率高的按“现象 - 原因 - 排查步骤”的方式写下来当作速查清单用。8.1 WAL 堆积备份目录疯狂膨胀现象/var/lib/barman/实例名/wal/目录持续增长Barman 没有按预期清理过期 WAL。排查思路按顺序走第一执行barman check pg-server看是否有复制槽相关警告。流式接收依赖复制槽如果槽被删了Barman 无法确定哪些 WAL 还被下游消费就不会清理。第二检查barman cron是否真的在跑。很多人配了 crontab但 cron 服务本身没启动Barman 的清理逻辑自然永远不会执行。第三查保留策略有没有生效。执行barman show-schedule pg-server看 Barman 是否对过期备份有输出。如果显示没有调度strategy 里retention_policy需要确认。WAL 堆积最危险的是拖垮备份盘进而让后续全备失败。如果发现wal目录异常大可以手动强制切一次清理barman keep pg-server backup_id但这个命令会强制保留指定备份并清理更早的所以执行前要确认备份 ID 是不是你想要留的不然误删是回不来的。8.2 SSH 连接失败与权限问题的定位技巧现象barman check报错说无法连接 PostgreSQL 服务器SSH 通道建立失败。排查方法在 Barman 服务器上手动执行su - barman ssh -vvv postgrespg服务器IP echo ok-vvv会打印详细握手过程。常见原因有几类authorized_keys 权限不对改为 600。目标服务器 SELinux 拦截了 SSH 对 postgres 用户目录的访问。PostgreSQL 服务器上的 postgres 用户的 shell 不是/bin/bash。Barman 的 rsync 方法依赖远程 shell 执行命令如果 shell 被设置成nologinSSH 能连上但无法执行命令。Barman 配置里的 ssh 用户名写错比如写成了 barman而目标机器根本没有这个用户。这类问题 90% 都可以通过手动 ssh 定位到不要在 Barman 的命令层面反复试浪费时间。8.3 恢复时报“缺少 WAL 文件”现象执行barman recover时报错提示某个 WAL 段在 Barman 侧找不到。这种情况通常不是 Barman 的锅而是生产侧 WAL 归档链路曾经断过。最常见的原因是在某个时间段里流式接收进程挂了archive_command 也失败那段时间的 WAL 已经在生产库上被清理了所以 Barman 侧缺失这部分日志。排查办法执行barman show-backup pg-server latest看WAL segments字段对比实际存在的 WAL 文件编号。确认缺失的时间范围后回到生产库看看是否还有对应的 WAL 文件如果有手动把它导入 Barmanbarman put-wal pg-server wal_folder然后重新执行恢复。如果没有那只能接受“已经丢失该段时间数据”的现实恢复到一个较早的时间点。这也是为什么我一直强调流式接收进程要监控WAL 断档是 PITR 恢复中最容易让人措手不及的问题。8.4 全量备份期间具体卡顿或互斥现象全量备份执行到一半长时间没有进展或者和另一个备份任务冲突。Barman 在同一实例上不允许同时执行两个备份。如果你手动执行了一个barman backup然后 cron 又发起了下一个后者会被锁等待。排查时看 Barman 日志会明确看到类似“another backup is already running for server”的字样。如果确认没有其他任务在跑但备份卡住常见原因是 PostgreSQL 侧执行pg_start_backup()时等待长事务结束。这时去 PostgreSQL 上查活跃事务SELECT * FROM pg_stat_activity WHERE xact_start IS NOT NULL ORDER BY xact_start ASC;如果有事务开了很多小时没提交备份初始化就会卡在起点。这种场景下我会选择错开备份窗口优先处理长事务问题让备份能够顺利走完。8.5 备份盘被撑爆的处理顺序现象备份盘满了全量备份失败Barman 管理目录状态混乱。处理顺序很重要别慌。第一步找到可以安全清理的备份。执行barman list-backups pg-server找出状态为FAILED的备份它们没有价值可以删掉barman delete pg-server 备份ID如果已经成功备份不少且保留策略允许可以手动删掉最老的一个正常备份barman delete pg-server 最老备份ID注意不要直接rm -rf备份目录因为 Barman 的元数据会不一致之后恢复操作可能根本认不出目录里有什么。一定要通过barman delete清理。临时清出空间后立刻检查 WAL 目录的大小如果需要可以手工清理早期 WAL但同样要谨慎前面说了要用正确命令。最后再执行一次全量备份把备份链重新立起来。我个人的习惯是备份盘容量监控的阈值设得比一般监控更保守宁可多告警几次也不要等到“满盘再救火”。满盘救火的操作非常痛苦而且你业务正在跑的时候“救火”这个动作本身就是在给系统加风险。最后再分享一个小技巧我会在每个周五下午从备份中随机挑一个实例做一次恢复演练恢复到一台开发机上跑一遍关键表的行数校验脚本然后自动生成报告。Barman 的barman recover命令适合做成这条流水线的基础如果演练过程中出现任何报错说明备份链有问题周末前还有时间修。用这个办法我在过去两年里成功拦截过三次备份失效问题。备份恢复这件事测试过、靠谱心里才真正有底。
阅读完成 · 觉得有帮助?