[SERVER-16359] Upserting a document where the _id field is a regex can cause secondaries to crash Created: 01/Dec/14  Updated: 01/Dec/14  Resolved: 01/Dec/14

Status: Closed
Project: Core Server
Component/s: Replication, Stability
Affects Version/s: 2.4.6, 2.4.12
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Ronan Bohan Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-16339 Updating by _id field with a regex br... Closed
Related
is related to SERVER-9502 Using regex in _id breaks replication Closed
Operating System: ALL
Steps To Reproduce:

MongoDB 2.4.12:

> rs.status().members.forEach(function(doc) { print(doc._id, ":", doc.stateStr) })
0 : PRIMARY
1 : SECONDARY
2 : SECONDARY
replset:PRIMARY>
replset:PRIMARY> var date1 = new ISODate("2013-01-01T00:00:00Z");
replset:PRIMARY> var date2 = new ISODate("2014-01-01T00:00:00Z");
replset:PRIMARY> var date3 = new ISODate("2015-01-01T00:00:00Z");
replset:PRIMARY>
replset:PRIMARY> db.foo.insert({_id: "ABC", when: date1})
replset:PRIMARY> db.foo.update({
...    _id: /[A-Z]/,
...    when: { $gte: date2 },
... },{
...    $set:{ when: date3 }
... },{
...    multi: true, upsert: true
... });
replset:PRIMARY>
replset:PRIMARY>
Mon Dec  1 11:39:28.030 DBClientCursor::init call() failed
>
Mon Dec  1 11:39:29.166 trying reconnect to 127.0.0.1:27017
Mon Dec  1 11:39:29.167 reconnect 127.0.0.1:27017 ok
replset:SECONDARY>
replset:SECONDARY> rs.status().members.forEach(function(doc) { print(doc._id, ":", doc.stateStr) })
0 : SECONDARY
1 : (not reachable/healthy)
2 : (not reachable/healthy)
replset:SECONDARY>
replset:SECONDARY> rs.slaveOk()
replset:SECONDARY> db.foo.find()
{ "_id" : "ABC", "when" : ISODate("2013-01-01T00:00:00Z") }
{ "_id" : /[A-Z]/, "when" : ISODate("2015-01-01T00:00:00Z") }

MongoDB 2.6.5:

replset:PRIMARY> rs.status().members.forEach(function(doc) { print(doc._id, ":", doc.stateStr) })
0 : PRIMARY
1 : SECONDARY
2 : SECONDARY
replset:PRIMARY>
replset:PRIMARY> var date1 = new ISODate("2013-01-01T00:00:00Z");
replset:PRIMARY> var date2 = new ISODate("2014-01-01T00:00:00Z");
replset:PRIMARY> var date3 = new ISODate("2015-01-01T00:00:00Z");
replset:PRIMARY>
replset:PRIMARY> db.foo.insert({_id: "ABC", when: date1})
WriteResult({ "nInserted" : 1 })
replset:PRIMARY> db.foo.update({
...    _id: /[A-Z]/,
...    when: { $gte: date2 },
... },{
...    $set:{ when: date3 }
... },{
...    multi: true, upsert: true
... });
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("547c54560419129296905c7f")
})
replset:PRIMARY>
replset:PRIMARY> rs.status().members.forEach(function(doc) { print(doc._id, ":", doc.stateStr) })
0 : PRIMARY
1 : SECONDARY
2 : SECONDARY
replset:PRIMARY>
replset:PRIMARY> db.foo.find()
{ "_id" : "ABC", "when" : ISODate("2013-01-01T00:00:00Z") }
{ "_id" : ObjectId("547c54560419129296905c7f"), "when" : ISODate("2015-01-01T00:00:00Z") }

Participants:

 Description   

Upserting a document where the the '_id' field in the query pattern is a regex results in a new document being created with the regex being stored in the '_id' field. This can lead to duplicate key errors on the secondaries when they process the oplog, resulting in a crash.

I have tested this on MongoDB 2.4.6 and 2.4.12 - both versions are affected.

MongoDB 2.6.5 handles this case differently and inserts the new document with an ObjectId for the '_id' field. As such, it does not appear to be affected.


Generated at Thu Feb 08 03:40:48 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.