Skip to content

Commit 751e985

Browse files
committed
SERVER-34483 Avoid taking DBLocks when clearing in-memory database cache in FCV op observer
1 parent a39601e commit 751e985

File tree

4 files changed

+22
-26
lines changed

4 files changed

+22
-26
lines changed

jstests/sharding/database_versioning_upgrade_downgrade.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
assert.eq(null, db1EntryOriginal.version);
3333
assert.eq(null, db2EntryOriginal.version);
3434

35-
// Ensure the shard does not have a cached entries in-memory or on-disk.
35+
// Ensure the shard does not have cached entries in-memory or on-disk.
3636
checkInMemoryDatabaseVersion(st.rs0.getPrimary(), db1Name, {});
3737
checkInMemoryDatabaseVersion(st.rs0.getSecondary(), db1Name, {});
3838
checkInMemoryDatabaseVersion(st.rs0.getPrimary(), db2Name, {});
@@ -104,10 +104,9 @@
104104
assert.docEq(db1EntryOriginal, db1EntryFCV36);
105105
assert.docEq(db2EntryOriginal, db2EntryFCV36);
106106

107-
// The shard's in-memory database cache should have been cleared, but its on-disk cache left
108-
// untouched.
109-
checkInMemoryDatabaseVersion(st.rs0.getPrimary(), db1Name, {});
110-
checkInMemoryDatabaseVersion(st.rs0.getSecondary(), db1Name, {});
107+
// The shard's in-memory and on-disk database caches should have been left untouched.
108+
checkInMemoryDatabaseVersion(st.rs0.getPrimary(), db1Name, db1EntryFCV40.version);
109+
checkInMemoryDatabaseVersion(st.rs0.getSecondary(), db1Name, db1EntryFCV40.version);
111110
checkInMemoryDatabaseVersion(st.rs0.getPrimary(), db2Name, {});
112111
checkInMemoryDatabaseVersion(st.rs0.getSecondary(), db2Name, {});
113112
checkOnDiskDatabaseVersion(st.shard0, db1Name, db1EntryFCV40);

src/mongo/db/commands/feature_compatibility_version.cpp

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
#include "mongo/db/operation_context.h"
4343
#include "mongo/db/repl/optime.h"
4444
#include "mongo/db/repl/storage_interface.h"
45-
#include "mongo/db/s/database_sharding_state.h"
45+
#include "mongo/db/s/collection_sharding_state.h"
4646
#include "mongo/db/s/sharding_state.h"
4747
#include "mongo/db/server_parameters.h"
4848
#include "mongo/db/service_context.h"
@@ -167,26 +167,7 @@ void FeatureCompatibilityVersion::onInsertOrUpdate(OperationContext* opCtx, cons
167167
(newVersion ==
168168
ServerGlobalParams::FeatureCompatibility::Version::kFullyDowngradedTo36 ||
169169
newVersion == ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo40)) {
170-
// Clear the in-memory cached database versions and collections metadata.
171-
// TODO: Once SERVER-34431 goes in, just clear the DatabaseShardingStateMap.
172-
std::vector<std::string> dbNames;
173-
getGlobalServiceContext()->getGlobalStorageEngine()->listDatabases(&dbNames);
174-
for (const auto& dbName : dbNames) {
175-
if (dbName == "admin") {
176-
// The 'admin' database is already locked, since the FCV document is in
177-
// admin.system.version. Just skip 'admin', since it is not versioned.
178-
continue;
179-
}
180-
AutoGetDb autoDb(opCtx, dbName, MODE_X);
181-
if (autoDb.getDb()) {
182-
DatabaseShardingState::get(autoDb.getDb()).setDbVersion(opCtx, boost::none);
183-
for (const auto& collection : *autoDb.getDb()) {
184-
CollectionShardingState::get(opCtx, collection->ns())
185-
->refreshMetadata(opCtx, nullptr);
186-
}
187-
}
188-
}
189-
170+
CollectionShardingState::resetAll(opCtx);
190171
Grid::get(opCtx)->catalogCache()->purgeAllDatabases();
191172
}
192173

src/mongo/db/s/collection_sharding_state.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,16 @@ class CollectionShardingStateMap {
124124
return *it->second;
125125
}
126126

127+
void resetAll() {
128+
stdx::lock_guard<stdx::mutex> lg(_mutex);
129+
for (auto it = _collections.begin(); it != _collections.end(); ++it) {
130+
// This is a hack to get around CollectionShardingState::refreshMetadata() requiring
131+
// the X lock: markNotShardedAtStepdown() doesn't have a lock check. Temporary
132+
// measure until SERVER-31595 removes the X lock requirement.
133+
it->second->markNotShardedAtStepdown();
134+
}
135+
}
136+
127137
void report(OperationContext* opCtx, BSONObjBuilder* builder) {
128138
BSONObjBuilder versionB(builder->subobjStart("versions"));
129139

@@ -175,6 +185,11 @@ CollectionShardingState* CollectionShardingState::get(OperationContext* opCtx,
175185
return &collectionsMap.getOrCreate(ns);
176186
}
177187

188+
void CollectionShardingState::resetAll(OperationContext* opCtx) {
189+
auto& collectionsMap = CollectionShardingStateMap::get(opCtx->getServiceContext());
190+
collectionsMap.resetAll();
191+
}
192+
178193
void CollectionShardingState::report(OperationContext* opCtx, BSONObjBuilder* builder) {
179194
auto& collectionsMap = CollectionShardingStateMap::get(opCtx->getServiceContext());
180195
collectionsMap.report(opCtx, builder);

src/mongo/db/s/collection_sharding_state.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class CollectionShardingState : public Decorable<CollectionShardingState> {
7171
static CollectionShardingState* get(OperationContext* opCtx, const NamespaceString& nss);
7272
static CollectionShardingState* get(OperationContext* opCtx, const std::string& ns);
7373

74+
static void resetAll(OperationContext* opCtx);
7475
static void report(OperationContext* opCtx, BSONObjBuilder* builder);
7576

7677
/**

0 commit comments

Comments
 (0)