diff options
Diffstat (limited to 'src/mongo/db/storage/storage_engine_impl.cpp')
| -rw-r--r-- | src/mongo/db/storage/storage_engine_impl.cpp | 76 |
1 files changed, 51 insertions, 25 deletions
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp index 5f5e0de5a9d..7440ac990b2 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()); @@ -665,21 +683,19 @@ StatusWith<StorageEngine::ReconcileResult> StorageEngineImpl::reconcileCatalogAn logAttrs(nss)); } - // Two-phase index drop ensures that the underlying data table for an index in the - // catalog is not dropped until the index removal from the catalog has been majority - // committed and become part of the latest checkpoint. Therefore, there should almost - // never be a case where the index catalog entry remains but the index table (identified - // by ident) has been removed. - // - // There is an exception to this due to the fact that we drop the index ident without a - // timestamp when restarting an index build for startup recovery. Then, if we experience - // an unclean shutdown before a checkpoint is taken, the subsequent startup recovery can - // see the now-dropped ident referenced by the old index catalog entry. - invariant(engineIdents.find(indexIdent) != engineIdents.end() || - lastShutdownState == LastShutdownState::kUnclean, - str::stream() << "Failed to find an index data table matching " << indexIdent - << " for durable index catalog entry " << indexMetaData.spec - << " in collection " << nss.ns()); + if (!engineIdents.count(indexIdent)) { + // There are cetain cases where the catalog entry may reference an index ident which + // is no longer present. One example of this is when an unclean shutdown occurs + // before a checkpoint is taken during startup recovery. Since we drop the index + // ident without a timestamp when restarting the index build for startup recovery, + // the subsequent startup recovery can see the now-dropped ident referenced by the + // old index catalog entry. + LOGV2(6386500, + "Index catalog entry ident not found", + "ident"_attr = indexIdent, + "entry"_attr = indexMetaData.spec, + logAttrs(nss)); + } // Any index build with a UUID is an unfinished two-phase build and must be restarted. // There are no special cases to handle on primaries or secondaries. An index build may @@ -782,6 +798,7 @@ void StorageEngineImpl::cleanShutdown() { } CollectionCatalog::write(getGlobalServiceContext(), [](CollectionCatalog& catalog) { + catalog.onCloseCatalog(); catalog.deregisterAllCollectionsAndViews(); }); @@ -884,8 +901,10 @@ Status StorageEngineImpl::_dropCollectionsNoTimestamp(OperationContext* opCtx, // No need to remove the indexes from the IndexCatalog because eliminating the Collection // will have the same effect. - auto ii = - coll->getIndexCatalog()->getIndexIterator(opCtx, true /* includeUnfinishedIndexes */); + auto ii = coll->getIndexCatalog()->getIndexIterator( + opCtx, + IndexCatalog::InclusionPolicy::kReady | IndexCatalog::InclusionPolicy::kUnfinished | + IndexCatalog::InclusionPolicy::kFrozen); while (ii->more()) { const IndexCatalogEntry* ice = ii->next(); @@ -1312,7 +1331,9 @@ int64_t StorageEngineImpl::sizeOnDiskForDb(OperationContext* opCtx, auto perCollectionWork = [&](const CollectionPtr& collection) { size += collection->getRecordStore()->storageSize(opCtx); - auto it = collection->getIndexCatalog()->getIndexIterator(opCtx, true); + auto it = collection->getIndexCatalog()->getIndexIterator( + opCtx, + IndexCatalog::InclusionPolicy::kReady | IndexCatalog::InclusionPolicy::kUnfinished); while (it->more()) { size += _engine->getIdentSize(opCtx, it->next()->getIdent()); } @@ -1359,6 +1380,11 @@ const DurableCatalog* StorageEngineImpl::getCatalog() const { return _catalog.get(); } +StatusWith<BSONObj> StorageEngineImpl::getSanitizedStorageOptionsForSecondaryReplication( + const BSONObj& options) const { + return _engine->getSanitizedStorageOptionsForSecondaryReplication(options); +} + void StorageEngineImpl::dump() const { _engine->dump(); } |
