diff options
author | Mathias Stearn <redbeard0531@gmail.com> | 2016-01-15 16:30:52 -0500 |
---|---|---|
committer | Mathias Stearn <redbeard0531@gmail.com> | 2016-01-18 13:33:40 -0500 |
commit | c44a3ecdffd5c98fdd2daa6e46f52c50ff594576 (patch) | |
tree | 4a04d9df845d94beba13abcde6b13a8ab6e0ba6d /src/mongo/db | |
parent | 930e47f1864d0319b7d9033ad2c2bf99f02014c1 (diff) | |
download | mongo-r3.0.9-rc0.tar.gz |
SERVER-19128 Clean up interaction of background index builds and cursor killingr3.0.9-rc0
This reverts commit 90a684ad25a86deff16f80e11e257c6ac6611683, restoring
1d26b77d115eb39f03dffbdbaccf10e696cd4fe3.
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/background.h | 10 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/catalog/cursor_manager.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/database.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_catalog.cpp | 17 | ||||
-rw-r--r-- | src/mongo/db/catalog/index_create.cpp | 14 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 4 |
7 files changed, 40 insertions, 15 deletions
diff --git a/src/mongo/db/background.h b/src/mongo/db/background.h index b5ec4caea70..3a40a286bda 100644 --- a/src/mongo/db/background.h +++ b/src/mongo/db/background.h @@ -64,6 +64,16 @@ public: static void awaitNoBgOpInProgForNs(const StringData& ns); static void dump(std::ostream&); + static bool inProgForNs(const NamespaceString& ns) { + return inProgForNs(ns.ns()); + } + static void assertNoBgOpInProgForNs(const NamespaceString& ns) { + assertNoBgOpInProgForNs(ns.ns()); + } + static void awaitNoBgOpInProgForNs(const NamespaceString& ns) { + awaitNoBgOpInProgForNs(ns.ns()); + } + /* check for in progress before instantiating */ BackgroundOperation(const StringData& ns); diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index 936909a4456..89e58c10021 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -38,6 +38,7 @@ #include "mongo/base/counter.h" #include "mongo/base/owned_pointer_map.h" +#include "mongo/db/background.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands/server_status_metric.h" #include "mongo/db/curop.h" @@ -480,7 +481,8 @@ uint64_t Collection::getIndexSize(OperationContext* opCtx, BSONObjBuilder* detai */ Status Collection::truncate(OperationContext* txn) { dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_X)); - massert(17445, "index build in progress", _indexCatalog.numIndexesInProgress(txn) == 0); + BackgroundOperation::assertNoBgOpInProgForNs(ns()); + invariant(_indexCatalog.numIndexesInProgress(txn) == 0); // 1) store index specs vector<BSONObj> indexSpecs; @@ -517,6 +519,8 @@ Status Collection::truncate(OperationContext* txn) { void Collection::temp_cappedTruncateAfter(OperationContext* txn, RecordId end, bool inclusive) { dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_IX)); invariant(isCapped()); + BackgroundOperation::assertNoBgOpInProgForNs(ns()); + invariant(_indexCatalog.numIndexesInProgress(txn) == 0); _cursorManager.invalidateAll(false); _recordStore->temp_cappedTruncateAfter(txn, end, inclusive); diff --git a/src/mongo/db/catalog/cursor_manager.cpp b/src/mongo/db/catalog/cursor_manager.cpp index 6507b8fd1a5..d192d52ba25 100644 --- a/src/mongo/db/catalog/cursor_manager.cpp +++ b/src/mongo/db/catalog/cursor_manager.cpp @@ -34,6 +34,7 @@ #include "mongo/base/init.h" #include "mongo/db/audit.h" #include "mongo/db/auth/authorization_session.h" +#include "mongo/db/background.h" #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_holder.h" @@ -313,6 +314,7 @@ CursorManager::~CursorManager() { void CursorManager::invalidateAll(bool collectionGoingAway) { SimpleMutex::scoped_lock lk(_mutex); + fassert(28819, !BackgroundOperation::inProgForNs(_nss)); for (ExecSet::iterator it = _nonCachedExecutors.begin(); it != _nonCachedExecutors.end(); ++it) { diff --git a/src/mongo/db/catalog/database.cpp b/src/mongo/db/catalog/database.cpp index 0d6f0e9aef2..652717dddce 100644 --- a/src/mongo/db/catalog/database.cpp +++ b/src/mongo/db/catalog/database.cpp @@ -432,6 +432,8 @@ Status Database::renameCollection(OperationContext* txn, bool stayTemp) { audit::logRenameCollection(currentClient.get(), fromNS, toNS); invariant(txn->lockState()->isDbLockedForMode(name(), MODE_X)); + BackgroundOperation::assertNoBgOpInProgForNs(fromNS); + BackgroundOperation::assertNoBgOpInProgForNs(toNS); { // remove anything cached Collection* coll = getCollection(fromNS); diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp index ceef866f8de..c7752655ee5 100644 --- a/src/mongo/db/catalog/index_catalog.cpp +++ b/src/mongo/db/catalog/index_catalog.cpp @@ -744,15 +744,21 @@ Status IndexCatalog::_dropIndex(OperationContext* txn, IndexCatalogEntry* entry) if (!status.isOK()) return status; - // there may be pointers pointing at keys in the btree(s). kill them. - // TODO: can this can only clear cursors on this index? - _collection->getCursorManager()->invalidateAll(false); - // wipe out stats _collection->infoCache()->reset(txn); - string indexNamespace = entry->descriptor()->indexNamespace(); + // Pulling indexName/indexNamespace out as they are needed post descriptor release. string indexName = entry->descriptor()->indexName(); + string indexNamespace = entry->descriptor()->indexNamespace(); + + // If any cursors could be using this index, invalidate them. Note that we do not use indexes + // until they are ready, so we do not need to invalidate anything if the index fails while it is + // being built. + // TODO only kill cursors that are actually using the index rather than everything on this + // collection. + if (entry->isReady(txn)) { + _collection->getCursorManager()->invalidateAll(false); + } // --------- START REAL WORK ---------- @@ -966,6 +972,7 @@ const IndexCatalogEntry* IndexCatalog::getEntry(const IndexDescriptor* desc) con const IndexDescriptor* IndexCatalog::refreshEntry(OperationContext* txn, const IndexDescriptor* oldDesc) { invariant(txn->lockState()->isCollectionLockedForMode(_collection->ns().ns(), MODE_X)); + invariant(!BackgroundOperation::inProgForNs(_collection->ns())); const std::string indexName = oldDesc->indexName(); invariant(_collection->getCatalogEntry()->isIndexReady(txn, indexName)); diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp index dcf70e5c3a0..3209b6cfbf5 100644 --- a/src/mongo/db/catalog/index_create.cpp +++ b/src/mongo/db/catalog/index_create.cpp @@ -45,6 +45,7 @@ #include "mongo/db/clientcursor.h" #include "mongo/db/concurrency/write_conflict_exception.h" #include "mongo/db/curop.h" +#include "mongo/db/exec/working_set_common.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/replication_coordinator_global.h" @@ -285,15 +286,10 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set<RecordId>* dupsO } } - if (state != PlanExecutor::IS_EOF) { - // If the plan executor was killed, this means the DB/collection was dropped and so it - // is not safe to cleanup the in-progress indexes. - if (state == PlanExecutor::DEAD) { - abortWithoutCleanup(); - } - - uasserted(28550, "Unable to complete index build as the collection is no longer readable"); - } + uassert(28550, + "Unable to complete index build due to collection scan failure: " + + WorkingSetCommon::toStatusString(objToIndex.value()), + state == PlanExecutor::IS_EOF); progress->finished(); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index d59ddbfc132..e83a287631b 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -1079,6 +1079,10 @@ public: Database* const db = autoDb.getDb(); Collection* coll = db ? db->getCollection(ns) : NULL; + // This can kill all cursors so don't allow running it while a background operation is in + // progress. + BackgroundOperation::assertNoBgOpInProgForNs(ns); + // If db/collection does not exist, short circuit and return. if (!db || !coll) { errmsg = "ns does not exist"; |