summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Pasette <dan@10gen.com>2015-09-16 19:52:06 -0400
committerDan Pasette <dan@mongodb.com>2015-09-22 12:23:43 -0400
commit895db3539016bc9c0bba76c2505c7878a1fbb9ff (patch)
tree6494cdb487b1bafebfd37a09bb6b4e48a8efd264
parent4119b212084ada7f544526f07cbf9352e7d5c910 (diff)
downloadmongo-895db3539016bc9c0bba76c2505c7878a1fbb9ff.tar.gz
SERVER-17425 Disallow creation of v0 indexes
-rw-r--r--jstests/core/create_indexes.js22
-rw-r--r--jstests/core/index7.js15
-rwxr-xr-xjstests/dur/dur1.js2
-rwxr-xr-xjstests/dur/dur1_tool.js2
-rwxr-xr-xjstests/dur/manyRestart.js2
-rw-r--r--jstests/mmap_v1/compact2.js52
-rw-r--r--jstests/mmap_v1/dumprestore6.js50
-rw-r--r--jstests/noPassthroughWithMongod/index_check10.js15
-rw-r--r--jstests/replsets/initSyncV1Index.js52
-rw-r--r--jstests/tool/dumprestore6.js26
-rw-r--r--src/mongo/db/commands/create_indexes.cpp10
-rw-r--r--src/mongo/db/db.cpp9
12 files changed, 58 insertions, 199 deletions
diff --git a/jstests/core/create_indexes.js b/jstests/core/create_indexes.js
index 9669daf6205..ef11187f76a 100644
--- a/jstests/core/create_indexes.js
+++ b/jstests/core/create_indexes.js
@@ -126,20 +126,12 @@
assert.eq( 6, t.getIndexes().length );
- //
- // Test that v0 indexes can only be created with mmapv1
- //
- res = t.runCommand('createIndexes',
- {indexes: [{key: {d: 1}, name: 'd_1', v: 0}]});
-
- if (!isMongos) {
- var status = db.serverStatus();
- assert.commandWorked(status);
- if (status.storageEngine.name === 'mmapv1') {
- assert.commandWorked(res, 'v0 index creation should work for mmapv1');
- } else {
- assert.commandFailed(res, 'v0 index creation should fail for non-mmapv1 storage engines');
- }
- }
+ // Test that v0 indexes cannot be created.
+ res = t.runCommand('createIndexes', {indexes: [{key: {d: 1}, name: 'd_1', v: 0}]});
+ assert.commandFailed(res, 'v0 index creation should fail');
+
+ // Test that v1 indexes can be created explicitly.
+ res = t.runCommand('createIndexes', {indexes: [{key: {d: 1}, name: 'd_1', v: 1}]});
+ assert.commandWorked(res, 'v1 index creation should succeed');
}());
diff --git a/jstests/core/index7.js b/jstests/core/index7.js
deleted file mode 100644
index bd7c75b8b08..00000000000
--- a/jstests/core/index7.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Check that v0 keys are generated for v0 indexes SERVER-3375
-
-t = db.jstests_indexw;
-t.drop();
-
-t.save( {a:[]} );
-assert.eq( 1, t.count( {a:[]} ) );
-t.ensureIndex( {a:1} );
-assert.eq( 1, t.count( {a:[]} ) );
-t.dropIndexes();
-
-// The count result is incorrect - just checking here that v0 key generation is used.
-t.ensureIndex( {a:1}, {v:0} );
-// QUERY_MIGRATION: WE GET THIS RIGHT...BY CHANCE?
-// assert.eq( 0, t.count( {a:[]} ) );
diff --git a/jstests/dur/dur1.js b/jstests/dur/dur1.js
index 4668b4921e2..a4cf88cf22e 100755
--- a/jstests/dur/dur1.js
+++ b/jstests/dur/dur1.js
@@ -62,7 +62,7 @@ function work() {
d.a.update({ _id: 4 }, { $inc: { x: 1} });
// try building an index. however, be careful as object id's in system.indexes would vary, so we do it manually:
- d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1", v: 0 });
+ d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1" });
log("endwork");
return d;
diff --git a/jstests/dur/dur1_tool.js b/jstests/dur/dur1_tool.js
index f86e643b6f7..f0c2916012d 100755
--- a/jstests/dur/dur1_tool.js
+++ b/jstests/dur/dur1_tool.js
@@ -62,7 +62,7 @@ function work() {
d.a.update({ _id: 4 }, { $inc: { x: 1} });
// try building an index. however, be careful as object id's in system.indexes would vary, so we do it manually:
- d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1", v: 0 });
+ d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1" });
log("endwork");
return d;
}
diff --git a/jstests/dur/manyRestart.js b/jstests/dur/manyRestart.js
index d2e864a708b..fe48de9beec 100755
--- a/jstests/dur/manyRestart.js
+++ b/jstests/dur/manyRestart.js
@@ -62,7 +62,7 @@ function work() {
d.a.update({ _id: 4 }, { $inc: { x: 1} });
// try building an index. however, be careful as object id's in system.indexes would vary, so we do it manually:
- d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1", v: 0 });
+ d.system.indexes.insert({ _id: 99, ns: "test.a", key: { x: 1 }, name: "x_1" });
log("endwork");
return d;
}
diff --git a/jstests/mmap_v1/compact2.js b/jstests/mmap_v1/compact2.js
deleted file mode 100644
index 0a7c343a3f9..00000000000
--- a/jstests/mmap_v1/compact2.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Compaction of a v0 index converts it to a v1 index using a v1 index comparator during external
-// sort. SERVER-6499
-
-t = db.jstests_compact2;
-t.drop();
-
-/**
- * Assert that the index is of the expected version and its keys are ordered consistently with this
- * version, and that the unique and background fields are set correctly.
- */
-function assertIndex( expectedVersion, unique, background ) {
- indexSpec = db.system.indexes.findOne( { ns:t.toString(), key:{ date:1 } } );
- // The index version is as expected.
- assert.eq( expectedVersion, indexSpec.v );
- // The index uniqueness is as expected (treat missing and false unique specs as equivalent).
- assert.eq( !unique, !indexSpec.unique );
- // Background is as expected.
- assert.eq( !background, !indexSpec.background );
- // Check that 'date' key ordering is consistent with the index version.
- dates = t.find().hint( { date:1 } ).toArray().map( function( x ) { return x.date; } );
- if ( expectedVersion == 0 ) {
- // Under v0 index comparison, new Date( -1 ) > new Date( 1 ).
- assert.eq( [ new Date( 1 ), new Date( -1 ) ], dates );
- }
- else {
- // Under v1 index comparsion, new Date( -1 ) < new Date( 1 ).
- assert.eq( [ new Date( -1 ), new Date( 1 ) ], dates );
- }
-}
-
-/** Compact a collection and check the resulting indexes. */
-function checkCompact( originalVersion, unique, background ) {
- t.drop();
- t.save( { date:new Date( 1 ) } );
- t.save( { date:new Date( -1 ) } );
- t.ensureIndex( { date:1 }, { unique:unique, v:originalVersion, background:background } );
- assertIndex( originalVersion, unique, background );
-
- // Under SERVER-6499, compact fails when a v0 index is converted to a v1 index and key
- // comparisons are inconsistent, as with the date values in this test.
- assert.commandWorked( t.runCommand( "compact" ) );
- assert( !db.getLastError() );
-
- // Compact built an index with the default index version (v1). Uniqueness is maintained, but
- // background always becomes false.
- assertIndex( 1, unique, false );
-}
-
-checkCompact( 0, true, true );
-checkCompact( 0, false, false );
-checkCompact( 1, true, false );
-checkCompact( 1, false, true );
diff --git a/jstests/mmap_v1/dumprestore6.js b/jstests/mmap_v1/dumprestore6.js
deleted file mode 100644
index 471a63cf150..00000000000
--- a/jstests/mmap_v1/dumprestore6.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// dumprestore6.js
-// Test restoring from a dump with an old index version
-
-
-t = new ToolTest( "dumprestore6" );
-
-c = t.startDB( "foo" );
-db = t.db
-assert.eq( 0 , c.count() , "setup1" );
-
-t.runTool("restore", "--dir", "jstests/tool/data/dumprestore6", "--db", "jstests_tool_dumprestore6")
-
-assert.soon( "c.findOne()" , "no data after sleep" );
-assert.eq( 1 , c.count() , "after restore" );
-
-var indexes = c.getIndexes();
-assert.eq( 2, indexes.length, "there aren't the correct number of indexes" );
-var aIndex = null;
-indexes.forEach(function(index) {
- if (index.name === "a_1") {
- aIndex = index;
- }
-});
-assert.neq(null, aIndex, "index doesn't exist" );
-assert.eq( 1 , aIndex.v, "index version wasn't updated");
-
-assert.eq( 1, c.count({v:0}), "dropped the 'v' field from a non-index collection")
-
-db.dropDatabase()
-assert.eq( 0 , c.count() , "after drop" );
-
-t.runTool("restore", "--dir", "jstests/tool/data/dumprestore6", "--db", "jstests_tool_dumprestore6", "--keepIndexVersion")
-
-assert.soon( "c.findOne()" , "no data after sleep2" );
-assert.eq( 1 , c.count() , "after restore2" );
-
-indexes = c.getIndexes();
-assert.eq( 2, indexes.length, "there aren't the correct number of indexes" );
-aIndex = null;
-indexes.forEach(function(index) {
- if (index.name === "a_1") {
- aIndex = index;
- }
-});
-assert.neq(null, aIndex, "index doesn't exist" );
-assert.eq( 0 , aIndex.v, "index version wasn't maintained")
-
-assert.eq( 1, c.count({v:0}), "dropped the 'v' field from a non-index collection")
-
-t.stop();
diff --git a/jstests/noPassthroughWithMongod/index_check10.js b/jstests/noPassthroughWithMongod/index_check10.js
index 5ace6951652..dd88e094cf2 100644
--- a/jstests/noPassthroughWithMongod/index_check10.js
+++ b/jstests/noPassthroughWithMongod/index_check10.js
@@ -5,7 +5,7 @@ Random.setRandomSeed();
t = db.test_index_check10;
-function doIt( indexVersion ) {
+function doIt() {
t.drop();
@@ -95,9 +95,8 @@ function doIt( indexVersion ) {
size -= f.length;
}
- var max = indexVersion == 0 ? 819 : 818;
-
- if ( size <= max /* KeyMax */ ) {
+ var max = 818; // KeyMax
+ if ( size <= max ) {
assert.eq( c1, c3 , "size: " + size );
}
}
@@ -110,7 +109,7 @@ function doIt( indexVersion ) {
}
assert.writeOK(bulk.execute());
- t.ensureIndex( idx , { v : indexVersion } );
+ t.ensureIndex( idx );
check();
bulk = t.initializeUnorderedBulkOp();
@@ -133,9 +132,5 @@ function doIt( indexVersion ) {
}
for( var z = 0; z < 5; ++z ) {
- var indexVersion = z % 2;
- var storageEngine = jsTest.options().storageEngine;
- if (storageEngine === 'mmapv1' || indexVersion !== 0) {
- doIt(indexVersion);
- }
+ doIt();
}
diff --git a/jstests/replsets/initSyncV1Index.js b/jstests/replsets/initSyncV1Index.js
deleted file mode 100644
index 10b91949942..00000000000
--- a/jstests/replsets/initSyncV1Index.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Create {v:0} index on primary. Add new secondary.
-// Make sure same index on secondary is {v:1} - SERVER-3852
-// Run only if storage engine is mmapv1 - SERVER-16893
-
-(function() {
- 'use strict';
-
- var storageEngine = jsTest.options().storageEngine;
- if (storageEngine !== 'mmapv1') {
- return;
- }
-
- var rs = new ReplSetTest( {name: 'rs', nodes: 1, host: 'localhost'} );
- rs.startSet();
- rs.initiate();
- var r1 = rs.getMaster();
- var db1 = r1.getDB('test');
-
- var t = '';
- for (var i = 0; i < 1000; i++) t += 'a';
- for (var i = 0; i < 10000; i++) db1.foo.insert( {_id:i, x:i%1000, t:t} );
-
- db1.foo.createIndex({x: 1}, {v: 0});
-
- var r2 = rs.add();
- rs.reInitiate(60000);
-
- var db2 = r2.getDB('test');
- r2.setSlaveOk();
- rs.awaitSecondaryNodes();
- rs.awaitReplication();
- var idxes = db2.foo.getIndexes();
- assert.gt(idxes.length, 0, "Secondary reported no indexes on collection " + db2.foo);
- var idx = idxes.filter(function(idx) {
- return friendlyEqual(idx.key, {x: 1});
- })[0];
- assert(idx, "expected to find an index with key {x: 1} on the secondary's collection " + db2.foo);
- assert.eq (idx.v, 1,
- 'expected all indexes generated on Mongo version >= 2.0 to be {v:1}. See SERVER-3852');
-
- // add another new node, make sure ports _aren't_ closed SERVER-4315
- r1 = rs.getMaster();
- rs.add();
- var c = r1.getDB("local").system.replset.findOne();
- var config = rs.getReplSetConfig();
- config.version = c.version+1;
- var result = r1.getDB("admin").runCommand({replSetReconfig:config});
- assert.eq(result.ok, 1);
-
- rs.stopSet(15);
-
-})();
diff --git a/jstests/tool/dumprestore6.js b/jstests/tool/dumprestore6.js
new file mode 100644
index 00000000000..e342e71f3f1
--- /dev/null
+++ b/jstests/tool/dumprestore6.js
@@ -0,0 +1,26 @@
+// Test restoring from a dump with v:0 indexes.
+// mongodump strips the 'v' property from the index specification by default. When using
+// --keepIndexVersion, the 'v' property is not stripped, but index creation will fail.
+
+var toolTest = new ToolTest( "dumprestore6" );
+var col = toolTest.startDB( "foo" );
+var testDb = toolTest.db;
+assert.eq( 0 , col.count() , "setup1" );
+
+// Normal restore should succeed and convert v:1 index.
+toolTest.runTool("restore", "--dir", "jstests/tool/data/dumprestore6", "--db",
+ "jstests_tool_dumprestore6");
+assert.soon( "col.findOne()" , "no data after sleep" );
+assert.eq( 1 , col.count() , "after restore" );
+var indexes = col.getIndexes();
+assert.eq( 2, indexes.length, "there aren't the correct number of indexes" );
+
+// Try with --keepIndexVersion, should fail to restore v:0 index.
+testDb.dropDatabase();
+assert.eq( 0 , col.count() , "after drop" );
+toolTest.runTool("restore", "--dir", "jstests/tool/data/dumprestore6", "--db",
+ "jstests_tool_dumprestore6", "--keepIndexVersion");
+indexes = col.getIndexes();
+assert.eq( 1, indexes.length, "there aren't the correct number of indexes" );
+
+toolTest.stop();
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 604ddaf7ac8..81552e57377 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -203,10 +203,16 @@ public:
status = checkUniqueIndexConstraints(txn, ns.ns(), spec["key"].Obj());
if (!status.isOK()) {
- appendCommandStatus(result, status);
- return false;
+ return appendCommandStatus(result, status);
}
}
+ if (spec["v"].isNumber() && spec["v"].numberInt() == 0) {
+ return appendCommandStatus(
+ result,
+ Status(ErrorCodes::CannotCreateIndex,
+ str::stream() << "illegal index specification: " << spec << ". "
+ << "The option v:0 cannot be passed explicitly"));
+ }
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index 47c6f207ec9..413515612c3 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -373,6 +373,15 @@ static void repairDatabasesAndCheckVersion() {
<< " For more info see"
<< " http://dochub.mongodb.org/core/index-validation" << startupWarningsLog;
}
+
+ if (index["v"].isNumber() && index["v"].numberInt() == 0) {
+ log() << "WARNING: The collection: '" << coll->ns() << "' with index " << index
+ << " was created with the deprecated v:0 format. This format will not"
+ << " be supported in a future release." << startupWarningsLog;
+ log() << "\t To fix this, you need to rebuild this index."
+ << " For instructions, see http://dochub.mongodb.org/core/rebuild-v0-indexes"
+ << startupWarningsLog;
+ }
}
if (PlanExecutor::IS_EOF != state) {