summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorEsha Maharishi <esha.maharishi@mongodb.com>2018-04-13 15:15:11 -0400
committerEsha Maharishi <esha.maharishi@mongodb.com>2018-04-13 18:27:07 -0400
commit5cd2a79f61b189db1330322e406b8c33960f2d24 (patch)
tree7fbc5f1ee1de85f1b268697efeb4c431d4e79a9d /src/mongo/db
parent4174e073c93e6023c4ba6243d60e40f30f809d52 (diff)
downloadmongo-5cd2a79f61b189db1330322e406b8c33960f2d24.tar.gz
SERVER-34459 Clear in-memory database versions on setFCV downgrade on shard primaries and secondaries
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/commands/feature_compatibility_version.cpp24
-rw-r--r--src/mongo/db/s/SConscript1
-rw-r--r--src/mongo/db/s/shard_filtering_metadata_refresh.cpp63
3 files changed, 58 insertions, 30 deletions
diff --git a/src/mongo/db/commands/feature_compatibility_version.cpp b/src/mongo/db/commands/feature_compatibility_version.cpp
index 2216c24dd6d..932f8d29553 100644
--- a/src/mongo/db/commands/feature_compatibility_version.cpp
+++ b/src/mongo/db/commands/feature_compatibility_version.cpp
@@ -33,6 +33,7 @@
#include "mongo/db/commands/feature_compatibility_version.h"
#include "mongo/base/status.h"
+#include "mongo/db/catalog_raii.h"
#include "mongo/db/commands/feature_compatibility_version_documentation.h"
#include "mongo/db/commands/feature_compatibility_version_parser.h"
#include "mongo/db/dbdirectclient.h"
@@ -41,6 +42,7 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/optime.h"
#include "mongo/db/repl/storage_interface.h"
+#include "mongo/db/s/database_sharding_state.h"
#include "mongo/db/server_parameters.h"
#include "mongo/db/service_context.h"
#include "mongo/db/storage/storage_engine.h"
@@ -154,12 +156,30 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons
<< FeatureCompatibilityVersionParser::toString(newVersion);
}
- // On commit, update the server parameters, close any connections with a wire version that is
- // below the minimum, and abort any open transactions if downgrading.
opCtx->recoveryUnit()->onCommit([opCtx, newVersion]() {
serverGlobalParams.featureCompatibility.setVersion(newVersion);
updateMinWireVersion();
+ if (newVersion == ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo36) {
+ // Clear the in-memory cached database versions on downgrade, so that we do not check
+ // databaseVersion in FCV 3.6 (it would be meaningless, since databases do not have
+ // versions in FCV 3.6).
+ // TODO: Once SERVER-34431 goes in, just clear the DatabaseShardingStateMap.
+ std::vector<std::string> dbNames;
+ getGlobalServiceContext()->getGlobalStorageEngine()->listDatabases(&dbNames);
+ for (const auto& dbName : dbNames) {
+ if (dbName == "admin") {
+ // The 'admin' database is already locked, since the FCV document is in
+ // admin.system.version. Just skip 'admin', since it is not versioned.
+ continue;
+ }
+ AutoGetDb autoDb(opCtx, dbName, MODE_X);
+ if (autoDb.getDb()) {
+ DatabaseShardingState::get(autoDb.getDb()).setDbVersion(opCtx, boost::none);
+ }
+ }
+ }
+
if (newVersion != ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo36) {
// Close all incoming connections from internal clients with binary versions lower than
// ours.
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