summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Milkie <milkie@10gen.com>2013-06-05 10:01:30 -0400
committerDan Pasette <dan@10gen.com>2013-06-19 19:05:27 -0400
commitaf0b49cbb0ca6888d6f133081b7d41464bf4135f (patch)
treef1d71805aa3dcfd21148de3935fffc3e7db5dd83
parent9f975ab30ef2f579ea2bbb2bebeadd7abf1d69d2 (diff)
downloadmongo-af0b49cbb0ca6888d6f133081b7d41464bf4135f.tar.gz
SERVER-9856 check in-progress indexes for duplicates in prepareToBuildIndex()
-rw-r--r--jstests/slowNightly/dup_bgindex.js16
-rw-r--r--src/mongo/db/index.cpp7
-rw-r--r--src/mongo/db/namespace_details-inl.h10
-rw-r--r--src/mongo/db/namespace_details.h5
4 files changed, 30 insertions, 8 deletions
diff --git a/jstests/slowNightly/dup_bgindex.js b/jstests/slowNightly/dup_bgindex.js
new file mode 100644
index 00000000000..fbfb8a8a322
--- /dev/null
+++ b/jstests/slowNightly/dup_bgindex.js
@@ -0,0 +1,16 @@
+// Try to create two identical indexes, via background. Shouldn't be allowed by the server.
+// This test runs fairly quickly but cannot be in /jstests/. So it lives in slowNightly for now.
+var t = db.duplIndexTest;
+t.drop();
+for (var i=0; i<10000; i++) {
+ t.insert( { name : "foo" , z : { a : 17 , b : 4}, i: i } );
+}
+var cmd = "db.duplIndexTest.ensureIndex( { i : 1 }, {background:true} );"
+var join1 = startParallelShell(cmd);
+var join2 = startParallelShell(cmd);
+t.ensureIndex( { i : 1 }, {background:true} );
+assert.eq(1, t.find({i:1}).count(), "Should find only one doc");
+t.dropIndex({ i : 1 });
+assert.eq(1, t.find({i:1}).count(), "Should find only one doc");
+join1();
+join2();
diff --git a/src/mongo/db/index.cpp b/src/mongo/db/index.cpp
index 377679806a4..f7346978313 100644
--- a/src/mongo/db/index.cpp
+++ b/src/mongo/db/index.cpp
@@ -369,11 +369,14 @@ namespace mongo {
verify( sourceCollection );
}
- if ( sourceCollection->findIndexByName(name) >= 0 ) {
+ // Check both existing and in-progress indexes (2nd param = true)
+ if ( sourceCollection->findIndexByName(name, true) >= 0 ) {
// index already exists.
return false;
}
- if( sourceCollection->findIndexByKeyPattern(key) >= 0 ) {
+
+ // Check both existing and in-progress indexes (2nd param = true)
+ if( sourceCollection->findIndexByKeyPattern(key, true) >= 0 ) {
LOG(2) << "index already exists with diff name " << name << ' ' << key.toString() << endl;
return false;
}
diff --git a/src/mongo/db/namespace_details-inl.h b/src/mongo/db/namespace_details-inl.h
index 0e64b961ba8..9e8ccbb37e6 100644
--- a/src/mongo/db/namespace_details-inl.h
+++ b/src/mongo/db/namespace_details-inl.h
@@ -56,8 +56,9 @@ namespace mongo {
return -1;
}
- inline int NamespaceDetails::findIndexByKeyPattern(const BSONObj& keyPattern) {
- IndexIterator i = ii();
+ inline int NamespaceDetails::findIndexByKeyPattern(const BSONObj& keyPattern,
+ bool includeBackgroundInProgress) {
+ IndexIterator i = ii(includeBackgroundInProgress);
while( i.more() ) {
if( i.next().keyPattern() == keyPattern )
return i.pos()-1;
@@ -83,8 +84,9 @@ namespace mongo {
}
// @return offset in indexes[]
- inline int NamespaceDetails::findIndexByName(const char *name) {
- IndexIterator i = ii();
+ inline int NamespaceDetails::findIndexByName(const char *name,
+ bool includeBackgroundInProgress) {
+ IndexIterator i = ii(includeBackgroundInProgress);
while( i.more() ) {
if ( strcmp(i.next().info.obj().getStringField("name"),name) == 0 )
return i.pos()-1;
diff --git a/src/mongo/db/namespace_details.h b/src/mongo/db/namespace_details.h
index 28416f4abf0..0e7e324da67 100644
--- a/src/mongo/db/namespace_details.h
+++ b/src/mongo/db/namespace_details.h
@@ -291,10 +291,11 @@ namespace mongo {
}
// @return offset in indexes[]
- int findIndexByName(const char *name);
+ int findIndexByName(const char *name, bool includeBackgroundInProgress = false);
// @return offset in indexes[]
- int findIndexByKeyPattern(const BSONObj& keyPattern);
+ int findIndexByKeyPattern(const BSONObj& keyPattern,
+ bool includeBackgroundInProgress = false);
void findIndexByType( const string& name , vector<int>& matches ) {
IndexIterator i = ii();