MongoDB是可以使用复制集的方式完成数据高可用,其实也不会丢数据,但是公司一般还是会要求有一个备份的库。而且在一些网络不能连通的情况(中间需要跨多个网络),就还需要实现手工的增量备份。本文介绍如何使用oplog完成MongoDB的增量备份。
数据准备
tenmao_mongo:PRIMARY> use blog
switched to db blog
tenmao_mongo:PRIMARY> db.article.insert({title:"one"})
WriteResult({ "nInserted" : 1 })
tenmao_mongo:PRIMARY> db.article.insert({title:"two"})
WriteResult({ "nInserted" : 1 })
tenmao_mongo:PRIMARY> db.article.insert({title:"three"})
WriteResult({ "nInserted" : 1 })
全量备份
#全量导出,而且同时导出oplog(这样就保证数据不会丢失)
mongodump --host=localhost --port 27017 --oplog --out=bkm
# 全量导入
mongorestore --host=localhost --port 28017 --oplogReplay bkm
导出的时候一定要使用
--oplog
,导入的时候也要使用--oplogReplay
,否则oplog的信息就会丢失,有的文章中oplog可以后续再导入,但是这里的oplog是无法导入的(可以导入的看后面)
增量备份
- 获取全量导入时的最新时间戳
[tim@vm backup]$ bsondump bkm/oplog.bson
{"ts":{"$timestamp":{"t":1557155068,"i":1}},"t":{"$numberLong":"1"},"h":{"$numberLong":"-8619141524121903478"},"v":2,"op":"n","ns":"","wall":{"$date":"2019-05-06T15:04:28.087Z"},"o":{"msg":"periodic noop"}}
得到时间戳Timestamp(1557155068, 1)
- 再在主库中插入数据
tenmao_mongo:PRIMARY> db.article.insert({title:"four"})
WriteResult({ "nInserted" : 1 })
- 导出新的oplog(增量)
mongodump --host localhost --port 27017 -d local -c oplog.rs -q '{ts:{$gt: Timestamp(1557155068, 1)}}'
- 导入oplog(增量)
mongorestore --host localhost --port 28017 --oplogReplay dump/local/oplog.rs.bson
- 查看备库数据
> db.article.find()
{ "_id" : ObjectId("5cd049460dec5d0273a0e3f9"), "title" : "one" }
{ "_id" : ObjectId("5cd049490dec5d0273a0e3fa"), "title" : "two" }
{ "_id" : ObjectId("5cd0494d0dec5d0273a0e3fb"), "title" : "three" }
{ "_id" : ObjectId("5cd18baedbafdcd937baa41c"), "title" : "four" }
- 继续
循环:后面就继续不断地根据前面一次的最新的timestamp,然后检索出新的oplog,再应用到备库
常见问题
-
Failed: no oplog file to replay; make sure you run mongodump with --oplog
一般使用因为全量导出数据时生成的oplog,不能单独的使用mongorestore --oplogReplay
导入,比如mongorestore --oplogReplay bkm/oplog.bson
网友评论