diff options
author | Enrico <enrico.golfieri@mongodb.com> | 2023-04-21 14:21:02 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2023-04-21 14:42:33 +0000 |
commit | 2f5665769c421ed8641c7ddf360c541655337735 (patch) | |
tree | da91d836fae2298dd740c02c42ab1c0d88637b42 | |
parent | 151cfa0038a81b950408b585a60d7503cf9c1ef1 (diff) | |
download | mongo-2f5665769c421ed8641c7ddf360c541655337735.tar.gz |
SERVER-73390 Mitigate database version regression bug on drop database ( cherry picked from 5780b40e0adf02427b5718f12959eae7d5e72939 )
-rw-r--r-- | src/mongo/db/s/drop_database_coordinator.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/mongo/db/s/drop_database_coordinator.cpp b/src/mongo/db/s/drop_database_coordinator.cpp index 660a95b96cc..faadd47bfba 100644 --- a/src/mongo/db/s/drop_database_coordinator.cpp +++ b/src/mongo/db/s/drop_database_coordinator.cpp @@ -101,6 +101,25 @@ private: const BSONObj _reason; }; +bool isDbAlreadyDropped(OperationContext* opCtx, + const boost::optional<mongo::DatabaseVersion>& dbVersion, + const StringData& dbName) { + if (dbVersion) { + try { + auto const catalogClient = Grid::get(opCtx)->catalogClient(); + const auto db = catalogClient->getDatabase( + opCtx, dbName, repl::ReadConcernLevel::kMajorityReadConcern); + if (dbVersion->getUuid() != db.getVersion().getUuid()) { + // The database was dropped and re-created with a different UUID + return true; + } + } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) { + // The database was already dropped + return true; + } + } + return false; +} } // namespace @@ -264,18 +283,18 @@ ExecutorFuture<void> DropDatabaseCoordinator::_runImpl( sharding_ddl_util::performNoopMajorityWriteLocally(opCtx); // ensure we do not delete collections of a different DB - if (!_firstExecution && _doc.getDatabaseVersion()) { - try { - const auto db = catalogClient->getDatabase( - opCtx, _dbName, repl::ReadConcernLevel::kMajorityReadConcern); - if (_doc.getDatabaseVersion()->getUuid() != db.getVersion().getUuid()) { - VectorClockMutable::get(opCtx)->waitForDurableConfigTime().get(opCtx); - return; // skip to _flushDatabaseCacheUpdates - } - } catch (const ExceptionFor<ErrorCodes::NamespaceNotFound>&) { - VectorClockMutable::get(opCtx)->waitForDurableConfigTime().get(opCtx); - return; // skip to _flushDatabaseCacheUpdates - } + if (!_firstExecution && + isDbAlreadyDropped(opCtx, _doc.getDatabaseVersion(), _dbName)) { + // Clear the database sharding state so that all subsequent write operations + // with the old database version will fail due to StaleDbVersion. + // Note: because we are using an scoped critical section it could happen that + // the dbversion being deleted is recovered once we return. It is a rare + // occurence, but it might lead to a situation where the now former primary + // will believe to still be primary. + _clearDatabaseInfoOnPrimary(opCtx); + _clearDatabaseInfoOnSecondaries(opCtx); + VectorClockMutable::get(opCtx)->waitForDurableConfigTime().get(opCtx); + return; // skip to FlushDatabaseCacheUpdates } if (_doc.getCollInfo()) { |