演示使用replica时的备份和还原
配置一个单节点的replication
方式1:使用命令参数
--replSet
mongod --dbpath /data/db --logpath /data/mongod.log --logappend --fork --port 30000 --replSet rs-lcm
方式2:使用配置
replication: oplogSizeMB: 100 replSetName: rs-lcm
使用上面两种之一方式启动后,再到mong-shell中执行初始化命令:
rs.initiate({ _id : "rs-lcm", members: [{_id: 1, host: "127.0.0.1:27017" }] })
查看节点运行状态:
rs.status()
完整备份(BSON形式)
> /bin/mongodump --host 127.0.0.1 --port 27017 --oplog --gzip --out 617/ 2020-06-17T10:32:40.454+0000 writing admin.system.version to 2020-06-17T10:32:40.457+0000 done dumping admin.system.version (1 document) 2020-06-17T10:32:40.458+0000 writing tlcm.phone to 2020-06-17T10:32:40.460+0000 done dumping tlcm.phone (3 documents) 2020-06-17T10:32:40.460+0000 writing captured oplog to 2020-06-17T10:32:40.557+0000 dumped 1 oplog entry > tree 617/ 617 ├── admin │ ├── system.version.bson.gz │ └── system.version.metadata.json.gz ├── oplog.bson └── tlcm ├── phone.bson.gz └── phone.metadata.json.gz
可以看到备份目录第一层是所有DB名字,还包含了dump过程中产生的oplog。 如果不是replica架构,无需
--oplog
参数。第二层是具体的集合。 另外mongodump/mongorestore工具不能用于还原4.2+版本的分片架构。还原完整备份
> mongorestore --host 127.0.0.1 --port 27017 --oplogReplay --gzip --drop --verbose 617/ 2020-06-17T10:53:49.344+0000 using write concern: w='majority', j=false, fsync=false, wtimeout=0 2020-06-17T10:53:49.344+0000 preparing collections to restore from 2020-06-17T10:53:49.344+0000 found collection admin.system.version bson to restore to admin.system.version 2020-06-17T10:53:49.344+0000 found collection metadata from admin.system.version to restore to admin.system.version 2020-06-17T10:53:49.344+0000 found collection tlcm.phone bson to restore to tlcm.phone 2020-06-17T10:53:49.344+0000 found collection metadata from tlcm.phone to restore to tlcm.phone 2020-06-17T10:53:49.346+0000 dropping collection tlcm.phone before restoring 2020-06-17T10:53:49.346+0000 reading metadata for tlcm.phone from 617/tlcm/phone.metadata.json.gz 2020-06-17T10:53:49.347+0000 creating collection tlcm.phone using options from metadata 2020-06-17T10:53:49.352+0000 restoring tlcm.phone from 617/tlcm/phone.bson.gz 2020-06-17T10:53:49.357+0000 no indexes to restore 2020-06-17T10:53:49.357+0000 finished restoring tlcm.phone (3 documents) 2020-06-17T10:53:49.357+0000 replaying oplog 2020-06-17T10:53:49.357+0000 applied 0 ops 2020-06-17T10:53:49.357+0000 done
如果不是
--oplog
备份,则无需--oplogReplay
, 同理--gzip
也和备份时使用的--gzip
对应。--drop
: 还原前先删除目标实例上已经有的集合。默认情况下使用保守还原更新。即只增加目标没有的数据。这里强制清理来保证数据完全恢复到指定备份。如果目标有新集合,不会清理。--dryRun
: 测试用。--oplogReplay
:只能在replica架构下使用。当使用本选项时,不能使用--db, --collection, --nsInclude, --nsExclude
来限定还原的范围。--nsFrom/--nsTo
: 用于还原时重命名备份差异oplog
因为在replica架构下,节点间同步使用了oplog机制,这些写脏历史保存在master节点中的local.oplog.rs
路径下。于是只要导出这个操作日志即可。即使同一秒有很多操作,Mongodb使用时间戳+增量来表示某个操作ID。{ "ts" : Timestamp(1592388317, 1), "t" : NumberLong(1), "h" : NumberLong("1613657939390302978"), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "periodic noop" } }
在配置时一般要指定oplog存储的大小,如果超过了就会出现丢失情况。一般根据实际数据量定好这个大小。而且我们也不需要把所有操作历史备份,一般来说,定时分段备份即可。多次replay也是幂等操作。
mongodump --host 127.0.0.1 --port 27017 -d local -c oplog.rs --query '{ts:{$gte:Timestamp('$starttime',1),$lte:Timestamp('$stoptime',9999)}}' -o ${serverpath}/${nowtime}
这里演示导出所有oplogs:
>mongodump --host 127.0.0.1 --port 27017 -d local -c oplog.rs -o Inc617 > tree Inc617/ Inc617/ └── local ├── oplog.rs.bson └── oplog.rs.metadata.json > bsondump Inc617/local/oplog.rs.bson | head -1 {"ts":{"$timestamp":{"t":1592388135,"i":1}},"h":{"$numberLong":"548748127594595304"},"v":2,"op":"n","ns":"","o":{"msg":"initiating set"}} > bsondump Inc617/local/oplog.rs.bson | grep andr {"ts":{"$timestamp":{"t":1592390699,"i":1}},"t":{"$numberLong":"1"},"h":{"$numberLong":"3532753012123006413"},"v":2,"op":"i","ns":"tlcm.phone","o":{"_id":{"$oid":"5ee9f42b1101b7935e990144"},"name":"android"}}
还原差异oplogs
/bin/mongorestore --host 127.0.0.1 --port 27017 --oplogReplay Inc617/
可以看到和恢复完整备份是一样的。只是传递的目录不一样
实例
/bin/mongorestore --oplogReplay --gzip --drop full/20200615 /bin/mongorestore --oplogReplay --gzip --drop full/20200615
评论 (0)