summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Hirschhorn <max.hirschhorn@mongodb.com>2016-11-15 09:57:53 -0500
committerMax Hirschhorn <max.hirschhorn@mongodb.com>2016-11-15 09:57:53 -0500
commit57ed82f0692bfb4e7a045a0108d029e53b21e3f8 (patch)
tree6dbcbe35ea010fad07b554115fb89876f04e9946
parent1ebe71d22dfa865fd451909a666305f581302f5c (diff)
downloadmongo-57ed82f0692bfb4e7a045a0108d029e53b21e3f8.tar.gz
SERVER-24994 Check in Helpers::removeRange() if shard key index dropped.
-rw-r--r--jstests/concurrency/fsm_all.js7
-rw-r--r--jstests/concurrency/fsm_all_composed.js3
-rw-r--r--jstests/concurrency/fsm_all_replication.js3
-rw-r--r--jstests/concurrency/fsm_all_sharded_replication_with_balancer.js5
-rw-r--r--jstests/concurrency/fsm_all_simultaneous.js3
-rw-r--r--jstests/concurrency/fsm_workloads/sharded_moveChunk_drop_shard_key_index.js81
-rw-r--r--src/mongo/db/dbhelpers.cpp6
7 files changed, 107 insertions, 1 deletions
diff --git a/jstests/concurrency/fsm_all.js b/jstests/concurrency/fsm_all.js
index 35031becb89..4c45ac7b99d 100644
--- a/jstests/concurrency/fsm_all.js
+++ b/jstests/concurrency/fsm_all.js
@@ -4,7 +4,12 @@ load('jstests/concurrency/fsm_libs/runner.js');
var dir = 'jstests/concurrency/fsm_workloads';
-var blacklist = [].map(function(file) {
+var blacklist = [
+ // Disabled due to MongoDB restrictions and/or workload restrictions
+
+ // This workload assumes it is running against a sharded cluster.
+ 'sharded_moveChunk_drop_shard_key_index.js',
+].map(function(file) {
return dir + '/' + file;
});
diff --git a/jstests/concurrency/fsm_all_composed.js b/jstests/concurrency/fsm_all_composed.js
index 159ff0919c9..c32b039dd32 100644
--- a/jstests/concurrency/fsm_all_composed.js
+++ b/jstests/concurrency/fsm_all_composed.js
@@ -16,6 +16,9 @@ var blacklist = [
// is slow and the composer doesn't honor iteration counts:
'remove_single_document_eval_nolock.js',
'update_simple_eval_nolock.js',
+
+ // This workload assumes it is running against a sharded cluster.
+ 'sharded_moveChunk_drop_shard_key_index.js',
].map(function(file) {
return dir + '/' + file;
});
diff --git a/jstests/concurrency/fsm_all_replication.js b/jstests/concurrency/fsm_all_replication.js
index 31770af9f80..93be7b7dfe2 100644
--- a/jstests/concurrency/fsm_all_replication.js
+++ b/jstests/concurrency/fsm_all_replication.js
@@ -9,6 +9,9 @@ var blacklist = [
'agg_group_external.js', // uses >100MB of data, which can overwhelm test hosts
'agg_sort_external.js', // uses >100MB of data, which can overwhelm test hosts
'findAndModify_update_grow.js', // can cause OOM kills on test hosts
+
+ // This workload assumes it is running against a sharded cluster.
+ 'sharded_moveChunk_drop_shard_key_index.js',
].map(function(file) {
return dir + '/' + file;
});
diff --git a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
index 54ebfabfc05..bc10f840949 100644
--- a/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
+++ b/jstests/concurrency/fsm_all_sharded_replication_with_balancer.js
@@ -89,6 +89,11 @@ var blacklist = [
'rename_collection_dbname_droptarget.js',
'rename_collection_droptarget.js',
+ // This workload assumes that the distributed lock can always be acquired when running the split
+ // command in its setup() function; however, a LockBusy error may be returned if the balancer is
+ // running.
+ 'sharded_moveChunk_drop_shard_key_index.js',
+
'update_simple_eval.js', // eval doesn't work with sharded collections
'update_simple_eval_nolock.js', // eval doesn't work with sharded collections
'update_upsert_multi.js', // our update queries lack shard keys
diff --git a/jstests/concurrency/fsm_all_simultaneous.js b/jstests/concurrency/fsm_all_simultaneous.js
index bf4fdfe3d02..237369bfe7b 100644
--- a/jstests/concurrency/fsm_all_simultaneous.js
+++ b/jstests/concurrency/fsm_all_simultaneous.js
@@ -14,6 +14,9 @@ var blacklist = [
'agg_group_external.js', // uses >100MB of data, which can overwhelm test hosts
'agg_sort_external.js', // uses >100MB of data, which can overwhelm test hosts
+
+ // This workload assumes it is running against a sharded cluster.
+ 'sharded_moveChunk_drop_shard_key_index.js',
].map(function(file) {
return dir + '/' + file;
});
diff --git a/jstests/concurrency/fsm_workloads/sharded_moveChunk_drop_shard_key_index.js b/jstests/concurrency/fsm_workloads/sharded_moveChunk_drop_shard_key_index.js
new file mode 100644
index 00000000000..d38bdbd3399
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/sharded_moveChunk_drop_shard_key_index.js
@@ -0,0 +1,81 @@
+'use strict';
+
+/**
+ * sharded_moveChunk_drop_shard_key_index.js
+ *
+ * Tests that dropping the shard key index while migrating a chunk doesn't cause the shard to abort.
+ *
+ * This workload was designed to reproduce SERVER-24994.
+ */
+
+var $config = (function() {
+
+ var data = {numSplitPoints: 100, shardKey: {key: 1}};
+
+ var states = {
+
+ init: function init(db, collName) {
+ // No-op
+ },
+
+ moveChunk: function moveChunk(db, collName) {
+ var configDB = db.getSiblingDB('config');
+ var shards = configDB.shards.aggregate([{$sample: {size: 1}}]).toArray();
+ assertAlways.eq(1, shards.length, tojson(shards));
+
+ var shardName = shards[0]._id;
+ var chunkBoundary = Random.randInt(this.numSplitPoints);
+
+ // We don't assert that the command succeeded when migrating a chunk because it's
+ // possible another thread has already started migrating a chunk.
+ db.adminCommand({
+ moveChunk: db[collName].getFullName(),
+ find: {key: chunkBoundary},
+ to: shardName,
+ _waitForDelete: true,
+ });
+ },
+
+ dropIndex: function dropIndex(db, collName) {
+ // We don't assert that the command succeeded when dropping an index because it's
+ // possible another thread has already dropped this index.
+ db[collName].dropIndex(this.shardKey);
+
+ // Re-create the index that was dropped.
+ assertAlways.commandWorked(db[collName].createIndex(this.shardKey));
+ }
+
+ };
+
+ var transitions = {
+ init: {moveChunk: 0.5, dropIndex: 0.5},
+ moveChunk: {moveChunk: 0.5, dropIndex: 0.5},
+ dropIndex: {moveChunk: 0.5, dropIndex: 0.5}
+ };
+
+ function setup(db, collName, cluster) {
+ var bulk = db[collName].initializeUnorderedBulkOp();
+ for (var i = 0; i < this.numSplitPoints; ++i) {
+ bulk.insert({key: i});
+ }
+
+ var res = bulk.execute();
+ assertAlways.writeOK(res);
+ assertAlways.eq(this.numSplitPoints, res.nInserted, tojson(res));
+
+ for (i = 0; i < this.numSplitPoints; ++i) {
+ assertWhenOwnColl.commandWorked(
+ db.adminCommand({split: db[collName].getFullName(), middle: {key: i}}));
+ }
+ }
+
+ return {
+ threadCount: 10,
+ iterations: 100,
+ data: data,
+ states: states,
+ transitions: transitions,
+ setup: setup
+ };
+
+})();
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index 4b441b90bd3..daf2767c908 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -365,6 +365,12 @@ long long Helpers::removeRange(OperationContext* txn,
IndexDescriptor* desc = collection->getIndexCatalog()->findIndexByName(txn, indexName);
+ if (!desc) {
+ warning(LogComponent::kSharding) << "shard key index '" << indexName << "' on '"
+ << ns << "' was dropped";
+ return -1;
+ }
+
unique_ptr<PlanExecutor> exec(
InternalPlanner::indexScan(txn,
collection,