summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/catalog/drop_database.cpp14
-rw-r--r--src/mongo/db/catalog/drop_database_test.cpp24
2 files changed, 38 insertions, 0 deletions
diff --git a/src/mongo/db/catalog/drop_database.cpp b/src/mongo/db/catalog/drop_database.cpp
index 1df925e5b49..ff526a9feda 100644
--- a/src/mongo/db/catalog/drop_database.cpp
+++ b/src/mongo/db/catalog/drop_database.cpp
@@ -224,6 +224,20 @@ Status dropDatabase(OperationContext* opCtx, const std::string& dbName) {
return writeConflictRetry(opCtx, "dropDatabase_database", dbName, [&] {
Lock::GlobalWrite lk(opCtx);
+
+ bool userInitiatedWritesAndNotPrimary =
+ opCtx->writesAreReplicated() && !replCoord->canAcceptWritesForDatabase(opCtx, dbName);
+
+ if (userInitiatedWritesAndNotPrimary) {
+ return Status(ErrorCodes::NotMaster,
+ str::stream() << "Could not drop database " << dbName
+ << " because we transitioned from PRIMARY to "
+ << replCoord->getMemberState().toString()
+ << " while waiting for "
+ << numCollectionsToDrop
+ << " pending collection drop(s).");
+ }
+
AutoGetDb autoDB(opCtx, dbName, MODE_X);
if (auto db = autoDB.getDb()) {
return _finishDropDatabase(opCtx, dbName, db);
diff --git a/src/mongo/db/catalog/drop_database_test.cpp b/src/mongo/db/catalog/drop_database_test.cpp
index 1e384c3a031..7ba02585bcd 100644
--- a/src/mongo/db/catalog/drop_database_test.cpp
+++ b/src/mongo/db/catalog/drop_database_test.cpp
@@ -426,4 +426,28 @@ TEST_F(DropDatabaseTest,
ASSERT_FALSE(AutoGetDb(_opCtx.get(), _nss.db(), MODE_X).getDb());
}
+TEST_F(DropDatabaseTest,
+ DropDatabaseReturnsNotMasterIfNotPrimaryAfterCollectionsDropsAreReplicated) {
+ // Transition from PRIMARY to SECONDARY while awaiting replication of collection drops.
+ _replCoord->setAwaitReplicationReturnValueFunction([this](const repl::OpTime&) {
+ ASSERT_OK(_replCoord->setFollowerMode(repl::MemberState::RS_SECONDARY));
+ ASSERT_TRUE(_opCtx->writesAreReplicated());
+ ASSERT_FALSE(_replCoord->canAcceptWritesForDatabase(_opCtx.get(), _nss.db()));
+ return repl::ReplicationCoordinator::StatusAndDuration(Status::OK(), Milliseconds(0));
+ });
+
+ _createCollection(_opCtx.get(), _nss);
+
+ ASSERT_TRUE(AutoGetDb(_opCtx.get(), _nss.db(), MODE_X).getDb());
+
+ auto status = dropDatabase(_opCtx.get(), _nss.db().toString());
+ ASSERT_EQUALS(ErrorCodes::NotMaster, status);
+ ASSERT_EQUALS(status.reason(),
+ str::stream() << "Could not drop database " << _nss.db()
+ << " because we transitioned from PRIMARY to SECONDARY"
+ << " while waiting for 1 pending collection drop(s).");
+
+ ASSERT_TRUE(AutoGetDb(_opCtx.get(), _nss.db(), MODE_X).getDb());
+}
+
} // namespace