mongodb备份与恢复
环境准备
- 在 mongodb 源实例(示例
192.168.31.101)上准备测试数据
use db1;
db.createCollection("aaa");
db.createCollection("bbb");
db.getCollection("aaa").insert({"id":1,"name":"tom","city":"beijing","note":"xxx1"});
db.getCollection("aaa").insert({"id":2,"name":"sam","city":"shanghai","note":"xxx2"});
db.getCollection("aaa").insert({"id":3,"name":"pay","city":"guangzhou","note":"xxx3"});
db.getCollection("aaa").insert({"id":4,"name":"dba","city":"shenzhen","note":"xxx4"});
库表的备份与还原
- 从 MongoDB 5 开始移除了 mongodump 和 mongorestore,没关系,可以从低版本的mongodb二进制文件(比如
mongodb-3.4.20)中提取这2个文件
curl -sL http://iso.sqlfans.cn/mongodb/tool/mongodump -o /usr/bin/mongodump
curl -sL http://iso.sqlfans.cn/mongodb/tool/mongorestore -o /usr/bin/mongorestore
chmod +x /usr/bin/mongo*
mongodump 备份
- 语法示例
mongodump --help
mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库名 [-c 表名] -o 文件存在路径
- 常用操作
#.备份指定库
mkdir -p /data/20220114
mongodump -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -o /data/20220114/
#.备份所有库(去掉-d)
mkdir -p /data/20220114
mongodump -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -o /data/20220114/
#.备份单表(会包含索引)
mkdir -p /data/20220114
mongodump -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -o /data/20220114/
- 附:一个定时备份的脚本
#!/bin/sh
HOST=192.168.31.101:3717
rootPath=/data/mongo_3717/backup/
BackupPath=$rootPath$(date +%Y%m%d)_$HOST/
LogFile=/data/mongo_3717/backup/run.log
DumpFile=$BackupPath
tarFile="$rootPath"$HOST_$(date +%Y%m%d).tgz
mkdir -p "$BackupPath"
find $rootPath -mtime +3 -name "*.tgz" -exec rm -rf {} \;
/usr/bin/mongodump -h $HOST -u dba_admin -p cf_rB1NKCzbaQuPH --oplog -o $DumpFile
tar czvf "$tarFile" "$DumpFile" >> $LogFile 2>&1
# rsync -e "ssh -p23245" --bwlimit=1024 -avz $tarFile 192.168.31.102:/data/dbbackup/192_168_31_101/
rm -rf "$DumpFile"
mongorestore 还原
- 语法示例:--drop导入前先删表,--noIndexRestore不还原索引,--noOptionsRestore不还原表选项,-j指定并行度
mongorestore --help
mongorestore -h IP --port 端口 -u 用户名 -p 密码 -d 数据库名 --drop 文件存在路径
- 常用操作
#.还原指定库
mongorestore -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 --drop /data/20220114/db1/
#.通过遍历目录还原所有库(即轮训所有db,--drop清理后恢复,最后还原admin库)
mongorestore -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 --drop /data/20220114/db1/
mongorestore -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db2 --drop /data/20220114/db2/
mongorestore -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d admin --drop /data/20220114/admin/
#.还原指定表(指向文件)
mongorestore -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa /data/20220114/db1/aaa.bson
表的导出与导入
- 从 MongoDB 5 开始移除了 mongoexport 和 mongoimport,没关系,可以从低版本的mongodb二进制文件(比如
mongodb-3.4.20)中提取这2个文件
curl -sL http://iso.sqlfans.cn/mongodb/tool/mongoexport -o /usr/bin/mongoexport
curl -sL http://iso.sqlfans.cn/mongodb/tool/mongoimport -o /usr/bin/mongoimport
chmod +x /usr/bin/mongo*
mongoexport 导出
- 语法示例
mongoexport --help
mongoexport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库名 -c 表名 -f 字段名 -q 筛选条件 --type=csv -o 文件存在路径
- 导出单表所有字段、指定字段(默认json格式,会带出_id字段)
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -o /aaa_1.json
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -f name,city -o /aaa_2.json
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -f name,city -q '{"id":{"$gt":1,"$lt":4},"city":"shanghai"}' -o /aaa_3.json
- 使用 --type 指定导出格式(若导出为csv格式则必须用-f指定字段清单,且csv格式第一行为字段名称)
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa --type=csv -o /aaa_4.csv #.这个会报错
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -f name,city --type=csv -o /aaa_5.csv
mongoexport -h 192.168.31.101 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -f name,city -q '{"id":{"$gt":1,"$lt":4},"city":"shanghai"}' --type=csv -o /aaa_6.csv
mongoimport 导入
- 语法示例:--type指定导出的文件格式,--headerline指定第一行是列名而不导入,--drop删除已存在的表再导入
- 注意:导入后的新表无索引哦~
mongoimport --help
mongoimport --port 端口 -u 用户名 -p 密码 -d 数据库名 -c 表名 --headerline --type=csv --file 文件存在路径
- 建议:导入之前先将老表改个名字
use db1
db.aaa.renameCollection("aaa_20220114_del");
- 导入单表所有字段(导入json格式的时候不能指定字段)
#.导入所有字段
mongoimport -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa --drop /aaa_1.json
#.下面的会报错,不能对json格式指定字段清单
mongoimport -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa -f name,city --drop /aaa_1.json
#.导入之后,记得对新表添加索引
db.aaa.ensureIndex({"city" : 1},{backgroud : true})
- 使用 --type=csv 导入 mongoexport 指定的字段,而 --headerline 可以不将第一列的字段名作为数据而导入
#.导入mongoexport指定的字段
mongoimport -h 192.168.31.102 --port 3717 -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin -d db1 -c aaa --headerline --type=csv --drop --file /aaa_5.csv
#.导入之后,记得对新表添加索引
db.aaa.ensureIndex({"city" : 1},{backgroud : true})
物理备份
- MongoDB 社区版主要支持逻辑备份,而一些高级功能(如物理备份和增量备份)则需要 MongoDB 企业版或 Percona Server for MongoDB
注:很遗憾,MongoDB 社区版没有办法物理备份 ...
| 备份功能 | MongoDB 社区版 | Percona Server for MongoDB |
|---|---|---|
| 逻辑备份 | ✔ | ✔ |
| 物理备份 | ✖ | ✔ (需满足版本要求) |
| 增量备份 | ✖ | ✔ (需满足版本要求) |
| PITR 时间点恢复 | ✔(仅逻辑方式) | ✔(逻辑和物理方式) |
| 快照备份 | ✖ | ✔ |
Percona Backup for MongoDB
- 针对 Percona Server for MongoDB 推荐 Percona Backup for MongoDB,它支持集群范围的一致性物理备份,并提供增量备份等功能,比手动操作更可靠
注:PBM 的设计目标是用于副本集和分片集群,不适用于独立的 MongoDB 实例,而物理备份(pbm backup -t physical)不支持 MongoDB 社区版,仅支持 Percona Server for MongoDB,但逻辑备份则全都支持
- 安装 pbm 2.15.0
#.查看副本集状态
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 127.0.0.1 --port 3717 admin --quiet --eval "rs.status()"
#.下载安装pbm
cd /opt/
wget -c http://iso.sqlfans.cn/mongodb/percona-backup-mongodb-2.15.0-x86_64.tar.gz
tar -xvf percona-backup-mongodb-2.15.0-x86_64.tar.gz
cp percona-backup-mongodb-2.15.0/pbm /usr/bin/
cp percona-backup-mongodb-2.15.0/pbm-agent /usr/bin/
pbm version
#.创建备份目录
mkdir -p /data/mongo_3717/backup
#.创建配置文件
cat > /data/mongo_3717/pbm_config.yaml <<EOF
storage:
type: filesystem
filesystem:
path: /data/mongo_3717/backup
EOF
#.配置变量
cat /etc/profile | grep PBM_MONGODB_URI || echo 'export PBM_MONGODB_URI="mongodb://dba_admin:cf_rB1NKCzbaQuPH@192.168.31.101:3717/?authSource=admin"' >> /etc/profile
source /etc/profile
echo $PBM_MONGODB_URI
#.应用配置
pbm config --file /data/mongo_3717/pbm_config.yaml
pbm status
#.启动pbm-agent进程
nohup pbm-agent --mongodb-uri "mongodb://dba_admin:cf_rB1NKCzbaQuPH@192.168.31.101:3717/?authSource=admin" > /data/mongo_3717/mongo_backup.log 2>&1 &
- 利用 pbm 备份与还原
#.创建逻辑备份
pbm backup -t logical
#.创建物理备份(不支持社区版的物理备份,会报错 node is not suitable for backup)
pbm backup -t physical
#.启用PITR(恢复到任意时间点)
pbm config --set pitr.enabled=true
pbm config | grep -A2 pitr
#.备份特定库表
pbm backup --ns="db1.aaa"
#.备份特定库 + 特定表
pbm backup --ns="testdb.*" --ns="db1.aaa"
#.查看备份列表
[root@localhost ~]# pbm list
Backup snapshots:
NAME TYPE PROFILE SELECTIVE BASE RESTORE TIME
-----------------------------------------------------------------------------------------------------
2026-08-01T04:37:05Z logical no no 2026-08-01T04:37:09
2026-08-01T04:38:06Z logical yes no 2026-08-01T04:38:09
2026-08-01T04:38:19Z logical yes no 2026-08-01T04:38:23
PITR <off>:
2026-08-01T04:37:10 - 2026-08-01T04:40:20
#.删表测试
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 192.168.31.101 --port 3717 admin --quiet --eval "db.getSiblingDB('db1').aaa.drop()"
#.恢复到指定时间点,不要加Z
pbm restore --time "2026-08-01T04:38:19"
#.确认表已恢复
/opt/mongodb/bin/mongosh -u dba_admin -p cf_rB1NKCzbaQuPH --authenticationDatabase admin --host 192.168.31.101 --port 3717 admin --quiet --eval "db.getSiblingDB('db1').getCollectionNames()"
- 查看 pbm 状态
[root@localhost opt]# pbm status
WARNING: This PBM works with MongoDB and PSMDB v7.0, v8.0 and you are running v6.0. Please upgrade your MongoDB to a supported version.
Cluster:
========
set3717:
- 192.168.31.101:3717 [P]: pbm-agent [v2.15.0] OK
- 192.168.31.102:3717 [ ]: pbm-agent [NOT FOUND]
- 192.168.31.103:3717 [H]: pbm-agent [NOT FOUND]
PITR incremental backup:
========================
Status [OFF]
Currently running:
==================
(none)
Backups:
========
Main storage:
Type: FS
Path: /data/mongo_3717/backup
Snapshots:
NAME SIZE TYPE PROFILE SEL BASE RESTORE TIME STATUS
------------------------------------------------------------------------------------------------------------------
2026-08-01T04:38:19Z 9.81KB logical yes no 2026-08-01T04:38:23 done
2026-08-01T04:38:06Z 5.81KB logical yes no 2026-08-01T04:38:09 done
2026-08-01T04:37:15Z 0.00B physical no no 2026-08-01T04:37:15 error: Backup stuck at `sta...
2026-08-01T04:37:05Z 26.58KB logical no no 2026-08-01T04:37:09 done
PITR chunks [109.80KB]:
2026-08-01T04:37:10 - 2026-08-01T04:40:20
部署定时备份
- 修改相关参数,然后部署 crontab 定时任务,仅供参考:
#!/bin/sh
HOST=127.0.0.1:27017
rootPath=/data/mongo_backup/
BackupPath=$rootPath$(date +%Y%m%d)_$HOST/
LogFile=/data/mongodb_backup/run.log
DumpFile=$BackupPath
tarFile="$rootPath"$HOST_$(date +%Y%m%d).tgz
mkdir -p "$BackupPath"
find $rootPath -mtime +3 -name "*.tgz" -exec rm -rf {} \;
/opt/mongodb/bin/mongodump -h $HOST -u dba_admin -p cf_rB1NKCzbaQuPH --oplog -o $DumpFile
tar czvf "$tarFile" "$DumpFile" >> $LogFile 2>&1
#rsync -e "ssh -p23245" --bwlimit=1024 -avz $tarFile 127.0.0.1:/data/dbbackup/127_0_0_1/
rm -rf "$DumpFile"