diff options
author | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-04-13 15:15:11 -0400 |
---|---|---|
committer | Esha Maharishi <esha.maharishi@mongodb.com> | 2018-04-13 18:27:07 -0400 |
commit | 5cd2a79f61b189db1330322e406b8c33960f2d24 (patch) | |
tree | 7fbc5f1ee1de85f1b268697efeb4c431d4e79a9d /src/mongo/db/s | |
parent | 4174e073c93e6023c4ba6243d60e40f30f809d52 (diff) | |
download | mongo-5cd2a79f61b189db1330322e406b8c33960f2d24.tar.gz |
SERVER-34459 Clear in-memory database versions on setFCV downgrade on shard primaries and secondaries
Diffstat (limited to 'src/mongo/db/s')
-rw-r--r-- | src/mongo/db/s/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/s/shard_filtering_metadata_refresh.cpp | 63 |
2 files changed, 36 insertions, 28 deletions
diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 6c43720e075..0c3d7918cb6 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -55,6 +55,7 @@ env.Library( 'split_vector.cpp', ], LIBDEPS=[ + '$BUILD_DIR/mongo/db/commands/mongod_fcv', '$BUILD_DIR/mongo/db/db_raii', '$BUILD_DIR/mongo/db/dbhelpers', '$BUILD_DIR/mongo/db/repl/oplog', diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp index e641d43578e..cc3e9533ecb 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp @@ -34,6 +34,7 @@ #include "mongo/db/catalog/database_holder.h" #include "mongo/db/catalog_raii.h" +#include "mongo/db/commands/feature_compatibility_version.h" #include "mongo/db/operation_context.h" #include "mongo/db/s/collection_sharding_state.h" #include "mongo/db/s/database_sharding_state.h" @@ -200,13 +201,39 @@ void forceDatabaseRefresh(OperationContext* opCtx, const StringData dbName) { uassertStatusOK(Grid::get(opCtx)->catalogCache()->getDatabaseWithRefresh(opCtx, dbName)) .databaseVersion(); - // First, check under a shared lock if another thread already updated the cached version. - // This is a best-effort optimization to make as few threads as possible to convoy on the - // exclusive lock below. - { - // Take the DBLock directly rather than using AutoGetDb, to prevent a recursive call - // into checkDbVersion(). - Lock::DBLock dbLock(opCtx, dbName, MODE_IS); + // Only set the in-memory version in FCV 4.0, and hold the lock across checking the FCV and + // setting the version. + Lock::SharedLock lk(opCtx->lockState(), FeatureCompatibilityVersion::fcvLock); + if (serverGlobalParams.featureCompatibility.getVersion() == + ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo40) { + // First, check under a shared lock if another thread already updated the cached version. + // This is a best-effort optimization to make as few threads as possible to convoy on the + // exclusive lock below. + { + // Take the DBLock directly rather than using AutoGetDb, to prevent a recursive call + // into checkDbVersion(). + Lock::DBLock dbLock(opCtx, dbName, MODE_IS); + const auto db = dbHolder().get(opCtx, dbName); + if (!db) { + log() << "Database " << dbName + << " has been dropped; not caching the refreshed databaseVersion"; + return; + } + + const auto cachedDbVersion = DatabaseShardingState::get(db).getDbVersion(opCtx); + if (cachedDbVersion && refreshedDbVersion && + cachedDbVersion->getUuid() == refreshedDbVersion->getUuid() && + cachedDbVersion->getLastMod() >= refreshedDbVersion->getLastMod()) { + LOG(2) << "Skipping setting cached databaseVersion for " << dbName + << " to refreshed version " << refreshedDbVersion->toBSON() + << " because current cached databaseVersion is already " + << cachedDbVersion->toBSON(); + return; + } + } + + // The cached version is older than the refreshed version; update the cached version. + Lock::DBLock dbLock(opCtx, dbName, MODE_X); const auto db = dbHolder().get(opCtx, dbName); if (!db) { log() << "Database " << dbName @@ -214,28 +241,8 @@ void forceDatabaseRefresh(OperationContext* opCtx, const StringData dbName) { return; } - const auto cachedDbVersion = DatabaseShardingState::get(db).getDbVersion(opCtx); - if (cachedDbVersion && refreshedDbVersion && - cachedDbVersion->getUuid() == refreshedDbVersion->getUuid() && - cachedDbVersion->getLastMod() >= refreshedDbVersion->getLastMod()) { - LOG(2) << "Skipping setting cached databaseVersion for " << dbName - << " to refreshed version " << refreshedDbVersion->toBSON() - << " because current cached databaseVersion is already " - << cachedDbVersion->toBSON(); - return; - } + DatabaseShardingState::get(db).setDbVersion(opCtx, std::move(refreshedDbVersion)); } - - // The cached version is older than the refreshed version; update the cached version. - Lock::DBLock dbLock(opCtx, dbName, MODE_X); - const auto db = dbHolder().get(opCtx, dbName); - if (!db) { - log() << "Database " << dbName - << " has been dropped; not caching the refreshed databaseVersion"; - return; - } - - DatabaseShardingState::get(db).setDbVersion(opCtx, std::move(refreshedDbVersion)); } } // namespace mongo |