summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeert Bosch <geert@mongodb.com>2016-11-22 16:53:05 -0500
committerGeert Bosch <geert@mongodb.com>2017-02-03 09:57:17 -0500
commit459fd0955603607b2d3d8763beacfc4e317aac33 (patch)
treea97a3f41c5cb93a25ef743cd48649777c949c430
parent76c9a2c0cf6bb6d7b63ccbef96e2d31ac36014c7 (diff)
downloadmongo-459fd0955603607b2d3d8763beacfc4e317aac33.tar.gz
SERVER-24963 Fix invalidation of cursors on system.indexes
(cherry picked from commit 647ebfac9ebf1c5fc431a2ba813bf9c97b9bdab9)
-rw-r--r--jstests/core/list_indexes_invalidation.js22
-rw-r--r--jstests/readonly/lib/read_only_test.js2
-rw-r--r--src/mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.cpp12
3 files changed, 35 insertions, 1 deletions
diff --git a/jstests/core/list_indexes_invalidation.js b/jstests/core/list_indexes_invalidation.js
new file mode 100644
index 00000000000..0557cb0e17b
--- /dev/null
+++ b/jstests/core/list_indexes_invalidation.js
@@ -0,0 +1,22 @@
+// SERVER-24963 Missing invalidation for system.indexes write
+(function() {
+ 'use strict';
+ let collName = 'system_indexes_invalidations';
+ let coll = db[collName];
+ coll.drop();
+ assert.commandWorked(coll.createIndexes([{a: 1}, {b: 1}, {c: 1}]));
+
+ // Get the first two indexes. Use find on 'system.indexes' on MMAPv1, listIndexes otherwise.
+ let cmd = db.system.indexes.count() ? {find: 'system.indexes'} : {listIndexes: collName};
+ Object.extend(cmd, {batchSize: 2});
+ let res = db.runCommand(cmd);
+ assert.commandWorked(res, 'could not run ' + tojson(cmd));
+ printjson(res);
+
+ // Ensure the cursor has data, drop the collection, and exhaust the cursor.
+ let cursor = new DBCommandCursor(db.getMongo(), res);
+ let errMsg = 'expected more data from command ' + tojson(cmd) + ', with result ' + tojson(res);
+ assert(cursor.hasNext(), errMsg);
+ assert(coll.drop());
+ assert.gt(cursor.itcount(), 0, errMsg);
+}());
diff --git a/jstests/readonly/lib/read_only_test.js b/jstests/readonly/lib/read_only_test.js
index 99d0a1ced92..5b2775e697a 100644
--- a/jstests/readonly/lib/read_only_test.js
+++ b/jstests/readonly/lib/read_only_test.js
@@ -1,7 +1,7 @@
var StandaloneFixture, ShardedFixture, runReadOnlyTest, zip2, cycleN;
(function() {
- "use_strict";
+ "use strict";
function makeDirectoryReadOnly(dir) {
if (_isWindows()) {
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 94cf75d1fde..7a54f771fa6 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
@@ -32,6 +32,8 @@
#include "mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h"
+#include "mongo/db/catalog/database.h"
+#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/ops/update.h"
#include "mongo/db/record_id.h"
@@ -257,6 +259,16 @@ Status NamespaceDetailsCollectionCatalogEntry::removeIndex(OperationContext* txn
d->idx(getTotalIndexCount(txn)) = IndexDetails();
}
+ // Soneone may be querying the system.indexes namespace directly, so we need to invalidate
+ // its cursors. Having to go back up through the DatabaseHolder is a bit of a layering
+ // violation, but at this point we're not going to add more MMAPv1 specific interfaces.
+ // We can find the name of the database through the first entries of the CollectionMap.
+ StringData dbName(nsToDatabaseSubstring(_db->_collections.begin()->first));
+ invariant(txn->lockState()->isDbLockedForMode(dbName, MODE_X));
+ Database* db = dbHolder().get(txn, dbName);
+ Collection* systemIndexes = db->getCollection(db->getSystemIndexesName());
+ systemIndexes->getCursorManager()->invalidateDocument(txn, infoLocation, INVALIDATION_DELETION);
+
// remove from system.indexes
_indexRecordStore->deleteRecord(txn, infoLocation);