diff options
author | Yoonsoo Kim <yoonsoo.kim@mongodb.com> | 2021-08-04 02:00:00 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-04 02:59:35 +0000 |
commit | d356d2ed92812367bb2f61495f2ec064cad5a021 (patch) | |
tree | a21a7433c2ba9c641ae7991b8d518fe6c83ffb91 /src | |
parent | bd221c2a5bfd2014bf1df08bb5497a5ee24650e2 (diff) | |
download | mongo-d356d2ed92812367bb2f61495f2ec064cad5a021.tar.gz |
SERVER-58735 Repurpose LastError for NotPrimaryError tracker
Diffstat (limited to 'src')
22 files changed, 87 insertions, 183 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index cf5fe18de9c..6c1fd4eb364 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -505,9 +505,9 @@ env.Library( ) env.Library( - target='lasterror', + target='not_primary_error_tracker', source=[ - "lasterror.cpp", + "not_primary_error_tracker.cpp", ], LIBDEPS=[ 'service_context', @@ -705,7 +705,7 @@ env.Library( 'catalog_raii', 'curop_failpoint_helpers', 'dbdirectclient', - 'lasterror', + 'not_primary_error_tracker', 'query_exec', 'repl/repl_server_parameters', 'stats/fill_locker_info', @@ -723,7 +723,7 @@ env.Library( LIBDEPS=[ '$BUILD_DIR/mongo/client/clientdriver_minimal', 'curop', - 'lasterror', + 'not_primary_error_tracker', 'ops/write_ops_parsers', ], LIBDEPS_PRIVATE=[ @@ -781,7 +781,7 @@ env.Library( 'command_can_run_here', 'commands/fsync_locked', 'concurrency/lock_manager', - 'lasterror', + 'not_primary_error_tracker', 'read_concern_d_impl', 's/sharding_runtime_d', 'service_entry_point_common', @@ -893,7 +893,7 @@ env.Library( 'commands/server_status_core', 'initialize_api_parameters', 'introspect', - 'lasterror', + 'not_primary_error_tracker', 'query_exec', 'repl/repl_server_parameters', 'repl/replica_set_messages', @@ -1306,7 +1306,7 @@ env.Library( '$BUILD_DIR/mongo/db/commands/server_status_core', '$BUILD_DIR/mongo/db/stats/resource_consumption_metrics', 'kill_sessions', - 'lasterror', + 'not_primary_error_tracker', 'record_id_helpers', ], ) diff --git a/src/mongo/db/commands/write_commands.cpp b/src/mongo/db/commands/write_commands.cpp index 2e78a91a7c3..267a6bf1aa9 100644 --- a/src/mongo/db/commands/write_commands.cpp +++ b/src/mongo/db/commands/write_commands.cpp @@ -41,10 +41,10 @@ #include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/json.h" -#include "mongo/db/lasterror.h" #include "mongo/db/matcher/doc_validation_error.h" #include "mongo/db/matcher/extensions_callback_real.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/ops/delete_request_gen.h" #include "mongo/db/ops/parsed_delete.h" #include "mongo/db/ops/parsed_update.h" @@ -527,7 +527,7 @@ public: return insertReply; } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } @@ -541,7 +541,7 @@ public: request().getBypassDocumentValidation(), request()); } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } @@ -1196,7 +1196,7 @@ public: return updateReply; } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } @@ -1206,7 +1206,7 @@ public: request().getBypassDocumentValidation(), request()); } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } @@ -1353,7 +1353,7 @@ public: return deleteReply; } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } @@ -1363,7 +1363,7 @@ public: request().getBypassDocumentValidation(), request()); } catch (const DBException& ex) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); throw; } diff --git a/src/mongo/db/lasterror.cpp b/src/mongo/db/not_primary_error_tracker.cpp index 396e707efb4..c9aaca76bd5 100644 --- a/src/mongo/db/lasterror.cpp +++ b/src/mongo/db/not_primary_error_tracker.cpp @@ -29,72 +29,35 @@ #include "mongo/platform/basic.h" -#include <boost/algorithm/string.hpp> - -#include "mongo/db/lasterror.h" - -#include "mongo/db/jsobj.h" -#include "mongo/util/assert_util.h" +#include "mongo/db/not_primary_error_tracker.h" namespace mongo { -const Client::Decoration<LastError> LastError::get = Client::declareDecoration<LastError>(); - -namespace { -void appendDupKeyFields(BSONObjBuilder& builder, std::string errMsg) { - // errMsg format for duplicate key errors: - // "E11000 duplicate key error collection: test.coll index: a_1 dup key: { a: 1.0 }", - std::vector<std::string> results; - boost::split(results, errMsg, [](char c) { return c == ' '; }); - auto collName = results[5]; - auto indexName = results[7]; - builder.append("ns", collName); - builder.append("index", indexName); -} -} // namespace +const Client::Decoration<NotPrimaryErrorTracker> NotPrimaryErrorTracker::get = + Client::declareDecoration<NotPrimaryErrorTracker>(); -void LastError::reset(bool valid) { - *this = LastError(); +void NotPrimaryErrorTracker::reset(bool valid) { + *this = NotPrimaryErrorTracker(); _valid = valid; } -void LastError::setLastError(int code, std::string msg) { +void NotPrimaryErrorTracker::recordError(int code) { if (_disabled) { return; } reset(true); - _code = code; - _msg = std::move(msg); - - if (ErrorCodes::isNotPrimaryError(ErrorCodes::Error(_code))) - _hadNotPrimaryError = true; -} - -void LastError::recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId) { - reset(true); - _nObjects = nObjects; - _updatedExisting = updateObjects ? True : False; - - // We record updates containing decimal data even if decimal is disabled. - if (upsertedId.valid() && upsertedId.hasField(kUpsertedFieldName)) - _upsertedId = upsertedId; -} - -void LastError::recordDelete(long long nDeleted) { - reset(true); - _nObjects = nDeleted; + if (ErrorCodes::isNotPrimaryError(ErrorCodes::Error(code))) + _hadError = true; } -void LastError::disable() { +void NotPrimaryErrorTracker::disable() { invariant(!_disabled); _disabled = true; - _nPrev--; // caller is a command that shouldn't count as an operation } -void LastError::startRequest() { +void NotPrimaryErrorTracker::startRequest() { _disabled = false; - ++_nPrev; - _hadNotPrimaryError = false; + _hadError = false; } } // namespace mongo diff --git a/src/mongo/db/lasterror.h b/src/mongo/db/not_primary_error_tracker.h index 6eff2f08ef0..f3dee23cd4a 100644 --- a/src/mongo/db/lasterror.h +++ b/src/mongo/db/not_primary_error_tracker.h @@ -29,19 +29,16 @@ #pragma once -#include <string> - #include "mongo/db/client.h" -#include "mongo/db/jsobj.h" namespace mongo { class BSONObjBuilder; static const char kUpsertedFieldName[] = "upserted"; -class LastError { +class NotPrimaryErrorTracker { public: - static const Client::Decoration<LastError> get; + static const Client::Decoration<NotPrimaryErrorTracker> get; /** * Resets the object to a newly constructed state. If "valid" is true, marks the last-error @@ -60,54 +57,38 @@ public: void disable(); /** - * Sets the error information for the current operation, if error recording was not - * explicitly disabled via a call to disable() since the call to startRequest. + * Records the error if the error can be categorized as "NotPrimaryError". */ - void setLastError(int code, std::string msg); - - void recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId); - - void recordDelete(long long nDeleted); + void recordError(int code); bool isValid() const { return _valid; } - int getNPrev() const { - return _nPrev; - } - bool hadNotPrimaryError() const { - return _hadNotPrimaryError; + bool hadError() const { + return _hadError; } class Disabled { public: - explicit Disabled(LastError* le) : _le(le), _prev(le->_disabled) { - _le->_disabled = true; + explicit Disabled(NotPrimaryErrorTracker* tracker) + : _tracker(tracker), _prev(tracker->_disabled) { + _tracker->_disabled = true; } ~Disabled() { - _le->_disabled = _prev; + _tracker->_disabled = _prev; } private: - LastError* const _le; + NotPrimaryErrorTracker* const _tracker; const bool _prev; }; private: - enum UpdatedExistingType { NotUpdate, True, False }; - - int _code = 0; - std::string _msg = {}; - UpdatedExistingType _updatedExisting = NotUpdate; - // _id field value from inserted doc, returned as kUpsertedFieldName (above) - BSONObj _upsertedId = {}; - long long _nObjects = 0; - int _nPrev = 1; bool _valid = false; bool _disabled = false; - bool _hadNotPrimaryError = false; + bool _hadError = false; }; } // namespace mongo diff --git a/src/mongo/db/ops/update_result.cpp b/src/mongo/db/ops/update_result.cpp index dd4ed0c127b..762ff704e06 100644 --- a/src/mongo/db/ops/update_result.cpp +++ b/src/mongo/db/ops/update_result.cpp @@ -34,7 +34,7 @@ #include "mongo/db/ops/update_result.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/logv2/log.h" #include "mongo/util/str.h" diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 008feac6177..c08c854a2f2 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -50,8 +50,8 @@ #include "mongo/db/exec/delete.h" #include "mongo/db/exec/update_stage.h" #include "mongo/db/introspect.h" -#include "mongo/db/lasterror.h" #include "mongo/db/matcher/extensions_callback_real.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/ops/delete_request_gen.h" #include "mongo/db/ops/insert.h" #include "mongo/db/ops/parsed_delete.h" @@ -254,7 +254,7 @@ bool handleError(OperationContext* opCtx, const write_ops::WriteCommandRequestBase& wholeOp, bool isMultiUpdate, WriteResult* out) { - LastError::get(opCtx->getClient()).setLastError(ex.code(), ex.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code()); auto& curOp = *CurOp::get(opCtx); curOp.debug().errInfo = ex.toStatus(); @@ -801,9 +801,6 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx, const bool didInsert = !updateResult.upsertedId.isEmpty(); const long long nMatchedOrInserted = didInsert ? 1 : updateResult.numMatched; - LastError::get(opCtx->getClient()) - .recordUpdate(updateResult.existing, nMatchedOrInserted, updateResult.upsertedId); - SingleWriteResult result; result.setN(nMatchedOrInserted); result.setNModified(updateResult.numDocsModified); @@ -1171,8 +1168,6 @@ static SingleWriteResult performSingleDeleteOp(OperationContext* opCtx, curOp.debug().execStats = std::move(stats); } - LastError::get(opCtx->getClient()).recordDelete(nDeleted); - SingleWriteResult result; result.setN(nDeleted); return result; diff --git a/src/mongo/db/ops/write_ops_exec.h b/src/mongo/db/ops/write_ops_exec.h index acbeae17ced..031003b5138 100644 --- a/src/mongo/db/ops/write_ops_exec.h +++ b/src/mongo/db/ops/write_ops_exec.h @@ -64,9 +64,10 @@ struct WriteResult { * counters, managing CurOp, and of course actually doing the write. Waiting for the writeConcern is * *not* handled by these functions and is expected to be done by the caller if needed. * - * LastError is updated for failures of individual writes, but not for batch errors reported by an - * exception being thrown from these functions. Callers are responsible for managing LastError in - * that case. This should generally be combined with LastError handling from parse failures. + * NotPrimaryErrorTracker is updated for failures of individual writes, but not for batch errors + * reported by an exception being thrown from these functions. Callers are responsible for managing + * NotPrimaryErrorTracker in that case. This should generally be combined with + * NotPrimaryErrorTracker handling from parse failures. * * 'type' indicates whether the operation was induced by a standard write, a chunk migration, or a * time-series insert. diff --git a/src/mongo/db/repl/SConscript b/src/mongo/db/repl/SConscript index 84dd97d8902..e77bb652917 100644 --- a/src/mongo/db/repl/SConscript +++ b/src/mongo/db/repl/SConscript @@ -853,7 +853,7 @@ env.Library( '$BUILD_DIR/mongo/db/auth/authprivilege', '$BUILD_DIR/mongo/db/commands', '$BUILD_DIR/mongo/db/commands/test_commands_enabled', - '$BUILD_DIR/mongo/db/lasterror', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', 'repl_coordinator_interface', ], LIBDEPS_PRIVATE=[ @@ -876,7 +876,7 @@ env.Library( '$BUILD_DIR/mongo/db/commands/test_commands_enabled', '$BUILD_DIR/mongo/db/concurrency/lock_manager', '$BUILD_DIR/mongo/db/dbhelpers', - '$BUILD_DIR/mongo/db/lasterror', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', '$BUILD_DIR/mongo/db/storage/storage_options', 'drop_pending_collection_reaper', 'repl_coordinator_interface', @@ -1415,8 +1415,8 @@ env.Library( '$BUILD_DIR/mongo/db/curop', '$BUILD_DIR/mongo/db/free_mon/free_mon_mongod', '$BUILD_DIR/mongo/db/kill_sessions_local', - '$BUILD_DIR/mongo/db/lasterror', '$BUILD_DIR/mongo/db/logical_time', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', '$BUILD_DIR/mongo/db/op_observer', '$BUILD_DIR/mongo/db/query_exec', '$BUILD_DIR/mongo/db/service_context', diff --git a/src/mongo/db/repl/repl_set_get_status_cmd.cpp b/src/mongo/db/repl/repl_set_get_status_cmd.cpp index 4fcd45073f4..0860f2f97f7 100644 --- a/src/mongo/db/repl/repl_set_get_status_cmd.cpp +++ b/src/mongo/db/repl/repl_set_get_status_cmd.cpp @@ -28,7 +28,7 @@ */ #include "mongo/bson/util/bson_extract.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/repl/repl_set_command.h" #include "mongo/db/repl/replication_coordinator.h" @@ -50,7 +50,7 @@ public: const BSONObj& cmdObj, BSONObjBuilder& result) override { if (cmdObj["forShell"].trueValue()) - LastError::get(opCtx->getClient()).disable(); + NotPrimaryErrorTracker::get(opCtx->getClient()).disable(); Status status = ReplicationCoordinator::get(opCtx)->checkReplEnabledForCommand(&result); uassertStatusOK(status); diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp index e0df47b07c4..4b831bb935e 100644 --- a/src/mongo/db/repl/replication_info.cpp +++ b/src/mongo/db/repl/replication_info.cpp @@ -46,9 +46,9 @@ #include "mongo/db/dbhelpers.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/jsobj.h" -#include "mongo/db/lasterror.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/ops/write_ops.h" #include "mongo/db/query/internal_plans.h" #include "mongo/db/read_write_concern_defaults.h" @@ -315,7 +315,7 @@ public: authenticated. */ if (cmd.getForShell()) { - LastError::get(opCtx->getClient()).disable(); + NotPrimaryErrorTracker::get(opCtx->getClient()).disable(); } transport::Session::TagMask sessionTagsToSet = 0; diff --git a/src/mongo/db/s/SConscript b/src/mongo/db/s/SConscript index 30f4319bb4a..8e20dabb18f 100644 --- a/src/mongo/db/s/SConscript +++ b/src/mongo/db/s/SConscript @@ -200,7 +200,7 @@ env.Library( '$BUILD_DIR/mongo/db/commands/server_status', '$BUILD_DIR/mongo/db/commands/txn_cmd_request', '$BUILD_DIR/mongo/db/dbdirectclient', - '$BUILD_DIR/mongo/db/lasterror', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', '$BUILD_DIR/mongo/db/repl/wait_for_majority_service', '$BUILD_DIR/mongo/db/rw_concern_d', '$BUILD_DIR/mongo/db/transaction', diff --git a/src/mongo/db/s/set_shard_version_command.cpp b/src/mongo/db/s/set_shard_version_command.cpp index 608289cc0fe..9fa4fd152a0 100644 --- a/src/mongo/db/s/set_shard_version_command.cpp +++ b/src/mongo/db/s/set_shard_version_command.cpp @@ -38,7 +38,7 @@ #include "mongo/db/catalog_raii.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/operation_context.h" #include "mongo/db/repl/replication_coordinator.h" #include "mongo/db/s/collection_sharding_runtime.h" @@ -114,7 +114,7 @@ public: // Step 1 Client* client = opCtx->getClient(); - LastError::get(client).disable(); + NotPrimaryErrorTracker::get(client).disable(); const bool authoritative = cmdObj.getBoolField("authoritative"); diff --git a/src/mongo/db/service_entry_point_common.cpp b/src/mongo/db/service_entry_point_common.cpp index 7d7320f9f25..ae999a37ff0 100644 --- a/src/mongo/db/service_entry_point_common.cpp +++ b/src/mongo/db/service_entry_point_common.cpp @@ -57,10 +57,10 @@ #include "mongo/db/initialize_operation_session_info.h" #include "mongo/db/introspect.h" #include "mongo/db/jsobj.h" -#include "mongo/db/lasterror.h" #include "mongo/db/logical_session_id.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/logical_time_validator.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/ops/write_ops.h" #include "mongo/db/ops/write_ops_exec.h" #include "mongo/db/query/find.h" @@ -225,7 +225,7 @@ struct HandleRequest { }; void registerError(OperationContext* opCtx, const Status& status) { - LastError::get(opCtx->getClient()).setLastError(status.code(), status.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(status.code()); CurOp::get(opCtx)->debug().errInfo = status; } @@ -1352,10 +1352,10 @@ void ExecCommandDatabase::_initiateCommand() { if (CommandHelpers::isHelpRequest(helpField)) { CurOp::get(opCtx)->ensureStarted(); - // We disable last-error for help requests due to SERVER-11492, because config servers use - // help requests to determine which commands are database writes, and so must be forwarded - // to all config servers. - LastError::get(opCtx->getClient()).disable(); + // We disable not-primary-error tracker for help requests due to SERVER-11492, because + // config servers use help requests to determine which commands are database writes, and so + // must be forwarded to all config servers. + NotPrimaryErrorTracker::get(opCtx->getClient()).disable(); Command::generateHelpResponse(opCtx, replyBuilder, *command); iassert(Status(ErrorCodes::SkipCommandExecution, "Skipping command execution for help request")); @@ -1828,7 +1828,7 @@ DbResponse makeCommandResponse(std::shared_ptr<HandleRequest::ExecutionContext> if (OpMsg::isFlagSet(message, OpMsg::kMoreToCome)) { // Close the connection to get client to go through server selection again. - if (LastError::get(opCtx->getClient()).hadNotPrimaryError()) { + if (NotPrimaryErrorTracker::get(opCtx->getClient()).hadError()) { if (c && c->getReadWriteType() == Command::ReadWriteType::kWrite) notPrimaryUnackWrites.increment(); @@ -1930,7 +1930,7 @@ struct GetMoreOpRunner : SynchronousOpRunner { * Fire and forget network operations don't produce a `DbResponse`. * They override `runAndForget` instead of `run`, and this base * class provides a `run` that calls it and handles error reporting - * via the `LastError` slot. + * via the `NotPrimaryErrorTracker` slot. */ struct FireAndForgetOpRunner : SynchronousOpRunner { using SynchronousOpRunner::SynchronousOpRunner; @@ -2029,7 +2029,7 @@ void HandleRequest::startOperation() { !opCtx->lockState()->inAWriteUnitOfWork()); } } else { - LastError::get(client).startRequest(); + NotPrimaryErrorTracker::get(client).startRequest(); AuthorizationSession::get(client)->startRequest(opCtx); // We should not be holding any locks at this point diff --git a/src/mongo/dbtests/directclienttests.cpp b/src/mongo/dbtests/directclienttests.cpp index 3c9b421ecfa..65543d80069 100644 --- a/src/mongo/dbtests/directclienttests.cpp +++ b/src/mongo/dbtests/directclienttests.cpp @@ -34,7 +34,6 @@ #include "mongo/db/client.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/json.h" -#include "mongo/db/lasterror.h" #include "mongo/dbtests/dbtests.h" #include "mongo/rpc/get_status_from_command_result.h" #include "mongo/util/timer.h" diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 75278418410..a35ad787320 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -44,7 +44,6 @@ #include "mongo/db/exec/queued_data_stage.h" #include "mongo/db/index/index_descriptor.h" #include "mongo/db/json.h" -#include "mongo/db/lasterror.h" #include "mongo/db/logical_time.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/find.h" diff --git a/src/mongo/dbtests/updatetests.cpp b/src/mongo/dbtests/updatetests.cpp index f29ccdb9699..63ee44d438f 100644 --- a/src/mongo/dbtests/updatetests.cpp +++ b/src/mongo/dbtests/updatetests.cpp @@ -41,7 +41,6 @@ #include "mongo/db/client.h" #include "mongo/db/dbdirectclient.h" #include "mongo/db/json.h" -#include "mongo/db/lasterror.h" #include "mongo/db/ops/update.h" #include "mongo/dbtests/dbtests.h" #include "mongo/idl/server_parameter_test_util.h" diff --git a/src/mongo/s/SConscript b/src/mongo/s/SConscript index 82bcc74fb5a..0cd79e8f461 100644 --- a/src/mongo/s/SConscript +++ b/src/mongo/s/SConscript @@ -34,7 +34,7 @@ env.Library( 'cluster_write.cpp', ], LIBDEPS=[ - '$BUILD_DIR/mongo/db/lasterror', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', 'query/cluster_query', 'write_ops/cluster_write_ops', ], @@ -491,8 +491,8 @@ env.Library( '$BUILD_DIR/mongo/db/commands/rwc_defaults_commands', '$BUILD_DIR/mongo/db/commands/servers', '$BUILD_DIR/mongo/db/ftdc/ftdc_mongos', - '$BUILD_DIR/mongo/db/lasterror', '$BUILD_DIR/mongo/db/log_process_details', + '$BUILD_DIR/mongo/db/not_primary_error_tracker', '$BUILD_DIR/mongo/db/read_write_concern_defaults', '$BUILD_DIR/mongo/db/serverinit', '$BUILD_DIR/mongo/db/service_liaison_mongos', diff --git a/src/mongo/s/cluster_write.cpp b/src/mongo/s/cluster_write.cpp index f5e51142f72..5ac8f4e0511 100644 --- a/src/mongo/s/cluster_write.cpp +++ b/src/mongo/s/cluster_write.cpp @@ -35,7 +35,7 @@ #include "mongo/s/cluster_write.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/s/chunk_manager_targeter.h" #include "mongo/s/grid.h" @@ -47,7 +47,8 @@ void write(OperationContext* opCtx, BatchWriteExecStats* stats, BatchedCommandResponse* response, boost::optional<OID> targetEpoch) { - LastError::Disabled disableLastError(&LastError::get(opCtx->getClient())); + NotPrimaryErrorTracker::Disabled scopeDisabledTracker( + &NotPrimaryErrorTracker::get(opCtx->getClient())); ChunkManagerTargeter targeter(opCtx, request.getNS(), targetEpoch); diff --git a/src/mongo/s/commands/cluster_repl_set_get_status_cmd.cpp b/src/mongo/s/commands/cluster_repl_set_get_status_cmd.cpp index 0cb9e7530eb..4618c8d6116 100644 --- a/src/mongo/s/commands/cluster_repl_set_get_status_cmd.cpp +++ b/src/mongo/s/commands/cluster_repl_set_get_status_cmd.cpp @@ -31,7 +31,7 @@ #include "mongo/db/client.h" #include "mongo/db/commands.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" namespace mongo { namespace { @@ -70,7 +70,7 @@ public: std::string& errmsg, BSONObjBuilder& result) { if (cmdObj["forShell"].trueValue()) { - LastError::get(cc()).disable(); + NotPrimaryErrorTracker::get(cc()).disable(); } errmsg = "replSetGetStatus is not supported through mongos"; diff --git a/src/mongo/s/commands/cluster_write_cmd.cpp b/src/mongo/s/commands/cluster_write_cmd.cpp index e4d41e28f23..c2f7aed02e7 100644 --- a/src/mongo/s/commands/cluster_write_cmd.cpp +++ b/src/mongo/s/commands/cluster_write_cmd.cpp @@ -39,7 +39,7 @@ #include "mongo/db/commands/update_metrics.h" #include "mongo/db/commands/write_commands_common.h" #include "mongo/db/curop.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/pipeline/lite_parsed_pipeline.h" #include "mongo/db/stats/counters.h" #include "mongo/db/storage/duplicate_key_error_info.h" @@ -67,10 +67,10 @@ namespace { MONGO_FAIL_POINT_DEFINE(hangAfterThrowWouldChangeOwningShardRetryableWrite); -void batchErrorToLastError(const BatchedCommandRequest& request, - const BatchedCommandResponse& response, - LastError* error) { - error->reset(); +void batchErrorToNotPrimaryErrorTracker(const BatchedCommandRequest& request, + const BatchedCommandResponse& response, + NotPrimaryErrorTracker* tracker) { + tracker->reset(); std::unique_ptr<WriteErrorDetail> commandError; WriteErrorDetail* lastBatchError = nullptr; @@ -89,45 +89,11 @@ void batchErrorToLastError(const BatchedCommandRequest& request, if (request.getBatchType() == BatchedCommandRequest::BatchType_Insert || lastOpErrored) { lastBatchError = response.getErrDetails().back(); } - } else { - // We don't care about write concern errors, these happen in legacy mode in GLE. } // Record an error if one exists if (lastBatchError) { - const auto& errMsg = lastBatchError->toStatus().reason(); - error->setLastError(lastBatchError->toStatus().code(), - errMsg.empty() ? "see code for details" : errMsg); - return; - } - - // Record write stats otherwise - // - // NOTE: For multi-write batches, our semantics change a little because we don't have - // un-aggregated "n" stats - if (request.getBatchType() == BatchedCommandRequest::BatchType_Update) { - BSONObj upsertedId; - if (response.isUpsertDetailsSet()) { - // Only report the very last item's upserted id if applicable - if (response.getUpsertDetails().back()->getIndex() + 1 == - static_cast<int>(request.sizeWriteOps())) { - upsertedId = response.getUpsertDetails().back()->getUpsertedID(); - } - } - - const int numUpserted = response.isUpsertDetailsSet() ? response.sizeUpsertDetails() : 0; - const auto numMatched = response.getN() - numUpserted; - invariant(numMatched >= 0); - - // Wrap upserted id in "upserted" field - BSONObj leUpsertedId; - if (!upsertedId.isEmpty()) { - leUpsertedId = upsertedId.firstElement().wrap(kUpsertedFieldName); - } - - error->recordUpdate(numMatched > 0, response.getN(), leUpsertedId); - } else if (request.getBatchType() == BatchedCommandRequest::BatchType_Delete) { - error->recordDelete(response.getN()); + tracker->recordError(lastBatchError->toStatus().code()); } } @@ -475,9 +441,9 @@ private: handleWouldChangeOwningShardError(opCtx, &batchedRequest, &response, stats); } - // Populate the lastError object based on the write response - batchErrorToLastError(batchedRequest, response, &LastError::get(opCtx->getClient())); - + // Populate the 'NotPrimaryErrorTracker' object based on the write response + batchErrorToNotPrimaryErrorTracker( + batchedRequest, response, &NotPrimaryErrorTracker::get(opCtx->getClient())); size_t numAttempts; if (!response.getOk()) { @@ -618,7 +584,7 @@ private: try { doCheckAuthorizationHook(AuthorizationSession::get(opCtx->getClient())); } catch (const DBException& e) { - LastError::get(opCtx->getClient()).setLastError(e.code(), e.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(e.code()); throw; } } diff --git a/src/mongo/s/commands/strategy.cpp b/src/mongo/s/commands/strategy.cpp index 90e9ca5a053..1013fc99471 100644 --- a/src/mongo/s/commands/strategy.cpp +++ b/src/mongo/s/commands/strategy.cpp @@ -49,11 +49,11 @@ #include "mongo/db/error_labels.h" #include "mongo/db/initialize_api_parameters.h" #include "mongo/db/initialize_operation_session_info.h" -#include "mongo/db/lasterror.h" #include "mongo/db/logical_session_id_helpers.h" #include "mongo/db/logical_time_validator.h" #include "mongo/db/matcher/extensions_callback_noop.h" #include "mongo/db/namespace_string.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/operation_time_tracker.h" #include "mongo/db/ops/write_ops.h" #include "mongo/db/query/find_common.h" @@ -1052,7 +1052,7 @@ void ParseAndRunCommand::RunInvocation::_tapOnError(const Status& status) { const auto command = _parc->_rec->getCommand(); command->incrementCommandsFailed(); - LastError::get(opCtx->getClient()).setLastError(status.code(), status.reason()); + NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(status.code()); // WriteConcern error (wcCode) is set to boost::none because: // 1. TransientTransaction error label handling for commitTransaction command in mongos is // delegated to the shards. Mongos simply propagates the shard's response up to the client. diff --git a/src/mongo/s/service_entry_point_mongos.cpp b/src/mongo/s/service_entry_point_mongos.cpp index 298432a3c0f..a62dba9466b 100644 --- a/src/mongo/s/service_entry_point_mongos.cpp +++ b/src/mongo/s/service_entry_point_mongos.cpp @@ -40,7 +40,7 @@ #include "mongo/db/commands.h" #include "mongo/db/curop.h" #include "mongo/db/dbmessage.h" -#include "mongo/db/lasterror.h" +#include "mongo/db/not_primary_error_tracker.h" #include "mongo/db/operation_context.h" #include "mongo/db/request_execution_context.h" #include "mongo/db/service_context.h" @@ -110,11 +110,11 @@ void HandleRequest::setupEnvironment() { isSupportedRequestNetworkOp(op) && op != dbCompressed); // Decompression should be handled above us. - // Start a new LastError session. Any exceptions thrown from here onwards will be returned - // to the caller (if the type of the message permits it). + // Start a new NotPrimaryErrorTracker session. Any exceptions thrown from here onwards will be + // returned to the caller (if the type of the message permits it). auto client = opCtx->getClient(); - LastError::get(client).startRequest(); - AuthorizationSession::get(opCtx->getClient())->startRequest(opCtx); + NotPrimaryErrorTracker::get(client).startRequest(); + AuthorizationSession::get(client)->startRequest(opCtx); CurOp::get(opCtx)->ensureStarted(); } |