summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/drop_collection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/catalog/drop_collection.cpp')
-rw-r--r--src/mongo/db/catalog/drop_collection.cpp34
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