summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog/drop_database.cpp
diff options
context:
space:
mode:
authorBenety Goh <benety@mongodb.com>2017-06-27 18:10:37 -0400
committerBenety Goh <benety@mongodb.com>2017-06-29 15:07:30 -0400
commit57e3704f443df1fb071e0af81421ce2999fad767 (patch)
tree5eae6ef63aeedbde59ff5c3e78ebb77da821ddfa /src/mongo/db/catalog/drop_database.cpp
parent8940fe34c3300e8d391254fcea3fed14a3a0db6a (diff)
downloadmongo-57e3704f443df1fb071e0af81421ce2999fad767.tar.gz
SERVER-29874 dropDatabase() releases locks when awaiting replication
This allows dropDatabase() to work with applyOps when we have to wait for collection drops to replicate
Diffstat (limited to 'src/mongo/db/catalog/drop_database.cpp')
-rw-r--r--src/mongo/db/catalog/drop_database.cpp80
1 files changed, 50 insertions, 30 deletions
diff --git a/src/mongo/db/catalog/drop_database.cpp b/src/mongo/db/catalog/drop_database.cpp
index 2c3aecf31a4..ef9bc6f8aa5 100644
--- a/src/mongo/db/catalog/drop_database.cpp
+++ b/src/mongo/db/catalog/drop_database.cpp
@@ -37,6 +37,7 @@
#include "mongo/db/background.h"
#include "mongo/db/catalog/database.h"
#include "mongo/db/client.h"
+#include "mongo/db/concurrency/d_concurrency.h"
#include "mongo/db/concurrency/write_conflict_exception.h"
#include "mongo/db/curop.h"
#include "mongo/db/db_raii.h"
@@ -159,39 +160,58 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
}
});
- 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());
- }
+ {
+ // Holding of any locks is disallowed while awaiting replication because this can
+ // potentially block for long time while doing network activity.
+ //
+ // Even though dropDatabase() does not explicitly acquire any locks before awaiting
+ // replication, it is possible that the caller of this function may already have acquired
+ // a lock. The applyOps command is an example of a dropDatabase() caller that does this.
+ // Therefore, we have to release any locks using a TempRelease RAII object.
+ //
+ // TODO: Remove the use of this TempRelease object when SERVER-29802 is completed.
+ // The work in SERVER-29802 will adjust the locking rules around applyOps operations and
+ // dropDatabase is expected to be one of the operations where we expect to no longer acquire
+ // the global lock.
+ Lock::TempRelease release(opCtx->lockState());
+
+ 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";
- } 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 << " - 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";
+ log() << "dropDatabase " << dbName
+ << " - pending collection drops completed. dropping database";
+ }
}
+
dropPendingGuardWhileAwaitingReplication.Dismiss();
MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {