1 备份恢复工具介绍
-
mongoexport
/mongoimport
,导入/导出的是JSON格式或CSV格式 -
mongodump
/mongorestore
,导入/导出的是BSON格式,常用!
JSON可读性强但体积较大,BSON是JSON的二进制文件,体积小但对人类几乎没有可读性。
在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump
/mongorestore
可能不会成功,具体要看版本之间的兼容性。当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport
/mongoimport
是一个可选项。不推荐进行跨版本的mongodump
/mongorestore
。
应用场景总结:
- 跨版本的mongodb数据导入导出,或异构平台的数据迁移,只能使用
mongoexport
/mongoimport
。 - 日常备份恢复,使用
mongodump
/mongorestore
。
2 mongoexport和mongoimport
2.1 mongoexport
参数说明
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-f 指明要导出哪些列
-o 指明要导出的文件名
-q 指明导出数据的过滤条件
--authenticationDatabase 指明验证库
--type 指明导出文件类型,默认是json,可以配置为CSV
例子:备份bigsky
库的log
集合,认证库是admin
#json格式备份
mongoexport -u root -p 123 -d bigsky -c log -o /tmp/log.json --authenticationDatabase admin
#CSV格式备份,需要-f指定备份哪些列
mongoexport -u root -p 123 -d bigsky -c log -o /tmp/log.csv --authenticationDatabase admin --type CSV -f uid
2.2 mongoimport
参数说明
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-f 指明要导入哪些列,多个列用","分割
-j 并发导入,使用几个cpu,默认是1
--drop 导入时删除原集合中的数据
--authenticationDatabase 指明验证库
例子:导入到aaa
库的test
集合,认证库是admin
#json导入
mongoimport -u root -p 123 -d aaa -c test --authenticationDatabase admin log.json
#CSV导入,当头行是列名时,需要加 --headerline参数
mongoimport -u root -p 123 -d aaa -c test1 --type CSV --headerline --authenticationDatabase admin log.csv
#CSV导入,当没有列名时,需要加 -f指定导入哪列
mongoimport -u root -p 123 -d aaa -c test2 --type CSV -f uid --authenticationDatabase admin log.csv
2.3 异构迁移
通过CSV格式的文件进行迁移,mysql和mongodb导出支持的CSV格式稍有不同,中间需要更改表的格式
mongodb格式第一行为列名,行数据用
,
分隔mysql导出的CSV不包含列名,行数据用
\t
分隔
2.3.1 mysql到mongodb
2.3.1.1 mysql导出数据
要导出的数据
由于mysql默认导出的格式与mongodb不一样,导出时需要更改格式,使用fields terminated by ','
参数
select id,sname,sage from test.t1 into outfile '/tmp/backup.csv' fields terminated by ',';
效果如下:
2.3.1.2 mongodb导入数据
由于mysql导出时不带列名,mongodb导入时需要加-f
参数指定列名
mongoimport -u root -p 123 -d test -c t1 --type CSV -f id,sname,sage --authenticationDatabase admin /tmp/backup.csv
2.3.2 mongodb到mysql
2.3.2.1 mongodb导出数据
要导出的数据
导出CSV格式数据
mongoexport -u root -p 123 -d test -c t1 -o /tmp/t1.csv --authenticationDatabase admin --type CSV -f id,sname,sage
导出的数据如下
2.3.2.2 mysql导入数据
创建跟mongodb导出数据列名一样的表
CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学号',
`sname` varchar(255) NOT NULL COMMENT '姓名',
`sage` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '年龄',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
在mysql中导入数据
LOAD DATA LOCAL INFILE '/tmp/t1.csv' INTO TABLE t2 CHARACTER SET utf8
FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (`id`,`sname`,`sage`);
3 mongodump和mongorestore
mongodump能够在Mongodb运行时进行备份,它的工作原理是对运行的Mongodb做查询,然后将所有查到的文档写入磁盘。
存在的问题:
使用Mongodump产生的备份不一定是数据库的实时快照,如果在备份时对数据库进行了写入操作,则备份出来的文件可能不完全和Mongodb实时数据相等。另外在备份时可能会对其他客户端性能产生影响。
3.1 mongodump
3.1.1 命令参数
mongodump --help
参数说明
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-o 指明要导出的文件名
-q 指明导出数据的过滤条件
-j 并发导出,使用几个cpu,默认是1
--oplog 同时备份oplog,配置复制集时使用
--authenticationDatabase 指明验证库
3.1.2 全库备份
mkdir /mongodb/backup
mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -o /mongodb/backup
备份后每个库生成一个目录,每个集合生成两个文件:一个.bson
文件、一个.metadata.json
文件
.bson
文件可以用bsondump
命令查看并导出成json格式,之后可以用mongoimport工具还原
bsondump test/t1.bson
{"_id":{"$oid":"60ab580444c9cbde02a3b130"},"id":{"$numberInt":"1"},"sname":"aaa","sage":{"$numberInt":"10"}}
{"_id":{"$oid":"60ab580444c9cbde02a3b131"},"id":{"$numberInt":"2"},"sname":"bbb","sage":{"$numberInt":"11"}}
{"_id":{"$oid":"60ab580444c9cbde02a3b132"},"id":{"$numberInt":"3"},"sname":"ccc","sage":{"$numberInt":"12"}}
3.1.3 备份单库
备份test单库
mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -d test -o /mongodb/backup
3.1.4 备份单集合
备份test库的t1集合
mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -d test -c t1 -o /mongodb/backup
3.1.5 压缩备份
加入--gzip
参数进行压缩,会对每个bson
和json
文件进行gz压缩
mongodump -uroot -p123 --port 27017 --authenticationDatabase admin -o /mongodb/backup --gzip
3.2 mongorestore
3.2.1 常用参数
mongorestore --help
参数说明
-h 指明数据库宿主机的IP
-u 指明数据库的用户名
-p 指明数据库的密码
-d 指明数据库的名字
-c 指明collection的名字
-j 并发导出,使用几个cpu,默认是1
--drop 恢复的时候把之前的集合drop掉10.207.42.0/
--authenticationDatabase 指明验证库
--oplogReplay 同时恢复oplog中的内容
--oplogLimit <seconds>[:ordinal]恢复到指定的时间戳之前
3.2.2 全备恢复
mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin /mongodb/backup
3.2.3 单库恢复
备份文件的目录需定位到备份出来的库目录
,本例恢复test
库,指向的备份文件目录为/mongodb/backup/test
mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin -d test --gzip /mongodb/backup/test
3.2.4 单集合恢复
备份文件的目录需定位到备份出来的集合文件名
,本例恢复test
库的t5
集合,指向的备份文件名为/mongodb/backup/test/t5.bson.gz
mongorestore -uroot -p123 --port 27017 --authenticationDatabase admin -d test -c t5 --gzip /mongodb/backup/test/t5.bson.gz
4 oplog应用
4.1 介绍
在replica set中oplog是一个定容集合(capped collection),它的默认大小是磁盘空间的5%,可以通过--oplogSizeMB
参数修改。
位于local
库的db.oplog.rs
,其中记录的是整个mongod实例一段时间内数据库的所有变更(插入/更新/删除)操作,类似于mysql binlog。当空间用完时新记录自动覆盖最老的记录。
oplog的覆盖范围为oplog的时间窗口,因为oplog是一个定容集合,所以时间窗口能覆盖的范围会因为单位时间内的更新次数不同而变化。
4.2 db.oplog.rs中的内容
{
"op" : "n",
"ns" : "",
"o" : {
"msg" : "periodic noop"
},
"ts" : Timestamp(1620637412, 1),
"t" : NumberLong(1),
"wall" : ISODate("2021-05-10T09:03:32.359Z"),
"v" : NumberLong(2)
}
重点关注参数:
"ts":时间戳,()中前一个数是时间,后一个数是当时发生的第几个事件
"op":进行操作的类型,"n"提示类的、"i"insert、"u"update、"d"delete、"c"db cmd(删库建库,删表建表...)
4.3 oplog大小及覆盖窗口
查看当前配置的大小rs.printReplicationInfo()
my_repl:PRIMARY> rs.printReplicationInfo()
configured oplog size: 2048MB
log length start to end: 2422018secs (672.78hrs)
oplog first event time: Mon May 10 2021 17:01:20 GMT+0800 (CST)
oplog last event time: Mon Jun 07 2021 17:48:18 GMT+0800 (CST)
now: Mon Jun 07 2021 17:48:27 GMT+0800 (CST)
参数解释:
configured oplog size: 当前配置的大小
log length start to end: 预估的覆盖时间
因为log length start to end
是预估的时间,所以生产中一般在覆盖时间内对db.oplog.rs
表进行定期全备。
4.4 带有oplog的备份、恢复
4.4.1 mongodump
使用mongodump备份时,可以将备份过程中数据库的操作通过oplog备份出,添加--oplog
参数
mongodump -uroot -p123 --port 28017 --authenticationDatabase admin --oplog -o /mongodb/backup
4.4.2 mongorestore
由于复制集默认只有主节点有写入权限,所以恢复的时候要连接主节点,添加--oplogReplay
参数
mongorestore -uroot -p123 --port 28018 --authenticationDatabase admin --oplogReplay /mongodb/backup
5 oplog备份恢复案例
5.1 模拟全备+oplog故障恢复
5.1.1 环境准备
创建bigsky库和t1表、t2表
use bigsky
db.t1.insert([{"id":1},{"id":2}])
db.t2.insert({"id":1})
进行全备
mongodump --port 28018 --oplog -o /mongodb/backup/
5.1.2 模拟插入数据和删库操作
对t2表继续插入数据
db.t2.insert([{"id":2},{"id":3}])
删库
use bigsky
db.dropDatabase()
5.1.3 定位删除操作的时间戳
use local
db.oplog.rs.find({"op":"c"}).pretty()
删库时,数据库内部的操作顺序是先删表再删库,以此为依据来定位删除的起始时间,起始时间是1623141134, 1
5.1.4 备份出全量oplog
mongodump --port 28018 -d local -c oplog.rs -o /mongodb/oplog/
5.1.5 使用全量oplog替换全备的oplog
mv /mongodb/oplog/local/oplog.rs.bson /mongodb/backup/oplog.bson
5.1.6 mongorestore恢复到删除操作之前
--oplogLimit "1623141134:1"
恢复到删除操作之前
mongorestore --port 28018 --oplogReplay --oplogLimit "1623141134:1" /mongodb/backup/ --drop
6 分片集群备份思路
6.1 需要备份的服务
config server
shard节点
6.2 备份的困难和问题
- chunk迁移问题
人为控制备份的时间,避开balancer开启chunk迁移的时间窗口。保证备份出来的config server中记录的分片信息和shard中的分片信息一致。 - shard节点之间的数据不在同一时间点
选择业务量较少的时间,将shard集中的从节点剔除复制集,备份从节点数据后,再将从节点加回集群。