项目地大量使用社区版MongoDB数据库,用来存放重要工单数据,随着业务量增长,数据规模越来越大,每天的备份任务执行时间越来越长。目前某项目地数据规模统计如下:
[mongod@mongodb02 mongodb]$ du -sh *
16K conf
13G config
45G mongos
1.4T shard1
0 shard2
0 shard3
[mongos] flowtest> show dbs
admin 204.00 KiB
config 37.21 MiB
flowtest 1.37 TiB
[mongos] flowtest> db.stats()
{
collections: 13,
objects: 268389871,
dataSize: 6290739041372,
storageSize: 1483442253824
}
可见实际的数据量达到了6T以上,数据库大小1.4T,实际磁盘空间占用也是1.4T。
目前的原生备份方法是 mongodump 压缩方式,因为磁盘空间不足,只能采用压缩方式备份,否则3天的备份占用就达到20T。原生备份方法效率较低,当前6T的数据备份需要耗时23个小时,几乎要达到每天备份的极限了。
由于社区版本身的限制,本次采用 percona 的 备份恢复工具 pbm (Percona Backup for MongoDB),大大缩短了备份时间,以下是具体的实践指南。
备注:网上暂无比较严谨、可用的中文版pbm备份恢复实践指南,本次认真研读官方文档,按照我们的实际部署情况执行操作,具有较强的指导意义。尤其是如何跳过安全验证这一步,实乃神来之笔。另外部分执行步骤按照官方文档无法执行,只能按照自己的理解来操作,最终达到成功高效完成备份的目的。
首先,最重要的是所有的参考一定是官方文档:
https://docs.percona.com/percona-backup-mongodb/
Percona Backup for MongoDB (PBM) is an open source and distributed solution for consistent backups and restores of MongoDB sharded clusters and replica sets to a specific point in time.
本次实践所有的操作来源均来自官网指南。
一、在每个 mongod 节点安装 pbm
下载pbm的二进制文件、解压缩、配置环境变量
wget https://downloads.percona.com/downloads/percona-backup-mongodb/percona-backup-mongodb-2.12.0/binary/tarball/percona-backup-mongodb-2.12.0-x86_64.tar.gz
cd /u01
tar -xf /home/nrms/pbm/percona-backup-mongodb-2.12.0-x86_64.tar.gz
export PATH=/u01/percona-backup-mongodb-2.12.0:$PATH
这个环境变量需要配置到mongod用户的.bash_profile文件。
我们的生产环境是分片集群3个节点,都配置了config服务、shard服务,目前均配置了一个分片集shard1,这两类服务都是mongod服务,所以在3个节点部署pbm软件即可。
二、Configure authentication in MongoDB
配置鉴权认证
1、Create a corresponding pbm user in the admin database
在admin库创建pbm用户。
Do this step on a primary node of each replica set. In a sharded cluster, this means on every shard replica set and the config server replica set.
按照以上官网要求,需要在每一个副本集的主节点执行。
To list all the host+port lists for the shard replica sets in a cluster, run the following command:
db.getSiblingDB("config").shards.find({}, {"host": true, "_id": false})
The replica set name at the front of these “host” strings will have to be placed as a “/?replicaSet=xxxx” argument in the parameters part of the connection URI (see below).
这是说明如何列出分片副本集。不过关于replicaSet=xxxx的要求,实践证明是错误的,不需要。
创建角色和用户的操作命令是:
db.getSiblingDB("admin").createRole({ "role": "pbmAnyAction",
"privileges": [
{ "resource": { "anyResource": true },
"actions": [ "anyAction" ]
}
],
"roles": []
});
db.getSiblingDB("admin").createUser({user: "pbmuser",
"pwd": "mypassword",
"roles" : [
{ "db" : "admin", "role" : "readWrite", "collection": "" },
{ "db" : "admin", "role" : "backup" },
{ "db" : "admin", "role" : "clusterMonitor" },
{ "db" : "admin", "role" : "restore" },
{ "db" : "admin", "role" : "pbmAnyAction" }
]
});
以上命令在后面步骤执行,此处只是列出指令。
1)、首先在config服务器执行创建
我们的config服务是21000端口,执行如下进入config主节点:
mongosh mongodb://'admin':'mypassword'@99.99.99.99:21000/admin?authSource=admin
然后执行以上指令创建pbm角色、用户。
2)、然后在shard服务器执行创建
我们的shard服务是27001端口,然而问题来了,我的mongodb分片集群配置了安全认证,无法直接访问mongod,只能通过mongos访问分片数据。但是pbm-agent只能直连分片副本集,无法通过mongos配置,这个问题怎么解决?
我们采用先关闭安全认证创建pbm角色用户,然后再打开安全认证的方式,成功绕过了这一个无法进行的难关,也是本次实践的神来之笔。解决办法:
1、停掉集群,关闭安全认证,启动集群,在shard上建立pbm角色及用户;
2、停掉集群,打开安全认证,启动集群,这样就可以在后面成功启动pbm-agent。
关闭、打开安全认证的方法是修改shard的配置文件如下两行:
security:
keyFile: /u01/mongodb/conf/mongo.keyfile
没这两行启动服务就是关闭安全认证,加上就是打开,不再赘述。
关闭安全认证后,在shard的主节点执行如下进入mogonsh:
mongosh --port 27001
然后执行以上指令创建pbm角色、用户。
2、Set the MongoDB connection URI for pbm-agent
Execute this step on each node where pbm-agent is installed.
对于我们的环境,在3个节点均如下配置pbm-agent指令:暂不执行
pbm-agent --mongodb-uri "mongodb://pbmuser:mypassword@localhost:27001/?authSource=admin" > /u01/percona-backup-mongodb-2.12.0/pbm-agent.$(hostname -s).27001.log 2>&1 &
pbm-agent --mongodb-uri "mongodb://pbmuser:mypassword@localhost:21000/?authSource=admin"> /u01/percona-backup-mongodb-2.12.0/pbm-agent.$(hostname -s).21000.log 2>&1 &
我加上了日志输出路径。
3、Set the MongoDB connection URI for pbm CLI
export PBM_MONGODB_URI="mongodb://pbmuser:mypassword@node1:21000,node2:21000,node3:21000/?authSource=admin"
建议将这个环境变量设置到mongod用户的配置文件.bash_profile
三、Configure remote backup storage
这一步配置nfs文件存储,需在pbm-agent的每个节点挂载好nfs,确保权限赋予mongod用户。
cd /u01/percona-backup-mongodb-2.12.0
vim pbm_config.yaml
storage:
type: filesystem
filesystem:
path: /u01/nfs/ynzybak_mongodb_pbm
执行以下命令将配置写入配置库:
pbm config --file pbm_config.yaml
注:因为是将配置信息写入配置库,所以只需在一个节点执行此步骤即可。
四、Start the pbm-agent process
在3个节点,执行上面配置好的pbm-agent指令,确保如下状态:
[mongod@mongodb07 u01]$ pbm status
Cluster:
========
shard1:
- node1:27001 [P]: pbm-agent [v2.12.0] OK
- node2:27001 [S]: pbm-agent [v2.12.0] OK
- node3:27001 [S]: pbm-agent [v2.12.0] OK
configs:
- node1:21000 [P]: pbm-agent [v2.12.0] OK
- node2:21000 [S]: pbm-agent [v2.12.0] OK
- node3:21000 [S]: pbm-agent [v2.12.0] OK
五、阶段总结
此时,就可以畅快的执行pbm相关备份恢复操作了。强烈建议在此刻,在官网花半小时学习一下pbm相关的操作指令,比如这些常用的操作命令:
pbm help
pbm help backup
pbm logs
pbm list
pbm config
pbm status
六、Make a physical backup
pbm backup --type=physical
Starting backup '2025-11-07T08:09:48Z'.................................Error: get backup metadata: get: context deadline exceeded
可见报错了,原因:pbm 不支持 社区版 monogodb 的 physical backup, 只支持 logical backup
其实在错误日志可看到:
pbm logs -n shard1 -s E
[backup/2025-11-07T08:09:48Z] node check: full physical backup works since Percona Server for MongoDB 4.2.15, 4.4.6
七、Make a logical backup
$ pbm backup --type=logical
Snapshot backup "2025-11-07T08:38:14Z", started at 2025-11-07T08:38:14Z.
注:使用 pbm cancel-backup 可取消备份
$ pbm list
Backup snapshots:
2025-11-07T08:38:14Z <logical> [restore_to_time: 2025-11-07T10:16:59]
耗时统计:650G数据,备份耗时:1h38m
查看备份日志:
pbm logs --tail=100 --event=backup
pbm logs --tail=100 --event=backup/2025-11-07T08:38:14Z
查看备份详情:
pbm describe-backup "2025-11-07T08:38:14Z"
查看关于 shard1 的备份错误:
pbm logs -n shard1 -s E
八、总结
以上可见,默认的备份效率还是非常高的,比社区版原生的压缩备份方式提高了至少好几倍,可有效降低备份时间过长的风险。
后续将择机进一步探讨物理备份恢复及增量备份恢复方法,彻底解决MongoDB的备份及恢复问题。
文章评论
后续的恢复操作实践,将另外总结,先简单列一下逻辑恢复操作。
■ Make a logical restore
pbm restore "2025-11-07T08:38:14Z"
查看恢复日志:
pbm logs -t 100 -e restore
恢复部分数据:
pbm restore "2025-11-07T08:38:14Z" --ns=flowtest.test1