diff --git a/jstests/sharding/test_find_classical_with_concurrent_drop.js b/jstests/sharding/test_find_classical_with_concurrent_drop.js new file mode 100644 index 00000000000..5b7c9aea98e --- /dev/null +++ b/jstests/sharding/test_find_classical_with_concurrent_drop.js @@ -0,0 +1,33 @@ + +(function() { +"use strict"; + +load('jstests/libs/fail_point_util.js'); +const st = new ShardingTest({mongos: 2, shards: 1, config: 1}); +st.rs0.getPrimary().adminCommand( + {setParameter: 1, internalQueryFrameworkControl: "forceClassicEngine"}); +st.s0.adminCommand({shardCollection: 'foo.test', key: {x: 1}, timeseries: {timeField: 'x'}}); + +let fp = configureFailPoint(st.rs0.getPrimary(), 'findWaitForDrop'); +let findThread = new Thread((mongosConnString) => { + let mongo = new Mongo(mongosConnString); + assert.commandWorked( + mongo.getDB('foo').runCommand({find: 'test', filter: {$where: 'this.x == 1'}})); +}, st.s1.host); +findThread.start(); +fp.wait(); + +let dropAndCreateThread = new Thread((mongosConnString) => { + let mongo = new Mongo(mongosConnString); + assert.commandWorked(mongo.getDB('foo').runCommand({drop: 'test'})); + assert.commandWorked(mongo.adminCommand({shardCollection: 'foo.test', key: {x: 1}})); +}, st.s1.host); +dropAndCreateThread.start(); +dropAndCreateThread.join(); + +fp.off(); + +findThread.join(); + +st.stop(); +})(); \ No newline at end of file diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index ef710cd11fc..3d731533d14 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -143,6 +143,8 @@ CounterMetric notPrimaryUnackWrites("repl.network.notPrimaryUnacknowledgedWrites namespace { +MONGO_FAIL_POINT_DEFINE(findWaitForDrop); + using namespace fmt::literals; Future runCommandInvocation(std::shared_ptr rec, @@ -1801,6 +1803,14 @@ void ExecCommandDatabase::_initiateCommand() { OperationShardingState::setShardRole( opCtx, namespaceForSharding, shardVersion, databaseVersion); } + + // Failpoint added for testing purposes: the current protocol is not correct for concurrent + // drop/create after this point. + if (request.getCommandName() == "find" && + (invocationNss == NamespaceString("foo.test") || + invocationNss == NamespaceString("foo.test").makeTimeseriesBucketsNamespace())) { + findWaitForDrop.pauseWhileSet(); + } } _scoped = _execContext->behaviors->scopedOperationCompletionShardingActions(opCtx);