summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRandolph Tan <randolph@10gen.com>2014-11-24 17:37:11 -0500
committerRandolph Tan <randolph@10gen.com>2014-11-24 18:01:05 -0500
commit0f7dbe98cd6a4f15eb7a112fbae62383fb3805c6 (patch)
tree3a69145038dff1ddadd70caeecdf45269cd15a91
parenta3ab21753b0dbf20cc98a6085a9c5af4e8af856d (diff)
downloadmongo-0f7dbe98cd6a4f15eb7a112fbae62383fb3805c6.tar.gz
SERVER-12472 Fail MoveChunk if an index is needed on TO shard and data exists
-rw-r--r--jstests/sharding/move_chunk_missing_idx.js36
-rw-r--r--src/mongo/s/d_migrate.cpp14
2 files changed, 50 insertions, 0 deletions
diff --git a/jstests/sharding/move_chunk_missing_idx.js b/jstests/sharding/move_chunk_missing_idx.js
new file mode 100644
index 00000000000..d963f08ae1e
--- /dev/null
+++ b/jstests/sharding/move_chunk_missing_idx.js
@@ -0,0 +1,36 @@
+/**
+ * Test that migration should fail if the destination shard does not
+ * have the index and is not empty.
+ */
+
+var st = new ShardingTest({ shards: 2 });
+
+var testDB = st.s.getDB('test');
+
+testDB.adminCommand({ enableSharding: 'test' });
+testDB.adminCommand({ shardCollection: 'test.user', key: { x: 1 }});
+
+testDB.user.ensureIndex({ a: 1, b: 1 });
+testDB.user.ensureIndex({ z: 'hashed' });
+
+testDB.adminCommand({ split: 'test.user', middle: { x: 0 }});
+testDB.adminCommand({ split: 'test.user', middle: { x: 10 }});
+
+assert.commandWorked(testDB.adminCommand({ moveChunk: 'test.user',
+ find: { x: 0 },
+ to: 'shard0000' }));
+
+st.d0.getDB('test').user.dropIndex({ a: 1, b: 1 });
+
+assert.commandWorked(testDB.adminCommand({ moveChunk: 'test.user',
+ find: { x: 10 },
+ to: 'shard0000' }));
+
+st.d0.getDB('test').user.dropIndex({ a: 1, b: 1 });
+testDB.user.insert({ x: 10 });
+
+assert.commandFailed(testDB.adminCommand({ moveChunk: 'test.user',
+ find: { x: -10 },
+ to: 'shard0000' }));
+
+st.stop();
diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp
index 718bf31aed6..8c9570d3d21 100644
--- a/src/mongo/s/d_migrate.cpp
+++ b/src/mongo/s/d_migrate.cpp
@@ -1682,6 +1682,20 @@ namespace mongo {
return;
}
+ BSONObj idxPattern(idx["key"].Obj());
+ bool hasIndex = collection->getIndexCatalog()->
+ findIndexByKeyPattern(idxPattern, true /* include unfinished */);
+
+ if (collection->numRecords() > 0 && !hasIndex) {
+ errmsg = str::stream() << "aborting migration, shard is missing "
+ << "indexes and collection is not empty. "
+ << "Non-trivial index creation should be "
+ << "scheduled manually";
+ warning() << errmsg;
+ state = FAIL;
+ return;
+ }
+
Status status = collection->getIndexCatalog()->createIndex( idx, false );
if ( !status.isOK() && status.code() != ErrorCodes::IndexAlreadyExists ) {
errmsg = str::stream() << "failed to create index before migrating data. "