diff options
Diffstat (limited to 'src/mongo/db/catalog/drop_collection.cpp')
-rw-r--r-- | src/mongo/db/catalog/drop_collection.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp index b5f30ae2a3e..18ab3311ca0 100644 --- a/src/mongo/db/catalog/drop_collection.cpp +++ b/src/mongo/db/catalog/drop_collection.cpp @@ -34,6 +34,7 @@ #include "mongo/db/catalog/drop_collection.h" #include "mongo/db/background.h" +#include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog/index_catalog.h" #include "mongo/db/client.h" #include "mongo/db/concurrency/write_conflict_exception.h" @@ -147,6 +148,29 @@ Status _dropCollection(OperationContext* opCtx, return Status::OK(); } +void closeDatabaseIfEmpty(OperationContext* opCtx, StringData ns) { + invariant(opCtx->lockState()->isDbLockedForMode(ns, MODE_NONE)); + + bool empty = CollectionCatalog::get(opCtx).empty(ns); + if (!empty) { + return; + } + + AutoGetDb autoDb(opCtx, ns, MODE_X); + if (!autoDb.getDb()) { + return; + } + + // Double check that we're still empty. A new collection could've been created before we got the + // exclusive lock. + empty = CollectionCatalog::get(opCtx).empty(ns); + if (!empty) { + return; + } + + DatabaseHolder::get(opCtx)->close(opCtx, ns); +} + Status dropCollection(OperationContext* opCtx, const NamespaceString& collectionName, BSONObjBuilder& result, @@ -160,7 +184,7 @@ Status dropCollection(OperationContext* opCtx, log() << "Hanging drop collection before lock acquisition while fail point is set"; MONGO_FAIL_POINT_PAUSE_WHILE_SET(hangDropCollectionBeforeLockAcquisition); } - return writeConflictRetry(opCtx, "drop", collectionName.ns(), [&] { + Status status = writeConflictRetry(opCtx, "drop", collectionName.ns(), [&] { AutoGetDb autoDb(opCtx, collectionName.db(), MODE_IX); Database* db = autoDb.getDb(); if (!db) { @@ -175,6 +199,14 @@ Status dropCollection(OperationContext* opCtx, opCtx, db, collectionName, dropOpTime, systemCollectionMode, result); } }); + + if (!status.isOK()) { + return status; + } + + // If this dropped the last collection in the database, we should close the database. + closeDatabaseIfEmpty(opCtx, collectionName.db()); + return Status::OK(); } } // namespace mongo |