summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/drop_database.cpp
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2017-06-27 00:06:17 -0400
committerBenety Goh <benety@mongodb.com>2017-06-29 11:17:45 -0400
commit560b3f562832664c1cb09cdbf3a257493bad6ba8 (patch)
tree657b5739d5e601ae8515501a74b9298e7870a46d /src/mongo/db/catalog/drop_database.cpp
parentf0110e2682e3a787df062ee3feb7637add694978 (diff)
downloadmongo-560b3f562832664c1cb09cdbf3a257493bad6ba8.tar.gz
SERVER-29876 dropDatabase() waits for pending collection drops to complete
Diffstat (limited to 'src/mongo/db/catalog/drop_database.cpp')
-rw-r--r--src/mongo/db/catalog/drop_database.cpp58
1 files changed, 46 insertions, 12 deletions
diff --git a/src/mongo/db/catalog/drop_database.cpp b/src/mongo/db/catalog/drop_database.cpp
index 8ccc1c8f944..2c3aecf31a4 100644
--- a/src/mongo/db/catalog/drop_database.cpp
+++ b/src/mongo/db/catalog/drop_database.cpp
@@ -32,6 +32,8 @@
#include "mongo/db/catalog/drop_database.h"
+#include <algorithm>
+
#include "mongo/db/background.h"
#include "mongo/db/catalog/database.h"
#include "mongo/db/client.h"
@@ -91,6 +93,10 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
auto replCoord = repl::ReplicationCoordinator::get(opCtx);
std::size_t numCollectionsToDrop = 0;
+ // We have to wait for the last drop-pending collection to be removed if there are no
+ // collections to drop.
+ repl::OpTime latestDropPendingOpTime;
+
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
Lock::GlobalWrite lk(opCtx);
AutoGetDb autoDB(opCtx, dbName, MODE_X);
@@ -118,6 +124,13 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
for (auto collection : *db) {
const auto& nss = collection->ns();
+ if (nss.isDropPendingNamespace() && replCoord->isReplEnabled() &&
+ opCtx->writesAreReplicated()) {
+ log() << "dropDatabase " << dbName << " - found drop-pending collection: " << nss;
+ latestDropPendingOpTime = std::max(
+ latestDropPendingOpTime, uassertStatusOK(nss.getDropPendingNamespaceOpTime()));
+ continue;
+ }
if (replCoord->isOplogDisabledFor(opCtx, nss) || nss.isSystemDotIndexes()) {
continue;
}
@@ -130,7 +143,7 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
dropPendingGuard.Dismiss();
// If there are no collection drops to wait for, we complete the drop database operation.
- if (numCollectionsToDrop == 0U) {
+ if (numCollectionsToDrop == 0U && latestDropPendingOpTime.isNull()) {
return _finishDropDatabase(opCtx, dbName, db);
}
}
@@ -146,18 +159,39 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
}
});
- auto status =
- replCoord->awaitReplicationOfLastOpForClient(opCtx, kDropDatabaseWriteConcern).status;
- if (!status.isOK()) {
- return Status(status.code(),
- str::stream() << "dropDatabase " << dbName << " failed waiting for "
- << numCollectionsToDrop
- << " collection drops to replicate: "
- << status.reason());
- }
+ if (numCollectionsToDrop > 0U) {
+ auto status =
+ replCoord->awaitReplicationOfLastOpForClient(opCtx, kDropDatabaseWriteConcern).status;
+ if (!status.isOK()) {
+ return Status(status.code(),
+ str::stream() << "dropDatabase " << dbName << " failed waiting for "
+ << numCollectionsToDrop
+ << " collection drops to replicate: "
+ << status.reason());
+ }
- log() << "dropDatabase " << dbName << " - successfully dropped " << numCollectionsToDrop
- << " collections. dropping database";
+ log() << "dropDatabase " << dbName << " - successfully dropped " << numCollectionsToDrop
+ << " collections. dropping database";
+ } else {
+ invariant(!latestDropPendingOpTime.isNull());
+ auto status =
+ replCoord->awaitReplication(opCtx, latestDropPendingOpTime, kDropDatabaseWriteConcern)
+ .status;
+ if (!status.isOK()) {
+ return Status(
+ status.code(),
+ str::stream()
+ << "dropDatabase "
+ << dbName
+ << " failed waiting for pending collection drops (most recent drop optime: "
+ << latestDropPendingOpTime.toString()
+ << ") to replicate: "
+ << status.reason());
+ }
+
+ log() << "dropDatabase " << dbName
+ << " - pending collection drops completed. dropping database";
+ }
dropPendingGuardWhileAwaitingReplication.Dismiss();
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {