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.cpp103
1 files changed, 52 insertions, 51 deletions
diff --git a/src/mongo/db/storage/storage_engine_impl.cpp b/src/mongo/db/storage/storage_engine_impl.cpp
index 1ab796a55ea..f7b203741a6 100644
--- a/src/mongo/db/storage/storage_engine_impl.cpp
+++ b/src/mongo/db/storage/storage_engine_impl.cpp
@@ -137,8 +137,7 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
std::sort(identsKnownToStorageEngine.begin(), identsKnownToStorageEngine.end());
}
- auto collectionsKnownToCatalog = _catalog->getAllCollections();
-
+ std::vector<DurableCatalog::Entry> catalogEntries = _catalog->getAllCatalogEntries(opCtx);
if (_options.forRepair) {
// It's possible that there are collection files on disk that are unknown to the catalog. In
// a repair context, if we can't find an ident in the catalog, we generate a catalog entry
@@ -146,12 +145,10 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
// will be dropped in reconcileCatalogAndIdents().
for (const auto& ident : identsKnownToStorageEngine) {
if (_catalog->isCollectionIdent(ident)) {
- bool isOrphan = !std::any_of(collectionsKnownToCatalog.begin(),
- collectionsKnownToCatalog.end(),
- [this, &ident](const auto& coll) {
- return _catalog->getCollectionIdent(
- NamespaceString(coll)) == ident;
- });
+ bool isOrphan = !std::any_of(
+ catalogEntries.begin(),
+ catalogEntries.end(),
+ [this, &ident](DurableCatalog::Entry entry) { return entry.ident == ident; });
if (isOrphan) {
// If the catalog does not have information about this
// collection, we create an new entry for it.
@@ -185,15 +182,13 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
}
KVPrefix maxSeenPrefix = KVPrefix::kNotPrefixed;
- for (const auto& nss : collectionsKnownToCatalog) {
- std::string dbName = nss.db().toString();
-
+ for (DurableCatalog::Entry entry : catalogEntries) {
if (loadingFromUncleanShutdownOrRepair) {
// If we are loading the catalog after an unclean shutdown or during repair, it's
// possible that there are collections in the catalog that are unknown to the storage
// engine. If we can't find a table in the list of storage engine idents, either
// attempt to recover the ident or drop it.
- const auto collectionIdent = _catalog->getCollectionIdent(nss);
+ const auto collectionIdent = entry.ident;
bool orphan = !std::binary_search(identsKnownToStorageEngine.begin(),
identsKnownToStorageEngine.end(),
collectionIdent);
@@ -201,17 +196,18 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
// store, drop it from the catalog and skip initializing it by continuing past the
// following logic.
if (orphan) {
- auto status = _recoverOrphanedCollection(opCtx, nss, collectionIdent);
+ auto status =
+ _recoverOrphanedCollection(opCtx, entry.catalogId, entry.nss, collectionIdent);
if (!status.isOK()) {
- warning() << "Failed to recover orphaned data file for collection '" << nss
- << "': " << status;
+ warning() << "Failed to recover orphaned data file for collection '"
+ << entry.nss << "': " << status;
WriteUnitOfWork wuow(opCtx);
- fassert(50716, _catalog->_removeEntry(opCtx, nss));
+ fassert(50716, _catalog->_removeEntry(opCtx, entry.catalogId));
if (_options.forRepair) {
StorageRepairObserver::get(getGlobalServiceContext())
->invalidatingModification(str::stream()
- << "Collection " << nss
+ << "Collection " << entry.nss
<< " dropped: " << status.reason());
}
wuow.commit();
@@ -220,12 +216,12 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
}
}
- _initCollection(opCtx, nss, _options.forRepair);
- auto maxPrefixForCollection = _catalog->getMetaData(opCtx, nss).getMaxPrefix();
+ _initCollection(opCtx, entry.catalogId, entry.nss, _options.forRepair);
+ auto maxPrefixForCollection = _catalog->getMetaData(opCtx, entry.catalogId).getMaxPrefix();
maxSeenPrefix = std::max(maxSeenPrefix, maxPrefixForCollection);
- if (nss.isOrphanCollection()) {
- log() << "Orphaned collection found: " << nss;
+ if (entry.nss.isOrphanCollection()) {
+ log() << "Orphaned collection found: " << entry.nss;
}
}
@@ -238,14 +234,15 @@ void StorageEngineImpl::loadCatalog(OperationContext* opCtx) {
}
void StorageEngineImpl::_initCollection(OperationContext* opCtx,
+ RecordId catalogId,
const NamespaceString& nss,
bool forRepair) {
- BSONCollectionCatalogEntry::MetaData md = _catalog->getMetaData(opCtx, nss);
+ BSONCollectionCatalogEntry::MetaData md = _catalog->getMetaData(opCtx, catalogId);
uassert(ErrorCodes::MustDowngrade,
str::stream() << "Collection does not have UUID in KVCatalog. Collection: " << nss,
md.options.uuid);
- auto ident = _catalog->getCollectionIdent(nss);
+ auto ident = _catalog->getEntry(catalogId).ident;
std::unique_ptr<RecordStore> rs;
if (forRepair) {
@@ -257,10 +254,10 @@ void StorageEngineImpl::_initCollection(OperationContext* opCtx,
invariant(rs);
}
- auto uuid = _catalog->getCollectionOptions(opCtx, nss).uuid.get();
+ auto uuid = _catalog->getCollectionOptions(opCtx, catalogId).uuid.get();
auto collectionFactory = Collection::Factory::get(getGlobalServiceContext());
- auto collection = collectionFactory->make(opCtx, nss, uuid, std::move(rs));
+ auto collection = collectionFactory->make(opCtx, nss, catalogId, uuid, std::move(rs));
auto& collectionCatalog = CollectionCatalog::get(getGlobalServiceContext());
collectionCatalog.registerCollection(uuid, std::move(collection));
@@ -279,6 +276,7 @@ void StorageEngineImpl::closeCatalog(OperationContext* opCtx) {
}
Status StorageEngineImpl::_recoverOrphanedCollection(OperationContext* opCtx,
+ RecordId catalogId,
const NamespaceString& collectionName,
StringData collectionIdent) {
if (!_options.forRepair) {
@@ -289,11 +287,10 @@ Status StorageEngineImpl::_recoverOrphanedCollection(OperationContext* opCtx,
<< collectionIdent;
WriteUnitOfWork wuow(opCtx);
- const auto metadata = _catalog->getMetaData(opCtx, collectionName);
- auto status =
+ const auto metadata = _catalog->getMetaData(opCtx, catalogId);
+ Status status =
_engine->recoverOrphanedIdent(opCtx, collectionName, collectionIdent, metadata.options);
-
bool dataModified = status.code() == ErrorCodes::DataModifiedByRepair;
if (!status.isOK() && !dataModified) {
return status;
@@ -320,7 +317,7 @@ Status StorageEngineImpl::_recoverOrphanedCollection(OperationContext* opCtx,
* Third, a DurableCatalog may have an index ident that the KVEngine does not. This method will
* rebuild the index.
*/
-StatusWith<std::vector<StorageEngine::CollectionIndexNamePair>>
+StatusWith<std::vector<StorageEngine::IndexIdentifier>>
StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
// Gather all tables known to the storage engine and drop those that aren't cross-referenced
// in the _mdb_catalog. This can happen for two reasons.
@@ -392,14 +389,13 @@ StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
// engine. An omission here is fatal. A missing ident could mean a collection drop was rolled
// back. Note that startup already attempts to open tables; this should only catch errors in
// other contexts such as `recoverToStableTimestamp`.
- auto collections = _catalog->getAllCollections();
+ std::vector<DurableCatalog::Entry> catalogEntries = _catalog->getAllCatalogEntries(opCtx);
if (!_options.forRepair) {
- for (const auto& coll : collections) {
- const auto& identForColl = _catalog->getCollectionIdent(coll);
- if (engineIdents.find(identForColl) == engineIdents.end()) {
+ for (DurableCatalog::Entry entry : catalogEntries) {
+ if (engineIdents.find(entry.ident) == engineIdents.end()) {
return {ErrorCodes::UnrecoverableRollbackError,
- str::stream() << "Expected collection does not exist. Collection: " << coll
- << " Ident: " << identForColl};
+ str::stream() << "Expected collection does not exist. Collection: "
+ << entry.nss << " Ident: " << entry.ident};
}
}
}
@@ -409,15 +405,17 @@ StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
//
// Also, remove unfinished builds except those that were background index builds started on a
// secondary.
- std::vector<CollectionIndexNamePair> ret;
- for (const auto& coll : collections) {
- BSONCollectionCatalogEntry::MetaData metaData = _catalog->getMetaData(opCtx, coll);
+ std::vector<StorageEngine::IndexIdentifier> ret;
+ for (DurableCatalog::Entry entry : catalogEntries) {
+ BSONCollectionCatalogEntry::MetaData metaData =
+ _catalog->getMetaData(opCtx, entry.catalogId);
+ NamespaceString coll(metaData.ns);
// Batch up the indexes to remove them from `metaData` outside of the iterator.
std::vector<std::string> indexesToDrop;
for (const auto& indexMetaData : metaData.indexes) {
const std::string& indexName = indexMetaData.name();
- std::string indexIdent = _catalog->getIndexIdent(opCtx, coll, indexName);
+ std::string indexIdent = _catalog->getIndexIdent(opCtx, entry.catalogId, indexName);
// Warn in case of incorrect "multikeyPath" information in catalog documents. This is
// the result of a concurrency bug which has since been fixed, but may persist in
@@ -442,7 +440,7 @@ StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
if (indexMetaData.ready && !foundIdent) {
log() << "Expected index data is missing, rebuilding. Collection: " << coll
<< " Index: " << indexName;
- ret.emplace_back(coll.ns(), indexName);
+ ret.push_back({entry.catalogId, coll, indexName});
continue;
}
@@ -488,7 +486,7 @@ StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
log() << "Expected background index build did not complete, rebuilding. "
"Collection: "
<< coll << " Index: " << indexName;
- ret.emplace_back(coll.ns(), indexName);
+ ret.push_back({entry.catalogId, coll, indexName});
continue;
}
@@ -515,7 +513,7 @@ StorageEngineImpl::reconcileCatalogAndIdents(OperationContext* opCtx) {
}
if (indexesToDrop.size() > 0) {
WriteUnitOfWork wuow(opCtx);
- _catalog->putMetaData(opCtx, coll, metaData);
+ _catalog->putMetaData(opCtx, entry.catalogId, metaData);
wuow.commit();
}
}
@@ -629,17 +627,17 @@ Status StorageEngineImpl::_dropCollectionsNoTimestamp(OperationContext* opCtx,
WriteUnitOfWork untimestampedDropWuow(opCtx);
for (auto& nss : toDrop) {
invariant(getCatalog());
- auto uuid = CollectionCatalog::get(opCtx).lookupUUIDByNSS(nss).get();
- Status result = getCatalog()->dropCollection(opCtx, nss);
+ auto coll = CollectionCatalog::get(opCtx).lookupCollectionByNamespace(nss);
+ Status result = getCatalog()->dropCollection(opCtx, coll->getCatalogId());
if (!result.isOK() && firstError.isOK()) {
firstError = result;
}
- auto removedColl = CollectionCatalog::get(opCtx).deregisterCollection(uuid);
+ auto removedColl = CollectionCatalog::get(opCtx).deregisterCollection(coll->uuid());
opCtx->recoveryUnit()->registerChange(
CollectionCatalog::get(opCtx).makeFinishDropCollectionChange(std::move(removedColl),
- uuid));
+ coll->uuid()));
}
untimestampedDropWuow.commit();
@@ -697,11 +695,13 @@ SnapshotManager* StorageEngineImpl::getSnapshotManager() const {
return _engine->getSnapshotManager();
}
-Status StorageEngineImpl::repairRecordStore(OperationContext* opCtx, const NamespaceString& nss) {
+Status StorageEngineImpl::repairRecordStore(OperationContext* opCtx,
+ RecordId catalogId,
+ const NamespaceString& nss) {
auto repairObserver = StorageRepairObserver::get(getGlobalServiceContext());
invariant(repairObserver->isIncomplete());
- Status status = _engine->repairIdent(opCtx, _catalog->getCollectionIdent(nss));
+ Status status = _engine->repairIdent(opCtx, _catalog->getEntry(catalogId).ident);
bool dataModified = status.code() == ErrorCodes::DataModifiedByRepair;
if (!status.isOK() && !dataModified) {
return status;
@@ -716,7 +716,7 @@ Status StorageEngineImpl::repairRecordStore(OperationContext* opCtx, const Names
auto& collectionCatalog = CollectionCatalog::get(getGlobalServiceContext());
auto uuid = collectionCatalog.lookupUUIDByNSS(nss).get();
collectionCatalog.deregisterCollection(uuid);
- _initCollection(opCtx, nss, false);
+ _initCollection(opCtx, catalogId, nss, false);
return Status::OK();
}
@@ -1012,10 +1012,11 @@ int64_t StorageEngineImpl::sizeOnDiskForDb(OperationContext* opCtx, StringData d
size += collection->getRecordStore()->storageSize(opCtx);
std::vector<std::string> indexNames;
- _catalog->getAllIndexes(opCtx, collection->ns(), &indexNames);
+ _catalog->getAllIndexes(opCtx, collection->getCatalogId(), &indexNames);
for (size_t i = 0; i < indexNames.size(); i++) {
- std::string ident = _catalog->getIndexIdent(opCtx, collection->ns(), indexNames[i]);
+ std::string ident =
+ _catalog->getIndexIdent(opCtx, collection->getCatalogId(), indexNames[i]);
size += _engine->getIdentSize(opCtx, ident);
}