使用 mongorestore 重放带有 binData 字段的 oplog 时出错
error when using mongorestore to replay oplog with binData field
当使用带选项--oplogReplay 的mongorestore 重播oplog 时,我发现了一个奇怪的错误,即mongorestore 无法处理binData 字段的设置操作。如果您这样做,您可能会遇到同样的错误:
插入一个测试数据。
db.testData.insert({_id: 10000, data: BinData(0, ""), size: 10})
更新其 binData 字段。
db.testData.update({_id: 10000}, {$set: {data: BinData(0, "CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA=")}})
更新其其他字段
db.testData.update({_id: 10000}, {$set: {size: 20}})
检查 oplog
use local
db.oplog.rs.find().sort({$natural: -1})
您可能会看到以下回复:
{ "ts" : Timestamp(1435627154, 1), "h" : NumberLong("-4979206321598144076"), "v" : 2, "op" : "u", "ns" : "test.testData", "o2" : { "_id" : 10000 }, "o" : { "$set" : { "size" : 20 } } }
{ "ts" : Timestamp(1435627144, 1), "h" : NumberLong("2899524097634687825"), "v" : 2, "op" : "u", "ns" : "test.testData", "o2" : { "_id" : 10000 }, "o" : { "$set" : { "data" : BinData(0,"CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA=") } } }
{ "ts" : Timestamp(1435627136, 1), "h" : NumberLong("-8486373688715225152"), "v" : 2, "op" : "i", "ns" : "test.testData", "o" : { "_id" : 10000, "data" : BinData(0,""), "size" : 10 } }
转储这两个oplog并重播
在bash shell:
mongodump --port 27017 -d local -c oplog.rs --query '{"ts" : {$gte: Timestamp(1435627144, 1)}}' -o ./oplogD/
mv ./oplogD/local/oplog.rs.bson ./oplogR/oplog.bson
mongorestore --port 27017 --oplogReplay ./oplogR/
之后您会发现数据与预期不符。在我自己,数据更改为这个。
{ "_id" : 10000, "data" : BinData(0,"ADRAAAAAPiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA="), "size" : 20 }
尺寸字段确实正确,但数据字段不正确。
最奇怪的事情就是这样,如果你只转储一个 oplog并重播它,数据会是正确的。
mongodump --port 27017 -d local -c oplog.rs --query '{"ts" : Timestamp(1435627144, 1)}' -o ./tmpD/
mv ./tmpD/local/oplog.rs.bson ./tmpR/oplog.bson
mongorestore --port 27017 --oplogReplay ./tmpR/
重放oplog后,'data'字段非常正确。
{ "_id" : 10000, "data" : BinData(0,"CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA="), "size" : 10 }
为什么会发生这种奇怪的事情?
当使用带选项--oplogReplay 的mongorestore 重播oplog 时,我发现了一个奇怪的错误,即mongorestore 无法处理binData 字段的设置操作。如果您这样做,您可能会遇到同样的错误:
插入一个测试数据。
db.testData.insert({_id: 10000, data: BinData(0, ""), size: 10})
更新其 binData 字段。
db.testData.update({_id: 10000}, {$set: {data: BinData(0, "CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA=")}})
更新其其他字段
db.testData.update({_id: 10000}, {$set: {size: 20}})
检查 oplog
use local db.oplog.rs.find().sort({$natural: -1})
您可能会看到以下回复:
{ "ts" : Timestamp(1435627154, 1), "h" : NumberLong("-4979206321598144076"), "v" : 2, "op" : "u", "ns" : "test.testData", "o2" : { "_id" : 10000 }, "o" : { "$set" : { "size" : 20 } } } { "ts" : Timestamp(1435627144, 1), "h" : NumberLong("2899524097634687825"), "v" : 2, "op" : "u", "ns" : "test.testData", "o2" : { "_id" : 10000 }, "o" : { "$set" : { "data" : BinData(0,"CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA=") } } } { "ts" : Timestamp(1435627136, 1), "h" : NumberLong("-8486373688715225152"), "v" : 2, "op" : "i", "ns" : "test.testData", "o" : { "_id" : 10000, "data" : BinData(0,""), "size" : 10 } }
转储这两个oplog并重播
在bash shell:
mongodump --port 27017 -d local -c oplog.rs --query '{"ts" : {$gte: Timestamp(1435627144, 1)}}' -o ./oplogD/ mv ./oplogD/local/oplog.rs.bson ./oplogR/oplog.bson mongorestore --port 27017 --oplogReplay ./oplogR/
之后您会发现数据与预期不符。在我自己,数据更改为这个。
{ "_id" : 10000, "data" : BinData(0,"ADRAAAAAPiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA="), "size" : 20 }
尺寸字段确实正确,但数据字段不正确。
最奇怪的事情就是这样,如果你只转储一个 oplog并重播它,数据会是正确的。
mongodump --port 27017 -d local -c oplog.rs --query '{"ts" : Timestamp(1435627144, 1)}' -o ./tmpD/ mv ./tmpD/local/oplog.rs.bson ./tmpR/oplog.bson mongorestore --port 27017 --oplogReplay ./tmpR/
重放oplog后,'data'字段非常正确。
{ "_id" : 10000, "data" : BinData(0,"CgxVfs93PiT/DrxMSvASFgoNMTAuMTYwLjIyMi4xMhDEJxgKIAA="), "size" : 10 }
为什么会发生这种奇怪的事情?