diff options
author | Haley Connelly <haley.connelly@mongodb.com> | 2023-01-09 15:10:47 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-01-09 15:52:02 +0000 |
commit | 6e0f8d23b304375591c7f5bce257cea348ae1928 (patch) | |
tree | 90f199e02846c012eae910d5f0cf218b6c6ae034 /src | |
parent | 038e983c30733e1ba107acaf0c7edcd4f858ef22 (diff) | |
download | mongo-6e0f8d23b304375591c7f5bce257cea348ae1928.tar.gz |
SERVER-67290 Support repair on clustered collections with missing _mdb_catalog
(cherry picked from commit bbfaa9d)
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/storage/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/storage/durable_catalog.h | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/durable_catalog_impl.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/durable_catalog_impl.h | 4 | ||||
-rw-r--r-- | src/mongo/db/storage/kv/kv_engine.h | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/storage_engine_impl.cpp | 32 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp | 7 | ||||
-rw-r--r-- | src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h | 2 |
8 files changed, 51 insertions, 16 deletions
diff --git a/src/mongo/db/storage/SConscript b/src/mongo/db/storage/SConscript index 45931873ba3..6081de4589c 100644 --- a/src/mongo/db/storage/SConscript +++ b/src/mongo/db/storage/SConscript @@ -623,6 +623,7 @@ env.Library( LIBDEPS_PRIVATE=[ '$BUILD_DIR/mongo/db/audit', '$BUILD_DIR/mongo/db/catalog/catalog_helpers', + '$BUILD_DIR/mongo/db/catalog/clustered_collection_options', '$BUILD_DIR/mongo/db/catalog/index_catalog', '$BUILD_DIR/mongo/db/multitenancy', '$BUILD_DIR/mongo/db/resumable_index_builds_idl', diff --git a/src/mongo/db/storage/durable_catalog.h b/src/mongo/db/storage/durable_catalog.h index 49db4546918..d41e8173883 100644 --- a/src/mongo/db/storage/durable_catalog.h +++ b/src/mongo/db/storage/durable_catalog.h @@ -123,11 +123,12 @@ public: /** * Create an entry in the catalog for an orphaned collection found in the * storage engine. Return the generated ns of the collection. - * Note that this function does not recreate the _id index on the collection because it does not - * have access to index catalog. + * Note that this function does not recreate the _id index on the for non-clustered collections + * because it does not have access to index catalog. */ virtual StatusWith<std::string> newOrphanedIdent(OperationContext* opCtx, - std::string ident) = 0; + std::string ident, + const CollectionOptions& optionsWithUUID) = 0; virtual std::string getFilesystemPathForDb(const std::string& dbName) const = 0; diff --git a/src/mongo/db/storage/durable_catalog_impl.cpp b/src/mongo/db/storage/durable_catalog_impl.cpp index 13b86f9af07..c4ef8527e52 100644 --- a/src/mongo/db/storage/durable_catalog_impl.cpp +++ b/src/mongo/db/storage/durable_catalog_impl.cpp @@ -554,8 +554,8 @@ bool DurableCatalogImpl::isCollectionIdent(StringData ident) const { ident.find("collection/") != std::string::npos; } -StatusWith<std::string> DurableCatalogImpl::newOrphanedIdent(OperationContext* opCtx, - std::string ident) { +StatusWith<std::string> DurableCatalogImpl::newOrphanedIdent( + OperationContext* opCtx, std::string ident, const CollectionOptions& optionsWithUUID) { // The collection will be named local.orphan.xxxxx. std::string identNs = ident; std::replace(identNs.begin(), identNs.end(), '-', '_'); @@ -563,9 +563,6 @@ StatusWith<std::string> DurableCatalogImpl::newOrphanedIdent(OperationContext* o NamespaceString nss(NamespaceString(NamespaceString::kOrphanCollectionDb, NamespaceString::kOrphanCollectionPrefix + identNs)); - // Generate a new UUID for the orphaned collection. - CollectionOptions optionsWithUUID; - optionsWithUUID.uuid.emplace(UUID::gen()); BSONObj obj; { BSONObjBuilder b; diff --git a/src/mongo/db/storage/durable_catalog_impl.h b/src/mongo/db/storage/durable_catalog_impl.h index 873733d58b4..bedaf4a79af 100644 --- a/src/mongo/db/storage/durable_catalog_impl.h +++ b/src/mongo/db/storage/durable_catalog_impl.h @@ -98,7 +98,9 @@ public: return _rs; } - StatusWith<std::string> newOrphanedIdent(OperationContext* opCtx, std::string ident); + StatusWith<std::string> newOrphanedIdent(OperationContext* opCtx, + std::string ident, + const CollectionOptions& optionsWithUUID); std::string getFilesystemPathForDb(const std::string& dbName) const; diff --git a/src/mongo/db/storage/kv/kv_engine.h b/src/mongo/db/storage/kv/kv_engine.h index 25f52f0e40f..304a695308e 100644 --- a/src/mongo/db/storage/kv/kv_engine.h +++ b/src/mongo/db/storage/kv/kv_engine.h @@ -422,6 +422,13 @@ public: } /** + * Returns the 'KeyFormat' tied to 'ident'. + */ + virtual KeyFormat getKeyFormat(OperationContext* opCtx, StringData ident) const { + MONGO_UNREACHABLE; + } + + /** * The destructor will never be called from mongod, but may be called from tests. * Engines may assume that this will only be called in the case of clean shutdown, even if * cleanShutdown() hasn't been called. diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp index 255f80efec1..6e9c57de195 100644 --- a/src/mongo/db/storage/storage_engine_impl.cpp +++ b/src/mongo/db/storage/storage_engine_impl.cpp @@ -35,6 +35,7 @@ #include "mongo/db/audit.h" #include "mongo/db/catalog/catalog_control.h" +#include "mongo/db/catalog/clustered_collection_util.h" #include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_catalog_helper.h" #include "mongo/db/catalog_raii.h" @@ -201,19 +202,36 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx, LastShutdownState l // If the catalog does not have information about this // collection, we create an new entry for it. WriteUnitOfWork wuow(opCtx); - StatusWith<std::string> statusWithNs = _catalog->newOrphanedIdent(opCtx, ident); + + auto keyFormat = _engine->getKeyFormat(opCtx, ident); + bool isClustered = keyFormat == KeyFormat::String; + CollectionOptions optionsWithUUID; + optionsWithUUID.uuid.emplace(UUID::gen()); + if (isClustered) { + optionsWithUUID.clusteredIndex = + clustered_util::makeDefaultClusteredIdIndex(); + } + + StatusWith<std::string> statusWithNs = + _catalog->newOrphanedIdent(opCtx, ident, optionsWithUUID); + if (statusWithNs.isOK()) { wuow.commit(); auto orphanCollNs = statusWithNs.getValue(); LOGV2(22247, "Successfully created an entry in the catalog for orphaned " "collection", - "namespace"_attr = orphanCollNs); - LOGV2_WARNING(22265, - "Collection does not have an _id index. Please manually " - "build the index", - "namespace"_attr = orphanCollNs); - + "namespace"_attr = orphanCollNs, + "options"_attr = optionsWithUUID); + + if (!isClustered) { + // The _id index is already implicitly created on collections clustered + // by _id. + LOGV2_WARNING(22265, + "Collection does not have an _id index. Please manually " + "build the index", + "namespace"_attr = orphanCollNs); + } StorageRepairObserver::get(getGlobalServiceContext()) ->benignModification(str::stream() << "Orphan collection created: " << statusWithNs.getValue()); diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp index 575335efe75..048cac044d2 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp @@ -2756,4 +2756,11 @@ Status WiredTigerKVEngine::reconfigureLogging() { return wtRCToStatus(_conn->reconfigure(_conn, verboseConfig.c_str()), nullptr); } +KeyFormat WiredTigerKVEngine::getKeyFormat(OperationContext* opCtx, StringData ident) const { + + const std::string wtTableConfig = + uassertStatusOK(WiredTigerUtil::getMetadataCreate(opCtx, "table:{}"_format(ident))); + return wtTableConfig.find("key_format=u") != string::npos ? KeyFormat::String : KeyFormat::Long; +} + } // namespace mongo diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h index 688db855b74..add1d9a9b29 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.h @@ -383,6 +383,8 @@ public: Status reconfigureLogging() override; + KeyFormat getKeyFormat(OperationContext* opCtx, StringData ident) const override; + private: class WiredTigerSessionSweeper; |