diff options
author | Antonio Fuschetto <antonio.fuschetto@mongodb.com> | 2022-11-10 17:11:11 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-10 17:38:11 +0000 |
commit | 1b3b0073a0b436a8a502b612f24fb2bd572772e5 (patch) | |
tree | 6d2fb59050d244596502e5b37526acb45c9263f4 | |
parent | ec65af7e2185c7e266bc6a04ea7777eea713fa58 (diff) | |
download | mongo-1b3b0073a0b436a8a502b612f24fb2bd572772e5.tar.gz |
SERVER-70793 Make database metadata refresh first check new metadata under the IS lock before taking X lockr5.0.14-rc0r5.0.14
-rw-r--r-- | src/mongo/db/s/shard_filtering_metadata_refresh.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp index 55997b65ad0..2938a78867b 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp @@ -149,6 +149,40 @@ Status refreshDbMetadata(OperationContext* opCtx, const auto swDbMetadata = Grid::get(opCtx)->catalogCache()->getDatabaseWithRefresh(opCtx, dbName); + // Before setting the database metadata, exit early if the database version received by the + // config server is not newer than the cached one. This is a best-effort optimization to reduce + // the number of possible threads convoying on the exclusive lock below. + if (swDbMetadata.isOK()) { + Lock::DBLock dbLock(opCtx, dbName, MODE_IS); + auto* dss = DatabaseShardingState::get(opCtx, dbName); + auto dssLock = DatabaseShardingState::DSSLock::lockShared(opCtx, dss); + + if (const auto cachedDbVersion = dss->getDbVersion(opCtx, dssLock)) { + const auto refreshedDbVersion = swDbMetadata.getValue().databaseVersion(); + + // Do not reorder these two statements! If the comparison is done through epochs, the + // construction order matters: we are pessimistically assuming that the refreshed + // version is newer when they have different UUIDs. + const ComparableDatabaseVersion comparableCachedDbVersion = + ComparableDatabaseVersion::makeComparableDatabaseVersion(cachedDbVersion); + const ComparableDatabaseVersion comparableRefreshedDbVersion = + ComparableDatabaseVersion::makeComparableDatabaseVersion(refreshedDbVersion); + + if (comparableRefreshedDbVersion < comparableCachedDbVersion || + (comparableRefreshedDbVersion == comparableCachedDbVersion && + refreshedDbVersion.getTimestamp() == cachedDbVersion->getTimestamp())) { + LOGV2_DEBUG(7079300, + 2, + "Skip setting cached database metadata as there are no updates", + "db"_attr = dbName, + "cachedDbVersion"_attr = *cachedDbVersion, + "refreshedDbVersion"_attr = refreshedDbVersion); + + return Status::OK(); + } + } + } + Lock::DBLock dbLock(opCtx, dbName, MODE_X); auto* dss = DatabaseShardingState::get(opCtx, dbName); auto dssLock = DatabaseShardingState::DSSLock::lockExclusive(opCtx, dss); |