|
Adding some clarification to the description above:
Line 2 inserts a normal document with '_id' set to 'A'. This is replicated as normal to the secondaries.
Line 3 is the real problem in which an upsert command is issued but no matching documents are found. In MongoDB 2.4.x this will create a new, malformed document in which the value of '_id' is the regex '/[A-Z]/'. In the presence of the document from the preceding line it will cause the secondaries to crash.
After running the code above we get the following in MongoDB 2.4.12:
replset:PRIMARY> var date = new ISODate()
|
replset:PRIMARY> db.test.insert( { _id : "A", date : new ISODate() } )
|
replset:PRIMARY> db.test.update( { _id : /[A-Z]/, date : { $lte : date } }, { $set : { date : date } }, { multi : true, upsert : true } )
|
replset:PRIMARY>
|
Mon Dec 1 12:49:08.797 DBClientCursor::init call() failed
|
>
|
Mon Dec 1 12:49:09.765 trying reconnect to 127.0.0.1:27017
|
Mon Dec 1 12:49:09.765 reconnect 127.0.0.1:27017 ok
|
replset:SECONDARY> rs.slaveOk()
|
replset:SECONDARY> db.test.find()
|
{ "_id" : "A", "date" : ISODate("2014-12-01T12:48:59.680Z") }
|
{ "_id" : /[A-Z]/, "date" : ISODate("2014-12-01T12:48:55.230Z") }
|
replset:SECONDARY> use local
|
switched to db local
|
replset:SECONDARY> db.oplog.rs.find()
|
{ "ts" : Timestamp(1417438065, 1), "h" : NumberLong(0), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
|
{ "ts" : Timestamp(1417438139, 1), "h" : NumberLong("-7187006773419573231"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : "A", "date" : ISODate("2014-12-01T12:48:59.680Z") } }
|
{ "ts" : Timestamp(1417438145, 1), "h" : NumberLong("-877234760831691788"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : /[A-Z]/, "date" : ISODate("2014-12-01T12:48:55.230Z") } }
|
replset:SECONDARY>
|
MongoDB 2.6.5 does not appear to be affected:
replset:PRIMARY> var date = new ISODate()
|
replset:PRIMARY> db.test.insert( { _id : "A", date : new ISODate() } )
|
WriteResult({ "nInserted" : 1 })
|
replset:PRIMARY> db.test.update( { _id : /[A-Z]/, date : { $lte : date } }, { $set : { date : date } }, { multi : true, upsert : true } )
|
WriteResult({
|
"nMatched" : 0,
|
"nUpserted" : 1,
|
"nModified" : 0,
|
"_id" : ObjectId("547c643cb6f12be4a6160b28")
|
})
|
replset:PRIMARY> db.test.find()
|
{ "_id" : "A", "date" : ISODate("2014-12-01T12:51:02.599Z") }
|
{ "_id" : ObjectId("547c643cb6f12be4a6160b28"), "date" : ISODate("2014-12-01T12:50:55.826Z") }
|
replset:PRIMARY> use local
|
switched to db local
|
replset:PRIMARY> db.oplog.rs.find()
|
{ "ts" : Timestamp(1417438236, 1), "h" : NumberLong(0), "v" : 2, "op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
|
{ "ts" : Timestamp(1417438262, 1), "h" : NumberLong("-7186997792642957295"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : "A", "date" : ISODate("2014-12-01T12:51:02.599Z") } }
|
{ "ts" : Timestamp(1417438268, 1), "h" : NumberLong("-857225590531386380"), "v" : 2, "op" : "i", "ns" : "test.test", "o" : { "_id" : ObjectId("547c643cb6f12be4a6160b28"), "date" : ISODate("2014-12-01T12:50:55.826Z") } }
|
replset:PRIMARY>
|
|