diff options
author | Gregory Wlodarek <gregory.wlodarek@mongodb.com> | 2019-10-10 19:51:48 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-10 19:51:48 +0000 |
commit | c4b5fd5f87de0ba8ffeaf86388f244a4a294c504 (patch) | |
tree | 2f71cd574058a86b3f32967cbac87d5fca0363b9 | |
parent | cfcdc9b9b84c3d9afcbb804513bbdbd54b77b7db (diff) | |
download | mongo-c4b5fd5f87de0ba8ffeaf86388f244a4a294c504.tar.gz |
SERVER-43886 Check if the index was dropped after locking the weak_ptr to the IndexCatalogEntry in RequiresIndexStage and RequiresAllIndicesStage
-rw-r--r-- | src/mongo/db/exec/requires_all_indices_stage.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/exec/requires_all_indices_stage.h | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/requires_index_stage.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/exec/requires_index_stage.h | 10 |
4 files changed, 11 insertions, 12 deletions
diff --git a/src/mongo/db/exec/requires_all_indices_stage.cpp b/src/mongo/db/exec/requires_all_indices_stage.cpp index be26a5a0402..f96d4d2fc27 100644 --- a/src/mongo/db/exec/requires_all_indices_stage.cpp +++ b/src/mongo/db/exec/requires_all_indices_stage.cpp @@ -36,9 +36,10 @@ namespace mongo { void RequiresAllIndicesStage::doRestoreStateRequiresCollection() { size_t i = 0; for (auto&& index : _indexCatalogEntries) { + auto indexCatalogEntry = index.lock(); uassert(ErrorCodes::QueryPlanKilled, str::stream() << "query plan killed :: index '" << _indexNames[i] << "' dropped", - index.lock()); + indexCatalogEntry && !indexCatalogEntry->isDropped()); ++i; } } diff --git a/src/mongo/db/exec/requires_all_indices_stage.h b/src/mongo/db/exec/requires_all_indices_stage.h index af70269e38f..68516960f3f 100644 --- a/src/mongo/db/exec/requires_all_indices_stage.h +++ b/src/mongo/db/exec/requires_all_indices_stage.h @@ -71,8 +71,9 @@ protected: private: // This stage holds weak pointers to all of the index catalog entries known at the time of // construction. During yield recovery, we attempt to lock each weak pointer in order to - // determine whether an index we rely on has been destroyed. If any index has been destroyed, - // then we throw a query-fatal exception during restore. + // determine whether an index we rely on has been destroyed. If we can lock the weak pointer, we + // need to check the 'isDropped()' flag on the index catalog entry. If any index has been + // destroyed, then we throw a query-fatal exception during restore. std::vector<std::weak_ptr<const IndexCatalogEntry>> _indexCatalogEntries; // The names of the indices above. Used for error reporting. diff --git a/src/mongo/db/exec/requires_index_stage.cpp b/src/mongo/db/exec/requires_index_stage.cpp index 2ff0f373480..8e3e2382c9d 100644 --- a/src/mongo/db/exec/requires_index_stage.cpp +++ b/src/mongo/db/exec/requires_index_stage.cpp @@ -58,11 +58,12 @@ void RequiresIndexStage::doSaveStateRequiresCollection() { void RequiresIndexStage::doRestoreStateRequiresCollection() { // Attempt to lock the weak_ptr. If the resulting shared_ptr is null, then our index is no - // longer valid and the query should die. + // longer valid and the query should die. We must also check the `isDropped()` flag on the index + // catalog entry if we are able lock the weak_ptr. auto indexCatalogEntry = _weakIndexCatalogEntry.lock(); uassert(ErrorCodes::QueryPlanKilled, str::stream() << "query plan killed :: index '" << _indexName << "' dropped", - indexCatalogEntry); + indexCatalogEntry && !indexCatalogEntry->isDropped()); // Re-obtain catalog pointers that were set to null during yield preparation. It is safe to // access the catalog entry by raw pointer when the query is active, as its validity is diff --git a/src/mongo/db/exec/requires_index_stage.h b/src/mongo/db/exec/requires_index_stage.h index fca94bf0de0..81d5649970e 100644 --- a/src/mongo/db/exec/requires_index_stage.h +++ b/src/mongo/db/exec/requires_index_stage.h @@ -82,17 +82,13 @@ protected: } private: - // We keep a weak_ptr to the index catalog entry in order to detect when the underlying catalog - // object has been destroyed, e.g. due to an index drop. In this scenario, the - // RequiresIndexStage will throw a query-fatal exception after an attempt to lock the weak_ptr - // indicates that the pointed-to object was deleted. - // // This is necessary to protect against that case that our index is dropped and then recreated // during yield. Such an event should cause the query to be killed, since index cursors may have // pointers into catalog objects that no longer exist. Since indices do not have UUIDs, - // different epochs of the index cannot be distinguished. The weak_ptr allows us to safely. + // different epochs of the index cannot be distinguished. The weak_ptr allows us to safely // determine whether the pointed-to object has been destroyed during yield recovery via the - // shared_ptr control block. + // shared_ptr control block. We need to call `isDropped()` on the index catalog entry after + // locking the weak_ptr to determine whether the index was dropped or destructed during yield. std::weak_ptr<const IndexCatalogEntry> _weakIndexCatalogEntry; const IndexDescriptor* _indexDescriptor; |