diff options
author | Antonio Fuschetto <antonio.fuschetto@mongodb.com> | 2022-08-29 08:06:59 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-08-29 08:50:14 +0000 |
commit | 6acc65f52de00bd9caa45e582e65a8669424b4dc (patch) | |
tree | 909e94e0c74895b8f9392704e8b3957a6e92973d | |
parent | 107d9c38caae897b7e99af3db4ec429039936c87 (diff) | |
download | mongo-6acc65f52de00bd9caa45e582e65a8669424b4dc.tar.gz |
SERVER-69108 SCCL can immediately return config and admin metadata without triggering a refresh
4 files changed, 54 insertions, 5 deletions
diff --git a/jstests/sharding/append_oplog_note_mongos.js b/jstests/sharding/append_oplog_note_mongos.js index 641ccf25c2b..1369ecb06be 100644 --- a/jstests/sharding/append_oplog_note_mongos.js +++ b/jstests/sharding/append_oplog_note_mongos.js @@ -41,11 +41,6 @@ assert(res.hasOwnProperty("raw"), res); appendOplogNoteFailpoint.wait(); appendOplogNoteFailpoint.off(); -// Force a database refresh on the sharding side so that the corresponding config.cache.databases -// entry is already in the oplog before we start issuing successful appendOplogNote commands. -assert.commandWorked(shardOnePrimary.adminCommand({_flushDatabaseCacheUpdates: "config"})); -assert.commandWorked(shardTwoPrimary.adminCommand({_flushDatabaseCacheUpdates: "config"})); - // Test that a successful 'appendOplogNote' command performs a no-op write and advances the // $clusterTime. const shardOneBefore = diff --git a/src/mongo/db/s/flush_database_cache_updates_command.cpp b/src/mongo/db/s/flush_database_cache_updates_command.cpp index e3a857fd57d..ff4837fdf16 100644 --- a/src/mongo/db/s/flush_database_cache_updates_command.cpp +++ b/src/mongo/db/s/flush_database_cache_updates_command.cpp @@ -37,6 +37,8 @@ #include "mongo/db/catalog_raii.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" +#include "mongo/db/database_name.h" +#include "mongo/db/dbdirectclient.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/s/database_sharding_state.h" @@ -54,6 +56,28 @@ namespace mongo { namespace { +/** + * Inserts a database collection entry with fixed metadata for the `config` or `admin` database. If + * the entry key already exists, it's not updated. + */ +Status insertDatabaseEntryForBackwardCompatibility(OperationContext* opCtx, + const DatabaseName& dbName) { + invariant(dbName == NamespaceString::kAdminDb || dbName == NamespaceString::kConfigDb); + + DBDirectClient client(opCtx); + auto commandResponse = client.runCommand([&] { + auto dbMetadata = + DatabaseType(dbName.toString(), ShardId::kConfigServerId, DatabaseVersion::makeFixed()); + + write_ops::InsertCommandRequest insertOp(NamespaceString::kShardConfigDatabasesNamespace); + insertOp.setDocuments({dbMetadata.toBSON()}); + return insertOp.serialize({}); + }()); + + auto commandStatus = getStatusFromWriteCommandReply(commandResponse->getCommandReply()); + return commandStatus.code() == ErrorCodes::DuplicateKey ? Status::OK() : commandStatus; +} + template <typename Derived> class FlushDatabaseCacheUpdatesCmdBase : public TypedCommand<Derived> { public: @@ -119,6 +143,26 @@ public: "Can't call _flushDatabaseCacheUpdates if in read-only mode", !opCtx->readOnly()); + if (_dbName() == NamespaceString::kAdminDb || _dbName() == NamespaceString::kConfigDb) { + // The admin and config databases have fixed metadata that does not need to be + // refreshed. + + if (Base::request().getSyncFromConfig()) { + // To ensure compatibility with old secondaries that still call the + // _flushDatabaseCacheUpdates command to get updated database metadata from + // primary, an entry with fixed metadata is inserted in the + // config.cache.databases collection. + + LOGV2_DEBUG(6910800, + 1, + "Inserting a database collection entry with fixed metadata", + "db"_attr = _dbName()); + uassertStatusOK(insertDatabaseEntryForBackwardCompatibility(opCtx, _dbName())); + } + + return; + } + boost::optional<SharedSemiFuture<void>> criticalSectionSignal; { diff --git a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp index 5debd090ab2..bcb67504217 100644 --- a/src/mongo/db/s/shard_filtering_metadata_refresh.cpp +++ b/src/mongo/db/s/shard_filtering_metadata_refresh.cpp @@ -65,6 +65,10 @@ void onDbVersionMismatch(OperationContext* opCtx, invariant(!opCtx->getClient()->isInDirectClient()); invariant(ShardingState::get(opCtx)->canAcceptShardedCommands()); + tassert(ErrorCodes::IllegalOperation, + "Can't check version of {} database"_format(dbName), + dbName != NamespaceString::kAdminDb && dbName != NamespaceString::kConfigDb); + Timer t{}; ScopeGuard finishTiming([&] { CurOp::get(opCtx)->debug().databaseVersionRefreshMillis += Milliseconds(t.millis()); diff --git a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp index 22e0710f6d3..cbc44c21b03 100644 --- a/src/mongo/db/s/shard_server_catalog_cache_loader.cpp +++ b/src/mongo/db/s/shard_server_catalog_cache_loader.cpp @@ -456,6 +456,12 @@ SemiFuture<CollectionAndChangedChunks> ShardServerCatalogCacheLoader::getChunksS } SemiFuture<DatabaseType> ShardServerCatalogCacheLoader::getDatabase(StringData dbName) { + // The admin and config database have fixed metadata that does not need to be refreshed. + if (dbName == NamespaceString::kAdminDb || dbName == NamespaceString::kConfigDb) { + return DatabaseType( + dbName.toString(), ShardId::kConfigServerId, DatabaseVersion::makeFixed()); + } + const auto [isPrimary, term] = [&] { stdx::lock_guard<Latch> lock(_mutex); return std::make_tuple(_role == ReplicaSetRole::Primary, _term); |