diff options
-rw-r--r-- | jstests/noPassthrough/step_down_during_drop_database.js | 60 | ||||
-rw-r--r-- | src/mongo/db/catalog/database.h | 2 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_impl.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/catalog/database_test.cpp | 9 |
4 files changed, 62 insertions, 13 deletions
diff --git a/jstests/noPassthrough/step_down_during_drop_database.js b/jstests/noPassthrough/step_down_during_drop_database.js new file mode 100644 index 00000000000..51a21afce76 --- /dev/null +++ b/jstests/noPassthrough/step_down_during_drop_database.js @@ -0,0 +1,60 @@ +/** + * Tests that performing a stepdown on the primary during a dropDatabase command doesn't have any + * negative effects when the new primary runs the same dropDatabase command while the old primary + * is still in the midst of dropping the database. + * + * @tags: [requires_replication] + */ +(function() { + "use strict"; + + load("jstests/libs/check_log.js"); + + const dbName = "test"; + const collName = "coll"; + + const replSet = new ReplSetTest({nodes: 2}); + replSet.startSet(); + replSet.initiate(); + + let primary = replSet.getPrimary(); + let testDB = primary.getDB(dbName); + + const size = 5; + jsTest.log("Creating " + size + " test documents."); + var bulk = testDB.getCollection(collName).initializeUnorderedBulkOp(); + for (var i = 0; i < size; ++i) { + bulk.insert({i: i}); + } + assert.writeOK(bulk.execute()); + replSet.awaitReplication(); + + const failpoint = "dropDatabaseHangAfterAllCollectionsDrop"; + assert.commandWorked(primary.adminCommand({configureFailPoint: failpoint, mode: "alwaysOn"})); + + // Run the dropDatabase command and stepdown the primary while it is running. + const awaitShell = startParallelShell(() => { + db.dropDatabase(); + }, testDB.getMongo().port); + + // Ensure the dropDatabase command has begun before stepping down. + checkLog.contains(primary, + "dropDatabase - fail point dropDatabaseHangAfterAllCollectionsDrop " + + "enabled. Blocking until fail point is disabled."); + + assert.commandWorked(testDB.adminCommand({replSetStepDown: 60, force: true})); + replSet.waitForState(primary, ReplSetTest.State.SECONDARY); + + assert.commandWorked(primary.adminCommand({configureFailPoint: failpoint, mode: "off"})); + awaitShell(); + + primary = replSet.getPrimary(); + testDB = primary.getDB(dbName); + + // Run dropDatabase on the new primary. The secondary (formerly the primary) should be able to + // drop the database too. + testDB.dropDatabase(); + replSet.awaitReplication(); + + replSet.stopSet(); +})(); diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h index 30648c41bd9..5e4a248305a 100644 --- a/src/mongo/db/catalog/database.h +++ b/src/mongo/db/catalog/database.h @@ -152,8 +152,6 @@ public: * Sets the 'drop-pending' state of this Database. * This is done at the beginning of a dropDatabase operation and is used to reject subsequent * collection creation requests on this database. - * Throws a UserAssertion if this is called on a Database that is already in a 'drop-pending' - * state. * The database must be locked in MODE_X when calling this function. */ virtual void setDropPending(OperationContext* opCtx, bool dropPending) = 0; diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp index e8db845ce50..4ca2102ff0f 100644 --- a/src/mongo/db/catalog/database_impl.cpp +++ b/src/mongo/db/catalog/database_impl.cpp @@ -370,10 +370,6 @@ Status DatabaseImpl::setProfilingLevel(OperationContext* opCtx, int newLevel) { void DatabaseImpl::setDropPending(OperationContext* opCtx, bool dropPending) { if (dropPending) { invariant(opCtx->lockState()->isDbLockedForMode(name(), MODE_X)); - uassert(ErrorCodes::DatabaseDropPending, - str::stream() << "Unable to drop database " << name() - << " because it is already in the process of being dropped.", - !_dropPending); _dropPending = true; } else { invariant(opCtx->lockState()->isDbLockedForMode(name(), MODE_IX)); diff --git a/src/mongo/db/catalog/database_test.cpp b/src/mongo/db/catalog/database_test.cpp index e1743a76488..c5f5caf1968 100644 --- a/src/mongo/db/catalog/database_test.cpp +++ b/src/mongo/db/catalog/database_test.cpp @@ -128,13 +128,8 @@ TEST_F(DatabaseTest, SetDropPendingThrowsExceptionIfDatabaseIsAlreadyInADropPend db->setDropPending(_opCtx.get(), true); ASSERT_TRUE(db->isDropPending(_opCtx.get())); - ASSERT_THROWS_CODE_AND_WHAT( - db->setDropPending(_opCtx.get(), true), - AssertionException, - ErrorCodes::DatabaseDropPending, - (StringBuilder() << "Unable to drop database " << _nss.db() - << " because it is already in the process of being dropped.") - .stringData()); + db->setDropPending(_opCtx.get(), true); + ASSERT_TRUE(db->isDropPending(_opCtx.get())); db->setDropPending(_opCtx.get(), false); ASSERT_FALSE(db->isDropPending(_opCtx.get())); |