summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiangyu Yao <xiangyu.yao@mongodb.com>2017-11-27 18:19:40 -0500
committerXiangyu Yao <xiangyu.yao@mongodb.com>2018-09-10 18:08:08 -0400
commite013b606016ead1c82ed7c09cbe3c558d5aaa3b2 (patch)
tree3e21e5353da1536c0209cafc929597bff89dc7ff
parent3339fc9385a6ae9c77d0830e7afdfe033a3a1b53 (diff)
downloadmongo-e013b606016ead1c82ed7c09cbe3c558d5aaa3b2.tar.gz
SERVER-25175 listIndexes command only includes ready indexes
(cherry picked from commit 2cc9396586e771a0484a4017bf3f126098818d2b)
-rw-r--r--jstests/noPassthrough/indexbg1.js3
-rw-r--r--jstests/noPassthrough/libs/index_build.js13
-rw-r--r--jstests/noPassthrough/list_indexes_only_ready_indexes.js51
-rw-r--r--jstests/noPassthroughWithMongod/indexbg_drop.js8
-rw-r--r--src/mongo/db/catalog/collection_catalog_entry.h2
-rw-r--r--src/mongo/db/commands/list_indexes.cpp2
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.cpp10
-rw-r--r--src/mongo/db/storage/bson_collection_catalog_entry.h2
-rw-r--r--src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp13
-rw-r--r--src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h2
10 files changed, 96 insertions, 10 deletions
diff --git a/jstests/noPassthrough/indexbg1.js b/jstests/noPassthrough/indexbg1.js
index 00670f3f2db..5d8e4a72847 100644
--- a/jstests/noPassthrough/indexbg1.js
+++ b/jstests/noPassthrough/indexbg1.js
@@ -1,6 +1,7 @@
// Test background index creation
load("jstests/libs/slow_weekly_util.js");
+load("jstests/noPassthrough/libs/index_build.js");
var testServer = new SlowWeeklyMongod("indexbg1");
var db = testServer.getDB("test");
@@ -56,7 +57,7 @@ while (1) { // if indexing finishes before we can run checks, try indexing w/ m
// wait for indexing to start
print("wait for indexing to start");
assert.soon(function() {
- return 2 === t.getIndexes().length;
+ return getIndexBuildOpId(db) != -1;
}, "no index created", 30000, 50);
print("started.");
sleep(1000); // there is a race between when the index build shows up in curop and
diff --git a/jstests/noPassthrough/libs/index_build.js b/jstests/noPassthrough/libs/index_build.js
new file mode 100644
index 00000000000..e3564db5c41
--- /dev/null
+++ b/jstests/noPassthrough/libs/index_build.js
@@ -0,0 +1,13 @@
+// Returns the op id for the running index build, or -1 if there is no current index build.
+function getIndexBuildOpId(db) {
+ const result = db.currentOp();
+ assert.commandWorked(result);
+ let indexBuildOpId = -1;
+
+ result.inprog.forEach(function(op) {
+ if (op.op == 'command' && op.query != undefined && 'createIndexes' in op.query) {
+ indexBuildOpId = op.opid;
+ }
+ });
+ return indexBuildOpId;
+}
diff --git a/jstests/noPassthrough/list_indexes_only_ready_indexes.js b/jstests/noPassthrough/list_indexes_only_ready_indexes.js
new file mode 100644
index 00000000000..c1748792675
--- /dev/null
+++ b/jstests/noPassthrough/list_indexes_only_ready_indexes.js
@@ -0,0 +1,51 @@
+// SERVER-25175: Test the listIndexes command only shows ready indexes.
+(function() {
+ "use strict";
+
+ load("jstests/noPassthrough/libs/index_build.js");
+
+ const conn = MongoRunner.runMongod({smallfiles: "", nojournal: ""});
+ assert.neq(null, conn, "mongod was unable to start up");
+
+ const testDB = conn.getDB("test");
+ assert.commandWorked(testDB.dropDatabase());
+
+ function assertIndexes(coll, numIndexes, indexes) {
+ let res = coll.runCommand("listIndexes");
+ assert.eq(numIndexes, res.cursor.firstBatch.length);
+ for (var i = 0; i < numIndexes; i++) {
+ assert.eq(indexes[i], res.cursor.firstBatch[i].name);
+ }
+ }
+
+ let coll = testDB.list_indexes_only_ready_indexes;
+ coll.drop();
+ assert.commandWorked(testDB.createCollection(coll.getName()));
+ assertIndexes(coll, 1, ["_id_"]);
+ assert.commandWorked(coll.createIndex({a: 1}));
+ assertIndexes(coll, 2, ["_id_", "a_1"]);
+
+ assert.commandWorked(
+ testDB.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'alwaysOn'}));
+ const createIdx = startParallelShell(
+ "let coll = db.getSiblingDB('test').list_indexes_only_ready_indexes;" +
+ "assert.commandWorked(coll.createIndex({ b: 1 }, { background: true }));",
+ conn.port);
+ assert.soon(function() {
+ return getIndexBuildOpId(testDB) != -1;
+ }, "Index build operation not found after starting via parallelShell");
+
+ // Verify there is no third index.
+ assertIndexes(coll, 2, ["_id_", "a_1"]);
+
+ assert.commandWorked(
+ testDB.adminCommand({configureFailPoint: 'hangAfterStartingIndexBuild', mode: 'off'}));
+ // Wait for the index build to stop.
+ assert.soon(function() {
+ return getIndexBuildOpId(testDB) == -1;
+ });
+ const exitCode = createIdx();
+ assert.eq(0, exitCode, 'expected shell to exit cleanly');
+
+ assertIndexes(coll, 3, ["_id_", "a_1", "b_1"]);
+}());
diff --git a/jstests/noPassthroughWithMongod/indexbg_drop.js b/jstests/noPassthroughWithMongod/indexbg_drop.js
index 1f4e1c1be64..244d0cca9c7 100644
--- a/jstests/noPassthroughWithMongod/indexbg_drop.js
+++ b/jstests/noPassthroughWithMongod/indexbg_drop.js
@@ -56,14 +56,6 @@ jsTest.log("Starting background indexing for test of: " + tojson(dc));
masterDB.getCollection(collection).ensureIndex({b: 1});
masterDB.getCollection(collection).ensureIndex({i: 1}, {background: true});
-assert.eq(3, masterDB.getCollection(collection).getIndexes().length);
-
-// Wait for the secondary to get the index entry
-assert.soon(function() {
- return 3 == secondDB.getCollection(collection).getIndexes().length;
-}, "index not created on secondary (prior to drop)", 240000);
-
-jsTest.log("Index created and index entry exists on secondary");
// make sure the index build has started on secondary
assert.soon(function() {
diff --git a/src/mongo/db/catalog/collection_catalog_entry.h b/src/mongo/db/catalog/collection_catalog_entry.h
index dd6a1f506f1..38e5b12d234 100644
--- a/src/mongo/db/catalog/collection_catalog_entry.h
+++ b/src/mongo/db/catalog/collection_catalog_entry.h
@@ -64,6 +64,8 @@ public:
virtual BSONObj getIndexSpec(OperationContext* txn, StringData idxName) const = 0;
+ virtual void getReadyIndexes(OperationContext* txn, std::vector<std::string>* names) const = 0;
+
/**
* Returns true if the index identified by 'indexName' is multikey, and returns false otherwise.
*
diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp
index 1a581074d55..5e8e47a7dfd 100644
--- a/src/mongo/db/commands/list_indexes.cpp
+++ b/src/mongo/db/commands/list_indexes.cpp
@@ -152,7 +152,7 @@ public:
vector<string> indexNames;
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
indexNames.clear();
- cce->getAllIndexes(txn, &indexNames);
+ cce->getReadyIndexes(txn, &indexNames);
}
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "listIndexes", ns.ns());
diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.cpp b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
index 7837e898b56..f0e5589a946 100644
--- a/src/mongo/db/storage/bson_collection_catalog_entry.cpp
+++ b/src/mongo/db/storage/bson_collection_catalog_entry.cpp
@@ -143,6 +143,16 @@ void BSONCollectionCatalogEntry::getAllIndexes(OperationContext* txn,
}
}
+void BSONCollectionCatalogEntry::getReadyIndexes(OperationContext* txn,
+ std::vector<std::string>* names) const {
+ MetaData md = _getMetaData(txn);
+
+ for (unsigned i = 0; i < md.indexes.size(); i++) {
+ if (md.indexes[i].ready)
+ names->push_back(md.indexes[i].spec["name"].String());
+ }
+}
+
bool BSONCollectionCatalogEntry::isIndexMultikey(OperationContext* txn,
StringData indexName,
MultikeyPaths* multikeyPaths) const {
diff --git a/src/mongo/db/storage/bson_collection_catalog_entry.h b/src/mongo/db/storage/bson_collection_catalog_entry.h
index 83c2238fc17..c42908f5f8c 100644
--- a/src/mongo/db/storage/bson_collection_catalog_entry.h
+++ b/src/mongo/db/storage/bson_collection_catalog_entry.h
@@ -58,6 +58,8 @@ public:
virtual void getAllIndexes(OperationContext* txn, std::vector<std::string>* names) const;
+ virtual void getReadyIndexes(OperationContext* txn, std::vector<std::string>* names) const;
+
virtual bool isIndexMultikey(OperationContext* txn,
StringData indexName,
MultikeyPaths* multikeyPaths) const;
diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
index a2421962853..abf43946697 100644
--- a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
+++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp
@@ -106,6 +106,19 @@ void NamespaceDetailsCollectionCatalogEntry::getAllIndexes(OperationContext* txn
}
}
+void NamespaceDetailsCollectionCatalogEntry::getReadyIndexes(
+ OperationContext* txn, std::vector<std::string>* names) const {
+ NamespaceDetails::IndexIterator i = _details->ii(true);
+ while (i.more()) {
+ const IndexDetails& id = i.next();
+ const BSONObj obj = _indexRecordStore->dataFor(txn, id.info.toRecordId()).toBson();
+ const char* idxName = obj.getStringField("name");
+ if (isIndexReady(txn, StringData(idxName))) {
+ names->push_back(idxName);
+ }
+ }
+}
+
bool NamespaceDetailsCollectionCatalogEntry::isIndexMultikey(OperationContext* txn,
StringData idxName,
MultikeyPaths* multikeyPaths) const {
diff --git a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
index 0f8940be756..8d57825d0c3 100644
--- a/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
+++ b/src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h
@@ -67,6 +67,8 @@ public:
BSONObj getIndexSpec(OperationContext* txn, StringData idxName) const final;
+ void getReadyIndexes(OperationContext* txn, std::vector<std::string>* names) const final;
+
bool isIndexMultikey(OperationContext* txn,
StringData indexName,
MultikeyPaths* multikeyPaths) const final;