mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 17:10:48 +01:00
SERVER-31953 Target secondary application of updates and deletes by just _id
This commit is contained in:
parent
368f337eae
commit
b6235c8418
30
jstests/sharding/replication_with_undefined_shard_key.js
Normal file
30
jstests/sharding/replication_with_undefined_shard_key.js
Normal file
@ -0,0 +1,30 @@
|
||||
// Test for SERVER-31953 where secondaries crash when replicating an oplog entry where the document
|
||||
// identifier in the oplog entry contains a shard key value that contains an undefined value.
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
const st = new ShardingTest({mongos: 1, config: 1, shard: 1, rs: {nodes: 2}});
|
||||
const mongosDB = st.s.getDB("test");
|
||||
const mongosColl = mongosDB.mycoll;
|
||||
|
||||
// Shard the test collection on the "x" field.
|
||||
assert.commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()}));
|
||||
assert.commandWorked(mongosDB.adminCommand({
|
||||
shardCollection: mongosColl.getFullName(),
|
||||
key: {x: 1},
|
||||
}));
|
||||
|
||||
// Insert a document with a literal undefined value.
|
||||
assert.writeOK(mongosColl.insert({x: undefined}));
|
||||
|
||||
jsTestLog("Doing writes that generate oplog entries including undefined document key");
|
||||
|
||||
assert.writeOK(mongosColl.update(
|
||||
{},
|
||||
{$set: {a: 1}},
|
||||
{multi: true, writeConcern: {w: 2, wtimeout: ReplSetTest.kDefaultTimeoutMs}}));
|
||||
assert.writeOK(
|
||||
mongosColl.remove({}, {writeConcern: {w: 2, wtimeout: ReplSetTest.kDefaultTimeoutMs}}));
|
||||
|
||||
st.stop();
|
||||
})();
|
@ -1297,12 +1297,15 @@ Status applyOperation_inlock(OperationContext* opCtx,
|
||||
} else if (*opType == 'u') {
|
||||
opCounters->gotUpdate();
|
||||
|
||||
BSONObj updateCriteria = o2;
|
||||
const bool upsert = valueB || alwaysUpsert;
|
||||
|
||||
auto idField = o2["_id"];
|
||||
uassert(ErrorCodes::NoSuchKey,
|
||||
str::stream() << "Failed to apply update due to missing _id: " << op.toString(),
|
||||
updateCriteria.hasField("_id"));
|
||||
!idField.eoo());
|
||||
|
||||
// The o2 field may contain additional fields besides the _id (like the shard key fields),
|
||||
// but we want to do the update by just _id so we can take advantage of the IDHACK.
|
||||
BSONObj updateCriteria = idField.wrap();
|
||||
const bool upsert = valueB || alwaysUpsert;
|
||||
|
||||
UpdateRequest request(requestNss);
|
||||
request.setQuery(updateCriteria);
|
||||
@ -1379,9 +1382,14 @@ Status applyOperation_inlock(OperationContext* opCtx,
|
||||
} else if (*opType == 'd') {
|
||||
opCounters->gotDelete();
|
||||
|
||||
auto idField = o["_id"];
|
||||
uassert(ErrorCodes::NoSuchKey,
|
||||
str::stream() << "Failed to apply delete due to missing _id: " << op.toString(),
|
||||
o.hasField("_id"));
|
||||
!idField.eoo());
|
||||
|
||||
// The o field may contain additional fields besides the _id (like the shard key fields),
|
||||
// but we want to do the delete by just _id so we can take advantage of the IDHACK.
|
||||
BSONObj deleteCriteria = idField.wrap();
|
||||
|
||||
SnapshotName timestamp;
|
||||
if (assignOperationTimestamp) {
|
||||
@ -1396,7 +1404,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
|
||||
}
|
||||
|
||||
if (opType[1] == 0) {
|
||||
deleteObjects(opCtx, collection, requestNss, o, /*justOne*/ valueB);
|
||||
deleteObjects(opCtx, collection, requestNss, deleteCriteria, /*justOne*/ valueB);
|
||||
} else
|
||||
verify(opType[1] == 'b'); // "db" advertisement
|
||||
wuow.commit();
|
||||
|
Loading…
Reference in New Issue
Block a user