MongoDB PBM 备份恢复完整验证手册
MongoDB PBM 备份恢复完整验证手册看那么多文章自己操作一遍比啥都熟悉的快这份文档使用的是podman,也可以使用docker不影响验证目标3 节点副本集 → 全量备份 PITR 切片 → 无共享存储时恢复必然失败 → copy 备份到另一台机器 → 挂共享存储后异机 PITR 恢复成功环境Mac PodmanMongoDB 7 PBM 2.15.0 ARM642026-07-29 实测变量区下面所有步骤的命令都基于这些变量。改 IP、改路径、改镜像版本只需改这里全文生效。# 集群网络 NETWORKmongo-netSUBNET10.89.1.0/24# 3 个 MongoDB 节点固定 IPNODE1_IP10.89.1.11NODE2_IP10.89.1.12NODE3_IP10.89.1.13MONGO_IMAGEmongo:7REPLSETrs0# PBM 二进制存放目录从 Docker 镜像提取PBM_BIN_DIR$HOME/pbm-bin# PBM Docker 镜像ARM64Mac 兼容PBM_IMAGEpercona/percona-backup-mongodb:2.15.0-arm64# 备份目录 RESTORE_DIR$HOME/mongo-restore-test# 从容器 copy 出来的备份SHARED_DIR$HOME/mongo-shared-backup# 模拟生产 NFS 的共享目录第 1 阶段搭建 3 节点副本集1.1 创建网络podmannetwork create--subnet${SUBNET}${NETWORK}2/dev/null1.2 启动 3 个 MongoDB 实例podmanrun-d--namemongo1--network${NETWORK}--ip${NODE1_IP}\${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_allpodmanrun-d--namemongo2--network${NETWORK}--ip${NODE2_IP}\${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_allpodmanrun-d--namemongo3--network${NETWORK}--ip${NODE3_IP}\${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_all1.3 初始化副本集sleep5podmanexecmongo1 mongosh--eval rs.initiate({ _id: rs0, members: [ {_id:0, host:10.89.1.11:27017}, {_id:1, host:10.89.1.12:27017}, {_id:2, host:10.89.1.13:27017} ] })sleep10podmanexecmongo1 mongosh--evalrs.status().members.forEach(m print(m.name → m.stateStr))# 预期: 1 个 PRIMARY 2 个 SECONDARY第 2 阶段安装 PBM3 个节点2.1 从 Docker 镜像提取 ARM64 二进制mkdir-p${PBM_BIN_DIR}podmanrun-d--namepbm-temp${PBM_IMAGE}podmancppbm-temp:/usr/bin/pbm${PBM_BIN_DIR}/pbmpodmancppbm-temp:/usr/bin/pbm-agent${PBM_BIN_DIR}/pbm-agentpodmanrm-fpbm-templs-lh${PBM_BIN_DIR}/# 预期: pbm pbm-agent 两个二进制各 ~60MBMac 是 ARM 芯片不能用 x86_64 RPM/tarball——之前踩过坑rpm -ivh报/lib64/ld-linux-x86-64.so.2不存在。2.2 拷到 3 个节点 配 storage 启 Agentforiin123;dopodmancp${PBM_BIN_DIR}/pbm mongo${i}:/usr/bin/podmancp${PBM_BIN_DIR}/pbm-agent mongo${i}:/usr/bin/podmanexecmongo${i}chmodx /usr/bin/pbm /usr/bin/pbm-agentpodmanexecmongo${i}bash-ccat /etc/pbm-storage.conf EOF storage: type: filesystem filesystem: path: /tmp/backup EOFpodmanexec-dmongo${i}pbm-agent --mongodb-urimongodb://10.89.1.1${i}:27017/?replSetName${REPLSET}done2.3 初始化 PBM 配置只在一台跑podmanexecmongo1 pbm config--file/etc/pbm-storage.conf\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}2.4 确认三节点就绪podmanexecmongo1 pbm status --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 预期: 三行 pbm-agent OK第 3 阶段全量备份podmanexecmongo1 pbm backup --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 记下备份名后面恢复用podmanexecmongo1 pbm list --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 例如: 2026-07-29T03:03:36Z此时全量备份里只有 MongoDB 系统库没有 test 业务数据。后面 PITR 恢复时全量恢复完 test 库是空的要靠 PITR 切片追回增量数据——这样才能真正验证 PITR 是否有效。第 4 阶段开启 PITR 插入测试数据4.1 开启 PITR切片间隔 1 分钟podmanexecmongo1 pbm config--setpitr.enabledtrue\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}podmanexecmongo1 pbm config--setpitr.oplogSpanMin1\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 确认 PITR 已开启podmanexecmongo1 pbm status --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 预期: PITR Status [ON]4.2 等切片开始生成后插入数据# 等 PITR 切片开始生成sleep120podmanexecmongo1 pbm status --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 确认 PITR chunks 行已经出现了切片# 在主库上插数据——这些数据全量备份里没有只存在 PITR 切片里podmanexecmongo2 mongosh--eval use test; for (let i0; i10000; i) { db.pitrTest.insertOne({name:useri, ts:new Date()}) }; db.users.insertMany([{name:张三,age:30},{name:李四,age:25},{name:王五,age:28}]); print(pitrTest: db.pitrTest.countDocuments() 条); print(users: db.users.countDocuments() 条); 4.3 获取恢复时间点# 等 PITR 切片覆盖刚才的插入操作约 3-5 分钟sleep240podmanexecmongo1 pbm status --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}PITR chunks那行示例2026-07-29T03:03:41 - 2026-07-29T03:21:06记下 2026-07-29T03:21:06 这个结束时间后面 PITR 恢复就用它。不需要手动 date。第 5 阶段第一次恢复PITR 会失败——这是关键教训5.1 执行 PITR 恢复podmanexecmongo1 pbm restore--time2026-07-29T03:21:06-w\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}5.2 实际输出——恢复失败Starting restore ... to point-in-time 2026-07-29T03:21:06 ... Error: failed to ensure chunk {1785294220 2}.{1785294545 1} on the storage, file: pbmPitr/rs0/20260729/20260729030340-2.20260729030905-1.oplog.s2, error: no such file - Restore on replicaset rs0 in state: error5.3 失败原因三个容器各自独立的/tmp/backupPBM 不会跨节点传输切片文件。PITR 切片是 mongo3负责 PITR 的节点写到它自己的 /tmp/backup 里的。 恢复时 PBM 在 mongo1 上执行mongo1 去读自己本地的 /tmp/backup—— 根本找不到 mongo3 写的切片 → 报 no such file PBM 的设计假设是所有节点挂同一个共享存储生产 NFS。 没有共享存储就没有 PITR 恢复。这就是为什么后面需要重新搭建带共享目录的集群来验证异机恢复。第 6 阶段copy 备份到 Mac 本地# 确认备份文件在 mongo3 上PITR 切片那台podmanexecmongo3ls-lh/tmp/backup/# 预期: 全量备份目录 .pbm.json pbmPitr/# copy 出来mkdir-p${RESTORE_DIR}podmancpmongo3:/tmp/backup/.${RESTORE_DIR}/# 确认ls-lh${RESTORE_DIR}/ls-lh${RESTORE_DIR}/pbmPitr/rs0/20260729/2/dev/null# 预期: 全量备份 PITR 切片文件第 7 阶段异机恢复挂共享存储问题解决7.1 清理旧集群podmanstop mongo1 mongo2 mongo3podmanrmmongo1 mongo2 mongo37.2 创建共享备份目录并 copy 备份进去模拟生产 NFSmkdir-p${SHARED_DIR}cp-r${RESTORE_DIR}/*${SHARED_DIR}/ls-lh${SHARED_DIR}/这就是生产环境的等价操作——备份放在所有节点都能访问的 NFS 目录上恢复时任意节点都能读到同一个文件。7.3 启动新集群共享目录挂载到每个容器podmanrun-d--namemongo1--network${NETWORK}--ip${NODE1_IP}\-v${SHARED_DIR}:/tmp/backup${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_allpodmanrun-d--namemongo2--network${NETWORK}--ip${NODE2_IP}\-v${SHARED_DIR}:/tmp/backup${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_allpodmanrun-d--namemongo3--network${NETWORK}--ip${NODE3_IP}\-v${SHARED_DIR}:/tmp/backup${MONGO_IMAGE}mongod--replSet${REPLSET}--bind_ip_all7.4 初始化副本集sleep5podmanexecmongo1 mongosh--eval rs.initiate({ _id: rs0, members: [ {_id:0, host:10.89.1.11:27017}, {_id:1, host:10.89.1.12:27017}, {_id:2, host:10.89.1.13:27017} ] })sleep10podmanexecmongo1 mongosh--evalrs.status().members.forEach(m print(m.name → m.stateStr))7.5 安装 PBM每个节点 识别备份 执行恢复# 拷 PBM 启 Agentforiin123;dopodmancp${PBM_BIN_DIR}/pbm mongo${i}:/usr/bin/podmancp${PBM_BIN_DIR}/pbm-agent mongo${i}:/usr/bin/podmanexecmongo${i}chmodx /usr/bin/pbm /usr/bin/pbm-agentpodmanexecmongo${i}bash-ccat /etc/pbm-storage.conf EOF storage: type: filesystem filesystem: path: /tmp/backup EOFpodmanexec-dmongo${i}pbm-agent --mongodb-urimongodb://10.89.1.1${i}:27017/?replSetName${REPLSET}done# 初始化 PBM 配置podmanexecmongo1 pbm config--file/etc/pbm-storage.conf\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 强制重扫描备份仓库新集群必须做podmanexecmongo1 pbm config --force-resync\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# 确认能看到备份podmanexecmongo1 pbm list --mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}# PITR 恢复y 确认podmanexecmongo1 pbm restore--time2026-07-29T03:21:06-w\--mongodb-urimongodb://${NODE1_IP}:27017/?replSetName${REPLSET}这次不报no such file——三个容器挂的都是同一个 Mac 目录${SHARED_DIR}mongo3 写的切片 mongo1 能读到 ✅第 8 阶段验证数据podmanexecmongo3 mongosh--eval use test; print(pitrTest 条数: db.pitrTest.countDocuments()); print(users 条数: db.users.countDocuments()); # 预期: pitrTest10000, users3# 从库延迟归零podmanexecmongo3 mongosh--evalrs.printSecondaryReplicationInfo()# 预期: 0 secs behind the primary全量备份里没有 test 库——恢复全量后 test 是空的。PITR 切片回放后 test 库和 1 万条数据全回来——PITR 增量恢复有效 ✅踩坑记录坑现象原因解决PITR 切片找不到致命restore 报no such file: pbmPitr/rs0/20260729/xxx.oplog.s2没有共享存储——三个容器各自独立的/tmp/backup。PBM 不会跨节点传输切片。所有节点挂同一共享目录-v ~/mongo-shared-backup:/tmp/backup生产用 NFS架构不匹配rpm -ivh报/lib64/ld-linux-x86-64.so.2不存在Mac ARM 芯片不能用 x86_64 RPM/tarball用 Docker Hub 的 ARM64 镜像新集群看不到备份pbm list报no documents in result备份文件在共享目录里但 PBM 元数据没同步到 MongoDB admin 库pbm config --filepbm config --force-resyncPBM 2.15.0 不支持 MongoDB 4.2no such command: helloMongoDB 4.2 用isMaster5.0 用hello生产 4.2 降级到 PBM 2.0.5练完清理podmanstop mongo1 mongo2 mongo3 mongo4 pbm-temp2/dev/nullpodmanrmmongo1 mongo2 mongo3 mongo4 pbm-temp2/dev/nullpodmannetworkrm${NETWORK}2/dev/nullrm-rf${RESTORE_DIR}${SHARED_DIR}${PBM_BIN_DIR}验证日期2026-07-29环境Mac Podman MongoDB 7 PBM 2.15.0 ARM64

相关新闻

GHelper:如何用5MB软件替代500MB的华硕笔记本控制中心

GHelper:如何用5MB软件替代500MB的华硕笔记本控制中心

GHelper:如何用5MB软件替代500MB的华硕笔记本控制中心 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, Ex…

2026/9/26 3:31:36 阅读更多 →
三步搞定B站视频转文字稿:Bili2Text高效智能转写工具详解

三步搞定B站视频转文字稿:Bili2Text高效智能转写工具详解

三步搞定B站视频转文字稿:Bili2Text高效智能转写工具详解 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内容而头疼吗&#xf…

2026/9/28 12:46:51 阅读更多 →
产品介绍PPT模板哪家强?8个平台实测对比

产品介绍PPT模板哪家强?8个平台实测对比

一、百度文库智能PPT百度文库智能PPT是行业首创的AI生成工具,全球月访问量超3400万,PPT访问量全球第一。依托18亿专业文档及百度学术7亿篇文献,搭载GenFlow4.0,支持经典/专业双模式、一键美化、自由画布、思维导图、多文档合并等功…

2026/9/28 23:00:02 阅读更多 →

最新新闻

差模干扰与共模干扰详解:EMC整改实战指南

差模干扰与共模干扰详解:EMC整改实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 4:17:52 阅读更多 →
从零构建AI服务:HTTP协议级AI工程化实践

从零构建AI服务:HTTP协议级AI工程化实践

1. 这不是“搭积木”,而是重建AI系统的底层认知框架“AI Engineering from Scratch”——这个标题乍看像一句技术圈的时髦口号,实则藏着一个被严重低估的真相:当前90%标榜“AI工程化”的团队,其实只是在已有模型、已有平台、已有S…

2026/9/30 4:17:52 阅读更多 →
DevC++实战:5个C++小游戏设计与调试全解析

DevC++实战:5个C++小游戏设计与调试全解析

DevC 和 C 小游戏,听起来像是大学时代最熟悉的几样东西。我读书那会儿,机房电脑清一色蓝底白字的 DevC 4.9.9.2,一节课的任务就是把书上的控制台程序敲出来,看它在黑框里跑出几行文字。后来我慢慢发现,光跑数学题和输出…

2026/9/30 4:17:52 阅读更多 →
Python自学第二周练什么?四个小项目夯实基础语法

Python自学第二周练什么?四个小项目夯实基础语法

"第二周练习"这个标题,乍一看平平无奇,但在我看来,它几乎是自学者的一道分水岭。很多朋友在第一天、第一周兴致勃勃,看完变量、循环、函数,觉得自己已经摸到了编程的大门,结果到了第二周&#xf…

2026/9/30 4:17:52 阅读更多 →
AI工程从零实战:数据、模型、训练到部署全链路指南

AI工程从零实战:数据、模型、训练到部署全链路指南

1. 先从一条 GitHub 仓库标题说起"ai-engineering-from-scratch",看着像是一个学习清单或者课程资源库,实际上一旦你点进去顺着这个脉络走,会发现它代表的是一整条从零开始、不依赖框架黑盒、亲手把 AI 系统搭出来的进阶路线。和我…

2026/9/30 4:17:52 阅读更多 →
华为全栈智能数据中心方案解读:从TCO倒推架构与选型逻辑

华为全栈智能数据中心方案解读:从TCO倒推架构与选型逻辑

简介:这份PDF文档聚焦华为全栈智能数据中心解决方案,面向金融、电信、政府等行业中负责数据中心规划、建设与运维的技术人员,以及关注企业数字化转型的架构师与决策者,帮助理解如何借助全栈智能技术提升业务效率并降低总拥有成本。…

2026/9/30 4:16:52 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →