summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/index_catalog_entry_impl.cpp
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2021-01-28 15:36:38 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-01-29 00:01:41 +0000
commit0d6199bb52dcae5978551816c6ac4ad98bda165b (patch)
tree0f1a707ead6ea117e4937414695fe4593d748dc6 /src/mongo/db/catalog/index_catalog_entry_impl.cpp
parent603f25ced3e7917ce94cf95265e7ffa0893b7fa6 (diff)
downloadmongo-0d6199bb52dcae5978551816c6ac4ad98bda165b.tar.gz
SERVER-53675 Allow validate to fix up multikey metadata
This allows foreground validation to fix up the following multikey metadata inconsistencies: * An index is multikey but there are no multikey fields * An index has multikeyPaths covering fields that are not multikey * An index does not have multikeyPaths but there are multikey documents (for pre-3.4 indexes) If any changes were made, a warning is included to the validate output and the 'repaired' flag is set to true.
Diffstat (limited to 'src/mongo/db/catalog/index_catalog_entry_impl.cpp')
-rw-r--r--src/mongo/db/catalog/index_catalog_entry_impl.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/index_catalog_entry_impl.cpp b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
index 5aafcab9a1b..80a02584e37 100644
--- a/src/mongo/db/catalog/index_catalog_entry_impl.cpp
+++ b/src/mongo/db/catalog/index_catalog_entry_impl.cpp
@@ -253,6 +253,36 @@ void IndexCatalogEntryImpl::setMultikey(OperationContext* opCtx,
}
}
+void IndexCatalogEntryImpl::forceSetMultikey(OperationContext* const opCtx,
+ const CollectionPtr& coll,
+ bool isMultikey,
+ const MultikeyPaths& multikeyPaths) {
+ invariant(opCtx->lockState()->isCollectionLockedForMode(coll->ns(), MODE_X));
+
+ // Don't check _indexTracksMultikeyPathsInCatalog because the caller may be intentionally trying
+ // to bypass this check. That is, pre-3.4 indexes may be 'stuck' in a state where they are not
+ // tracking multikey paths in the catalog (i.e. the multikeyPaths field is absent), but the
+ // caller wants to upgrade this index because it knows exactly which paths are multikey. We rely
+ // on the following function to make sure this upgrade only takes place on index types that
+ // currently support path-level multikey path tracking.
+ DurableCatalog::get(opCtx)->forceSetIndexIsMultikey(
+ opCtx, _catalogId, _descriptor.get(), isMultikey, multikeyPaths);
+
+ // The prior call to set the multikey metadata in the catalog does some validation and clean up
+ // based on the inputs, so reset the multikey variables based on what is actually in the durable
+ // catalog entry.
+ {
+ stdx::lock_guard<Latch> lk(_indexMultikeyPathsMutex);
+ const bool isMultikey = _catalogIsMultikey(opCtx, &_indexMultikeyPaths);
+ _isMultikeyForRead.store(isMultikey);
+ _isMultikeyForWrite.store(isMultikey);
+ _indexTracksMultikeyPathsInCatalog = !_indexMultikeyPaths.empty();
+ }
+
+ // Since multikey metadata has changed, invalidate the query cache.
+ CollectionQueryInfo::get(coll).clearQueryCacheForSetMultikey(coll);
+}
+
Status IndexCatalogEntryImpl::_setMultikeyInMultiDocumentTransaction(
OperationContext* opCtx, const CollectionPtr& collection, const MultikeyPaths& multikeyPaths) {
// If we are inside a multi-document transaction, we write the on-disk multikey update in a