summaryrefslogtreecommitdiff
path: root/jstests/sharding/query
diff options
context:
space:
mode:
Diffstat (limited to 'jstests/sharding/query')
-rw-r--r--jstests/sharding/query/agg_explain_fmt.js1
-rw-r--r--jstests/sharding/query/aggregation_currentop.js5
-rw-r--r--jstests/sharding/query/delete_with_partial_shard_key.js65
-rw-r--r--jstests/sharding/query/find_and_modify_with_partial_shard_key.js55
-rw-r--r--jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js6
-rw-r--r--jstests/sharding/query/lookup_mongod_unaware.js62
-rw-r--r--jstests/sharding/query/merge_nondefault_read_concern.js39
-rw-r--r--jstests/sharding/query/merge_write_concern.js28
-rw-r--r--jstests/sharding/query/metadata_removal.js46
-rw-r--r--jstests/sharding/query/shard_refuses_cursor_ownership.js83
10 files changed, 14 insertions, 376 deletions
diff --git a/jstests/sharding/query/agg_explain_fmt.js b/jstests/sharding/query/agg_explain_fmt.js
index a1049e6f937..b11381a63d1 100644
--- a/jstests/sharding/query/agg_explain_fmt.js
+++ b/jstests/sharding/query/agg_explain_fmt.js
@@ -59,6 +59,7 @@ assert.eq(mergeCursors.nss,
"test.agg_explain_fmt",
mergeCursors); // This test manually sets collection and db at the top.
assert.eq(mergeCursors.allowPartialResults, false, mergeCursors);
+assert.eq(mergeCursors.recordRemoteOpWaitTime, false, mergeCursors);
// Do a sharded explain from a mongod, not mongos, to ensure that it does not have a
// SHARDING_FILTER stage.");
diff --git a/jstests/sharding/query/aggregation_currentop.js b/jstests/sharding/query/aggregation_currentop.js
index 207d93b42f2..58d63128329 100644
--- a/jstests/sharding/query/aggregation_currentop.js
+++ b/jstests/sharding/query/aggregation_currentop.js
@@ -13,7 +13,7 @@
* applicable.
*
* This test requires replica set configuration and user credentials to persist across a restart.
- * @tags: [requires_persistence, uses_transactions, uses_prepare_transaction, requires_fcv_60]
+ * @tags: [requires_persistence, uses_transactions, uses_prepare_transaction]
*/
// Restarts cause issues with authentication for awaiting replication.
@@ -411,8 +411,7 @@ function runCommonTests(conn, curOpSpec) {
explain: true
}));
- let expectedStages =
- [{$currentOp: {idleConnections: true, allUsers: false}}, {$match: {desc: {$eq: "test"}}}];
+ let expectedStages = [{$currentOp: {idleConnections: true}}, {$match: {desc: {$eq: "test"}}}];
if (isRemoteShardCurOp) {
assert.docEq(explainPlan.splitPipeline.shardsPart, expectedStages);
diff --git a/jstests/sharding/query/delete_with_partial_shard_key.js b/jstests/sharding/query/delete_with_partial_shard_key.js
deleted file mode 100644
index 8fb85a40900..00000000000
--- a/jstests/sharding/query/delete_with_partial_shard_key.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * Tests that delete queries that are not an exact match on shard key and target only a single shard
- * work.
- */
-
-(function() {
-'use strict';
-
-load('jstests/sharding/libs/with_partial_shard_key_util.js');
-
-const st = new ShardingTest({shards: 2});
-
-// Setup the test by creating two chunks:
-// 1. The first chunk has documents with "a" from [min, 2) and is on shard0.
-// 2. The second chunk has documents with "a" from [2, max) and is on shard1.
-const dbName = "test";
-const coll = "sharded_coll";
-const ns = dbName + "." + coll;
-const db = st.getDB(dbName);
-const docsToInsert = [{a: 1, b: 1}, {a: 2, b: 1}, {a: 3, b: 1}, {a: 999, b: 1}];
-assert.commandWorked(st.s0.adminCommand({enableSharding: dbName}));
-assert.commandWorked(st.s0.adminCommand({shardcollection: ns, key: {a: 1, b: 1}}));
-db.sharded_coll.insert(docsToInsert);
-splitAndMoveChunks(st,
- {a: 2, b: 1} /* split point */,
- {a: 1, b: 1} /* move chunk containing doc to shard0 */,
- {a: 3, b: 1} /* move chunk containing doc to shard1 */);
-
-// deleteOne query without the full shard key and only one shard targeted should succeed.
-assert.eq(db.sharded_coll.count({a: 999}), 1);
-let cmdObj = {delete: coll, deletes: [{q: {a: 999}, limit: 1}]};
-assert.commandWorked(db.runCommand(cmdObj));
-assert.eq(db.sharded_coll.count({a: 999}), 0);
-assertExplainTargetsCorrectShard(db, cmdObj, st.shard1.shardName);
-
-// deleteOne query without the full shard key and multiple shards targeted should fail.
-cmdObj = {
- delete: coll,
- deletes: [{q: {a: {$gt: 0}}, limit: 1}]
-};
-assert.commandFailedWithCode(db.runCommand(cmdObj), ErrorCodes.ShardKeyNotFound);
-assert.commandFailedWithCode(db.runCommand({explain: cmdObj}), ErrorCodes.ShardKeyNotFound);
-
-// deleteOne query without the shard key should fail (as this would requiring targeting more than
-// one shard).
-cmdObj = {
- delete: coll,
- deletes: [{q: {nonShardKey: 12345}, limit: 1}]
-};
-assert.commandFailedWithCode(db.runCommand(cmdObj), ErrorCodes.ShardKeyNotFound);
-assert.commandFailedWithCode(db.runCommand({explain: cmdObj}), ErrorCodes.ShardKeyNotFound);
-
-// deleteMany query that targets only one shard should work correctly.
-assert.eq(db.sharded_coll.count({a: 1}), 1);
-cmdObj = {
- delete: coll,
- deletes: [{q: {a: 1}, limit: 0}]
-};
-assert.commandWorked(db.runCommand(cmdObj));
-assert.eq(db.sharded_coll.count({a: 1}), 0);
-assert.eq(db.sharded_coll.count({a: {$gt: 0}}), 2); // Check that other documents were not deleted.
-assertExplainTargetsCorrectShard(db, cmdObj, st.shard0.shardName);
-
-st.stop();
-})();
diff --git a/jstests/sharding/query/find_and_modify_with_partial_shard_key.js b/jstests/sharding/query/find_and_modify_with_partial_shard_key.js
deleted file mode 100644
index e0a0bb1b3f9..00000000000
--- a/jstests/sharding/query/find_and_modify_with_partial_shard_key.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Tests that findAndModify queries that are not an exact match on shard key and target only a
- * single shard work.
- */
-
-(function() {
-'use strict';
-
-load('jstests/sharding/libs/with_partial_shard_key_util.js');
-
-const st = new ShardingTest({shards: 2});
-
-// Setup the test by creating two chunks:
-// 1. The first chunk has documents with "a" from [min, 2) and is on shard0.
-// 2. The second chunk has documents with "a" from [2, max) and is on shard1.
-const dbName = "test";
-const coll = "sharded_coll";
-const ns = dbName + "." + coll;
-const db = st.getDB(dbName);
-const docsToInsert = [{a: 1, b: 1}, {a: 2, b: 1}, {a: 3, b: 1}, {a: 999, b: 1}];
-assert.commandWorked(st.s0.adminCommand({enableSharding: dbName}));
-assert.commandWorked(st.s0.adminCommand({shardcollection: ns, key: {a: 1, b: 1}}));
-db.sharded_coll.insert(docsToInsert);
-splitAndMoveChunks(st,
- {a: 2, b: 1} /* split point */,
- {a: 1, b: 1} /* move chunk containing doc to shard0 */,
- {a: 3, b: 1} /* move chunk containing doc to shard1 */);
-
-// Query without the full shard key and only one shard targeted should succeed.
-assert.eq(db.sharded_coll.count({a: 1, name: "bob"}), 0);
-let cmdObj = {findAndModify: coll, query: {a: 1}, update: {$set: {name: "bob"}}};
-assert.commandWorked(db.runCommand(cmdObj));
-assert.eq(db.sharded_coll.count({a: 1, name: "bob"}), 1);
-assertExplainTargetsCorrectShard(db, cmdObj, st.shard0.shardName);
-
-// Query without the full shard key and multiple shards targeted should fail.
-cmdObj = {
- findAndModify: coll,
- query: {a: {$gt: 0}},
- update: {$set: {name: "bob"}}
-};
-assert.commandFailedWithCode(db.runCommand(cmdObj), ErrorCodes.ShardKeyNotFound);
-assert.commandFailedWithCode(db.runCommand({explain: cmdObj}), ErrorCodes.ShardKeyNotFound);
-
-// Query without the shard key should fail (as this would requiring targeting more than one shard).
-cmdObj = {
- findAndModify: coll,
- query: {c: "3"},
- update: {$set: {name: "bob"}}
-};
-assert.commandFailedWithCode(db.runCommand(cmdObj), ErrorCodes.ShardKeyNotFound);
-assert.commandFailedWithCode(db.runCommand({explain: cmdObj}), ErrorCodes.ShardKeyNotFound);
-
-st.stop();
-})();
diff --git a/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js b/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
index 1bc05f59555..c3924654a74 100644
--- a/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
+++ b/jstests/sharding/query/lookup_graph_lookup_foreign_becomes_sharded.js
@@ -225,14 +225,14 @@ for (let testCase of testCases) {
const newStaleConfigErrorCount = assert.commandWorked(primaryDB.runCommand({serverStatus: 1}))
.shardingStatistics.countStaleConfigErrors;
-// ... and a single StaleConfig error for the foreign namespace. Note that the 'ns' field of the
+// ... and a single StaleConfig exception for the foreign namespace. Note that the 'ns' field of the
// profiler entry is the source collection in both cases, because the $lookup's parent aggregation
// produces the profiler entry, and it is always running on the source collection.
// TODO SERVER-60018: When the feature flag is removed, remove the check and ensure the results are
// expected.
if (!isShardedLookupEnabled) {
- // Both in the classic lookup and the SBE lookup, StaleConfig error happens. In the classic
- // lookup, profiling can properly report the StaleConfig of the foreign collection.
+ // Both in the classic lookup and the SBE lookup, 'StaleConfig' error happens. In the classic
+ // lookup, profiling can properly report the 'StaleConfig' of the foreign collection.
//
// On the other hand, in the SBE lookup, profiling fails to report the error because the
// profiling level is not set up properly according to the configured profiling level in case of
diff --git a/jstests/sharding/query/lookup_mongod_unaware.js b/jstests/sharding/query/lookup_mongod_unaware.js
index 35cc9d920cb..41e5f23047b 100644
--- a/jstests/sharding/query/lookup_mongod_unaware.js
+++ b/jstests/sharding/query/lookup_mongod_unaware.js
@@ -6,9 +6,8 @@
* We restart a mongod to cause it to forget that a collection was sharded. When restarted, we
* expect it to still have all the previous data.
*
- * // TODO (SERVER-74380): Remove requires_fcv_70 once SERVER-74380 has been backported to v6.0
* @tags: [
- * requires_persistence,
+ * requires_persistence
* ]
*
*/
@@ -19,7 +18,7 @@ load("jstests/noPassthrough/libs/server_parameter_helpers.js"); // For setParam
load("jstests/libs/discover_topology.js"); // For findDataBearingNodes.
// Restarts the primary shard and ensures that it believes both collections are unsharded.
-function restartPrimaryShard(rs, ...expectedCollections) {
+function restartPrimaryShard(rs, localColl, foreignColl) {
// Returns true if the shard is aware that the collection is sharded.
function hasRoutingInfoForNs(shardConn, coll) {
const res = shardConn.adminCommand({getShardVersion: coll, fullMetadata: true});
@@ -29,11 +28,8 @@ function restartPrimaryShard(rs, ...expectedCollections) {
rs.restart(0);
rs.awaitSecondaryNodes();
-
- expectedCollections.forEach(function(coll) {
- assert(!hasRoutingInfoForNs(rs.getPrimary(), coll.getFullName()),
- 'Shard role not cleared for ' + coll.getFullName());
- });
+ assert(!hasRoutingInfoForNs(rs.getPrimary(), localColl.getFullName()));
+ assert(!hasRoutingInfoForNs(rs.getPrimary(), foreignColl.getFullName()));
}
// Disable checking for index consistency to ensure that the config server doesn't trigger a
@@ -174,55 +170,5 @@ assert.eq(mongos0LocalColl.aggregate(pipeline).toArray(), expectedResults);
restartPrimaryShard(st.rs0, mongos0LocalColl, mongos0ForeignColl);
assert.eq(mongos1LocalColl.aggregate(pipeline).toArray(), expectedResults);
-//
-// Test two-level $lookup with a stale shard handles the shard role recovery case.
-//
-jsTest.log("Running two-level $lookup with a shard that needs recovery");
-
-assert.commandWorked(st.s0.adminCommand({enableSharding: 'D'}));
-st.ensurePrimaryShard('D', st.shard0.shardName);
-
-const D = st.s0.getDB('D');
-
-assert.commandWorked(D.A.insert({Key: 1, Value: 1}));
-assert.commandWorked(D.B.insert({Key: 1, Value: 1}));
-assert.commandWorked(D.C.insert({Key: 1, Value: 1}));
-assert.commandWorked(D.D.insert({Key: 1, Value: 1}));
-
-const aggPipeline = [{
- $lookup: {
- from: 'B',
- localField: 'Key',
- foreignField: 'Value',
- as: 'Joined',
- pipeline: [
- {
- $lookup: {
- from: 'C',
- localField: 'Key',
- foreignField: 'Value',
- as: 'Joined',
- }
- },
- {
- $lookup: {
- from: 'D',
- localField: 'Key',
- foreignField: 'Value',
- as: 'Joined',
- }
- },
- ],
- }
-}];
-
-const resultBefore = D.A.aggregate(aggPipeline).toArray();
-
-// Restarting the shard primary in order for the shard role's cache to be cleared
-restartPrimaryShard(st.rs0, D.A, D.B, D.C, D.D);
-
-const resultAfter = D.A.aggregate(aggPipeline).toArray();
-assert.eq(resultBefore, resultAfter, "Before and after results do not match");
-
st.stop();
})();
diff --git a/jstests/sharding/query/merge_nondefault_read_concern.js b/jstests/sharding/query/merge_nondefault_read_concern.js
deleted file mode 100644
index 70df9207bd8..00000000000
--- a/jstests/sharding/query/merge_nondefault_read_concern.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Tests that $merge doesn't fail when a non-default readConcern is
- * set on the session.
- * @tags: [requires_fcv_71]
- */
-(function() {
-"use strict";
-
-load("jstests/aggregation/extras/merge_helpers.js");
-
-const st = new ShardingTest({shards: 2, rs: {nodes: 1}});
-
-const mongosDB = st.s0.getDB("merge_nondefault_read_concern");
-const source = mongosDB["source"];
-const target = mongosDB["target"];
-
-assert.commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()}));
-
-const baseMergeCommand = {
- aggregate: "source",
- pipeline:
- [{$merge: {into: "target", on: "_id", whenMatched: "replace", whenNotMatched: "insert"}}],
- cursor: {},
-};
-
-// Test with command level override.
-var withReadConcern = baseMergeCommand;
-withReadConcern.readConcern = {
- level: "majority"
-};
-assert.commandWorked(mongosDB.runCommand(withReadConcern));
-
-// Test with global override.
-assert.commandWorked(
- mongosDB.adminCommand({"setDefaultRWConcern": 1, "defaultReadConcern": {level: "majority"}}));
-assert.commandWorked(mongosDB.runCommand(baseMergeCommand));
-
-st.stop();
-}());
diff --git a/jstests/sharding/query/merge_write_concern.js b/jstests/sharding/query/merge_write_concern.js
index a29c8b7e6b8..1aac599f0f8 100644
--- a/jstests/sharding/query/merge_write_concern.js
+++ b/jstests/sharding/query/merge_write_concern.js
@@ -17,21 +17,12 @@ assert.commandWorked(mongosDB.adminCommand({enableSharding: mongosDB.getName()})
st.ensurePrimaryShard(mongosDB.getName(), st.shard0.shardName);
function testWriteConcernError(rs) {
- // Split the target collection at {_id: 10} so that there'll be doc $merge-ed to both shards.
- if (FixtureHelpers.isSharded(target)) {
- mongosDB.adminCommand({split: target.getFullName(), middle: {_id: 10}});
- }
-
// Make sure that there are only 2 nodes up so w:3 writes will always time out.
const stoppedSecondary = rs.getSecondary();
rs.stop(stoppedSecondary);
// Test that $merge correctly returns a WC error.
withEachMergeMode(({whenMatchedMode, whenNotMatchedMode}) => {
- // When either mode is "fail", a different error rather than WC error is thrown.
- if (whenMatchedMode === "fail" || whenNotMatchedMode === "fail") {
- return;
- }
const res = mongosDB.runCommand({
aggregate: "source",
pipeline: [{
@@ -45,24 +36,13 @@ function testWriteConcernError(rs) {
cursor: {},
});
- jsTestLog("Testing Mode: " + tojson(whenMatchedMode) + tojson(whenNotMatchedMode));
- jsTestLog("Target collection after $merge: " + tojson(target.find().toArray()));
-
- let oplogEntries = shard0.getPrimary()
- .getDB("local")
- .oplog.rs.find({"ns": {$regex: "merge_write_concern.*"}})
- .toArray();
- jsTestLog("Shard0 oplog entries: " + tojson(oplogEntries));
- oplogEntries = shard1.getPrimary()
- .getDB("local")
- .oplog.rs.find({"ns": {$regex: "merge_write_concern.*"}})
- .toArray();
- jsTestLog("Shard1 oplog entries: " + tojson(oplogEntries));
-
// $merge writeConcern errors are handled differently from normal writeConcern
// errors. Rather than returing ok:1 and a WriteConcernError, the entire operation
// fails.
- assert.commandFailedWithCode(res, ErrorCodes.WriteConcernFailed);
+ assert.commandFailedWithCode(res,
+ whenNotMatchedMode == "fail"
+ ? [13113, ErrorCodes.WriteConcernFailed]
+ : ErrorCodes.WriteConcernFailed);
assert.commandWorked(target.remove({}));
});
diff --git a/jstests/sharding/query/metadata_removal.js b/jstests/sharding/query/metadata_removal.js
deleted file mode 100644
index 7caba6433bc..00000000000
--- a/jstests/sharding/query/metadata_removal.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Ensure that metadata fields (and only metadata) are removed before documents are returned to
-// customers. As we can't insert documents with metadata, this test focuses on queries that might
-// inject metadata when communication results to mongos for merging. In addition, we want to ensure
-// that other fields beginning with a '$' are not modified before returning them to customers.
-// @tags: [
-// requires_fcv_60
-// ]
-
-(function() {
-"use strict";
-
-function runTest(coll, keyword) {
- const document = ({_id: 5, x: 1, $set: {$inc: {x: 5}}});
- assert.commandWorked(coll.insert(document));
-
- // Leaves $set intact without shard merging.
- assert.eq([document], coll.find().hint({$natural: 1}).toArray());
- assert.eq([document], coll.find().hint({_id: 1}).toArray());
-
- // Leaves $set intact when shard merging on agg query.
- const docWithY = ({_id: 5, x: 1, $set: {$inc: {x: 5}}, y: 1});
- assert.eq([docWithY], coll.aggregate([{$addFields: {y: 1}}]).toArray());
-
- // Leaves $set intact when shard merging on sort query.
- assert.eq([document], coll.find().sort({_id: 1}).toArray());
-
- // Leaves added fields intact when user adds $ prefixed field in an agg pipeline.
- const docWithDollarY = ({_id: 5, x: 1, $set: {$inc: {x: 5}}, $y: 1});
- assert.eq(
- [docWithDollarY],
- coll.aggregate(
- [{$replaceWith: {$setField: {field: {$literal: "$y"}, input: "$$ROOT", value: 1}}}])
- .toArray());
-}
-
-const st = new ShardingTest({shards: 2});
-try {
- assert.commandWorked(st.s0.adminCommand({enableSharding: 'test'}));
- st.ensurePrimaryShard('test', st.shard1.shardName);
- assert.commandWorked(st.s0.adminCommand({shardCollection: 'test.coll', key: {x: 'hashed'}}));
-
- runTest(st.getDB("test").coll);
-} finally {
- st.stop();
-}
-})();
diff --git a/jstests/sharding/query/shard_refuses_cursor_ownership.js b/jstests/sharding/query/shard_refuses_cursor_ownership.js
deleted file mode 100644
index 30e6e88d896..00000000000
--- a/jstests/sharding/query/shard_refuses_cursor_ownership.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * This test runs and unsharded $out query which results in mongos setting up a cursor and giving
- * it to a shard to complete. mongos assumes the shard will kill the cursor, but if a shard doesn't
- * accept ownership of the cursor then previously no one would kill it. this test ensures mongos
- * will kill the cursor if a shard doesn't accept ownership.
- * @tags: [
- * ]
- */
-(function() {
-"use strict";
-
-load("jstests/libs/fail_point_util.js");
-load("jstests/libs/parallel_shell_helpers.js");
-
-const st = new ShardingTest({shards: 2});
-
-const dbName = jsTestName();
-const collName = "foo";
-const ns = dbName + "." + collName;
-
-let db = st.s.getDB(dbName);
-assert.commandWorked(db.dropDatabase());
-let coll = db[collName];
-
-st.shardColl(collName, {x: 1}, {x: 0}, {x: 1}, dbName, true);
-
-assert.commandWorked(coll.insert([{x: -2}, {x: -1}, {x: 1}, {x: 2}]));
-
-const primary = st.getPrimaryShard(dbName);
-const other = st.getOther(st.getPrimaryShard(dbName));
-
-// Start an aggregation that requires merging on a shard. Let it run until the shard cursors have
-// been established but make it hang right before opening the merge cursor.
-let shardedAggregateHangBeforeDispatchMergingPipelineFP =
- configureFailPoint(st.s, "shardedAggregateHangBeforeDispatchMergingPipeline");
-let awaitAggregationShell = startParallelShell(
- funWithArgs((dbName, collName) => {
- assert.eq(
- 0, db.getSiblingDB(dbName)[collName].aggregate([{$out: collName + ".out"}]).itcount());
- }, dbName, collName), st.s.port);
-shardedAggregateHangBeforeDispatchMergingPipelineFP.wait();
-
-// Start a chunk migration, let it run until it enters the critical section.
-let hangBeforePostMigrationCommitRefresh =
- configureFailPoint(primary, "hangBeforePostMigrationCommitRefresh");
-let awaitMoveChunkShell = startParallelShell(
- funWithArgs((recipientShard, ns) => {
- assert.commandWorked(db.adminCommand({moveChunk: ns, find: {x: -1}, to: recipientShard}));
- }, other.shardName, ns), st.s.port);
-hangBeforePostMigrationCommitRefresh.wait();
-
-// Let the aggregation continue and try to establish the merge cursor (it will first fail because
-// the shard is in the critical section. Mongos will transparently retry).
-shardedAggregateHangBeforeDispatchMergingPipelineFP.off();
-
-// Let the migration exit the critical section and complete.
-hangBeforePostMigrationCommitRefresh.off();
-
-// The aggregation will be able to complete now.
-awaitAggregationShell();
-
-awaitMoveChunkShell();
-
-// Did any cursor leak?
-const idleCursors = primary.getDB("admin")
- .aggregate([
- {$currentOp: {idleCursors: true, allUsers: true}},
- {$match: {type: "idleCursor", ns: ns}}
- ])
- .toArray();
-assert.eq(0, idleCursors.length, "Found idle cursors: " + tojson(idleCursors));
-
-// Check that range deletions can be completed (if a cursor was left open, the range deletion would
-// not finish).
-assert.soon(
- () => {
- return primary.getDB("config")["rangeDeletions"].find().itcount() === 0;
- },
- "Range deletion tasks did not finish: + " +
- tojson(primary.getDB("config")["rangeDeletions"].find().toArray()));
-
-st.stop();
-})();