summaryrefslogtreecommitdiff
path: root/src/mongo/db/storage/storage_engine_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/storage/storage_engine_impl.cpp')
-rw-r--r--src/mongo/db/storage/storage_engine_impl.cpp76
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();
}