diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/s/flush_database_cache_updates_command.cpp | 137 | ||||
-rw-r--r-- | src/mongo/s/request_types/flush_database_cache_updates.idl | 2 |
2 files changed, 69 insertions, 70 deletions
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 362c45dc8e8..5b70c6fede0 100644 --- a/src/mongo/db/s/flush_database_cache_updates_command.cpp +++ b/src/mongo/db/s/flush_database_cache_updates_command.cpp @@ -55,9 +55,9 @@ namespace mongo { namespace { -class FlushDatabaseCacheUpdates : public BasicCommand { +class FlushDatabaseCacheUpdatesCmd final : public TypedCommand<FlushDatabaseCacheUpdatesCmd> { public: - FlushDatabaseCacheUpdates() : BasicCommand("_flushDatabaseCacheUpdates") {} + using Request = _flushDatabaseCacheUpdates; std::string help() const override { return "Internal command which waits for any pending routing table cache updates for a " @@ -76,84 +76,83 @@ public: return AllowedOnSecondary::kNever; } - bool supportsWriteConcern(const BSONObj& cmd) const override { - return false; - } + class Invocation final : public InvocationBase { + public: + using InvocationBase::InvocationBase; - Status checkAuthForCommand(Client* client, - const std::string& dbname, - const BSONObj& cmdObj) const override { - if (!AuthorizationSession::get(client)->isAuthorizedForActionsOnResource( - ResourcePattern::forClusterResource(), ActionType::internal)) { - return Status(ErrorCodes::Unauthorized, "Unauthorized"); + /** + * ns() is the database to flush, with no collection. + */ + NamespaceString ns() const { + return NamespaceString(_dbName(), ""); } - return Status::OK(); - } - - void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) const override { - ActionSet actions; - actions.addAction(ActionType::internal); - out->push_back(Privilege(ResourcePattern::forClusterResource(), actions)); - } - bool run(OperationContext* opCtx, - const std::string& dbname, - const BSONObj& cmdObj, - BSONObjBuilder& result) override { - auto const shardingState = ShardingState::get(opCtx); - uassertStatusOK(shardingState->canAcceptShardedCommands()); - - uassert(ErrorCodes::IllegalOperation, - "Can't issue _flushDatabaseCacheUpdates from 'eval'", - !opCtx->getClient()->isInDirectClient()); - - uassert(ErrorCodes::IllegalOperation, - "Can't call _flushDatabaseCacheUpdates if in read-only mode", - !storageGlobalParams.readOnly); - - auto& oss = OperationShardingState::get(opCtx); - - const auto request = _flushDatabaseCacheUpdatesRequest::parse( - IDLParserErrorContext("_FlushDatabaseCacheUpdatesRequest"), cmdObj); - auto name = request.getCommandParameter().toString(); - - { - AutoGetDb autoDb(opCtx, name, MODE_IS); - if (!autoDb.getDb()) { - uasserted(ErrorCodes::NamespaceNotFound, - str::stream() << "Can't issue _flushDatabaseCacheUpdates on the database " - << name - << " because it does not exist on this shard."); - } + bool supportsWriteConcern() const override { + return false; + } - // If the primary is in the critical section, secondaries must wait for the commit to - // finish on the primary in case a secondary's caller has an afterClusterTime inclusive - // of the commit (and new writes to the committed chunk) that hasn't yet propagated back - // to this shard. This ensures the read your own writes causal consistency guarantee. - auto criticalSectionSignal = - DatabaseShardingState::get(autoDb.getDb()) - .getCriticalSectionSignal(ShardingMigrationCriticalSection::kRead); - if (criticalSectionSignal) { - oss.setMigrationCriticalSectionSignal(criticalSectionSignal); - } + void doCheckAuthorization(OperationContext* opCtx) const override { + uassert(ErrorCodes::Unauthorized, + "Unauthorized", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::internal)); } - oss.waitForMigrationCriticalSectionSignal(opCtx); + void typedRun(OperationContext* opCtx) { + auto const shardingState = ShardingState::get(opCtx); + uassertStatusOK(shardingState->canAcceptShardedCommands()); + + uassert(ErrorCodes::IllegalOperation, + "Can't issue _flushDatabaseCacheUpdates from 'eval'", + !opCtx->getClient()->isInDirectClient()); + + uassert(ErrorCodes::IllegalOperation, + "Can't call _flushDatabaseCacheUpdates if in read-only mode", + !storageGlobalParams.readOnly); + + auto& oss = OperationShardingState::get(opCtx); + + { + AutoGetDb autoDb(opCtx, _dbName(), MODE_IS); + if (!autoDb.getDb()) { + uasserted(ErrorCodes::NamespaceNotFound, + str::stream() + << "Can't issue _flushDatabaseCacheUpdates on the database " + << _dbName() + << " because it does not exist on this shard."); + } + + // If the primary is in the critical section, secondaries must wait for the commit + // to finish on the primary in case a secondary's caller has an afterClusterTime + // inclusive of the commit (and new writes to the committed chunk) that hasn't yet + // propagated back to this shard. This ensures the read your own writes causal + // consistency guarantee. + auto criticalSectionSignal = + DatabaseShardingState::get(autoDb.getDb()) + .getCriticalSectionSignal(ShardingMigrationCriticalSection::kRead); + if (criticalSectionSignal) { + oss.setMigrationCriticalSectionSignal(criticalSectionSignal); + } + } - if (request.getSyncFromConfig()) { - LOG(1) << "Forcing remote routing table refresh for " << name; - forceDatabaseRefresh(opCtx, name); - } + oss.waitForMigrationCriticalSectionSignal(opCtx); - CatalogCacheLoader::get(opCtx).waitForDatabaseFlush(opCtx, name); + if (request().getSyncFromConfig()) { + LOG(1) << "Forcing remote routing table refresh for " << _dbName(); + forceDatabaseRefresh(opCtx, _dbName()); + } - repl::ReplClientInfo::forClient(opCtx->getClient()).setLastOpToSystemLastOpTime(opCtx); + CatalogCacheLoader::get(opCtx).waitForDatabaseFlush(opCtx, _dbName()); - return true; - } + repl::ReplClientInfo::forClient(opCtx->getClient()).setLastOpToSystemLastOpTime(opCtx); + } + private: + StringData _dbName() const { + return request().getCommandParameter(); + } + }; } _flushDatabaseCacheUpdatesCmd; } // namespace diff --git a/src/mongo/s/request_types/flush_database_cache_updates.idl b/src/mongo/s/request_types/flush_database_cache_updates.idl index 34f0a7e4973..2e0b764c9f2 100644 --- a/src/mongo/s/request_types/flush_database_cache_updates.idl +++ b/src/mongo/s/request_types/flush_database_cache_updates.idl @@ -33,7 +33,7 @@ imports: - "mongo/idl/basic_types.idl" commands: - _flushDatabaseCacheUpdatesRequest: + _flushDatabaseCacheUpdates: description: "An internal command to wait for the last routing table cache refresh for a particular database to be persisted to disk" strict: true namespace: type |