From 347c164c35eddab388009470e6848cb361ac93f8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 15:22:53 +0200 Subject: Merging upstream version 1:10.11.8. Signed-off-by: Daniel Baumann --- wsrep-lib/dbsim/db_client_service.hpp | 5 +++++ wsrep-lib/include/wsrep/client_service.hpp | 10 ++++++++++ wsrep-lib/include/wsrep/reporter.hpp | 16 ++++++++-------- wsrep-lib/src/client_state.cpp | 3 +-- wsrep-lib/src/reporter.cpp | 12 ++++++------ wsrep-lib/src/transaction.cpp | 13 +++++++++++-- wsrep-lib/test/mock_client_state.hpp | 5 +++++ 7 files changed, 46 insertions(+), 18 deletions(-) (limited to 'wsrep-lib') diff --git a/wsrep-lib/dbsim/db_client_service.hpp b/wsrep-lib/dbsim/db_client_service.hpp index be6f9ad8..15f32ef8 100644 --- a/wsrep-lib/dbsim/db_client_service.hpp +++ b/wsrep-lib/dbsim/db_client_service.hpp @@ -82,6 +82,11 @@ namespace db return false; } + bool is_prepared_xa() override + { + return false; + } + bool is_xa_rollback() override { return false; diff --git a/wsrep-lib/include/wsrep/client_service.hpp b/wsrep-lib/include/wsrep/client_service.hpp index d47396df..e5aa6499 100644 --- a/wsrep-lib/include/wsrep/client_service.hpp +++ b/wsrep-lib/include/wsrep/client_service.hpp @@ -194,6 +194,16 @@ namespace wsrep */ virtual bool is_explicit_xa() = 0; + /** + * Returns true if the client has an ongoing XA transaction + * in prepared state. + * Notice: one could simply check if wsrep::transaction is + * in s_prepared state. However, wsrep::transaction does not + * transition to prepared state for read-only / empty + * transactions. + */ + virtual bool is_prepared_xa() = 0; + /** * Returns true if the currently executing command is * a rollback for XA. This is used to avoid setting a diff --git a/wsrep-lib/include/wsrep/reporter.hpp b/wsrep-lib/include/wsrep/reporter.hpp index 3e8c7000..05cc5230 100644 --- a/wsrep-lib/include/wsrep/reporter.hpp +++ b/wsrep-lib/include/wsrep/reporter.hpp @@ -105,21 +105,21 @@ namespace wsrep typedef struct { double tstamp; std::string msg; - } log_msg; + } log_msg_t ; - std::deque err_msg_; - std::deque warn_msg_; - std::deque events_; + std::deque err_msg_; + std::deque warn_msg_; + std::deque events_; size_t const max_msg_; static void write_log_msg(std::ostream& os, - const log_msg& msg); + const log_msg_t& msg); static void write_event(std::ostream& os, - const log_msg& msg); + const log_msg_t& msg); static void write_array(std::ostream& os, const std::string& label, - const std::deque& events, + const std::deque& events, void (*element_writer)(std::ostream& os, - const log_msg& msg)); + const log_msg_t& msg)); substates substate_map(enum server_state::state state); float progress_map(float progress) const; void write_file(double timestamp); diff --git a/wsrep-lib/src/client_state.cpp b/wsrep-lib/src/client_state.cpp index 99c4222f..48501fdd 100644 --- a/wsrep-lib/src/client_state.cpp +++ b/wsrep-lib/src/client_state.cpp @@ -68,8 +68,7 @@ void wsrep::client_state::close() keep_command_error_ = false; lock.unlock(); if (transaction_.active() && - (mode_ != m_local || - transaction_.state() != wsrep::transaction::s_prepared)) + (mode_ != m_local || !client_service_.is_prepared_xa())) { client_service_.bf_rollback(); transaction_.after_statement(); diff --git a/wsrep-lib/src/reporter.cpp b/wsrep-lib/src/reporter.cpp index 511ef819..3b21a199 100644 --- a/wsrep-lib/src/reporter.cpp +++ b/wsrep-lib/src/reporter.cpp @@ -176,7 +176,7 @@ static std::string escape_json(const std::string& str) void wsrep::reporter::write_log_msg(std::ostream& os, - const log_msg& msg) + const log_msg_t& msg) { os << "\t\t{\n"; os << "\t\t\t\"timestamp\": " << std::showpoint << std::setprecision(18) @@ -187,7 +187,7 @@ wsrep::reporter::write_log_msg(std::ostream& os, void wsrep::reporter::write_event(std::ostream& os, - const log_msg& msg) + const log_msg_t& msg) { os << "\t\t{\n"; os << "\t\t\t\"timestamp\": " << std::showpoint << std::setprecision(18) @@ -199,9 +199,9 @@ wsrep::reporter::write_event(std::ostream& os, void wsrep::reporter::write_array(std::ostream& os, const std::string& label, - const std::deque& msgs, + const std::deque& msgs, void (*element_writer)(std::ostream& os, - const log_msg& msg)) + const log_msg_t& msg)) { os << "\t\"" << label << "\": [\n"; for (size_t i(0); i < msgs.size(); ++i) @@ -351,7 +351,7 @@ wsrep::reporter::report_log_msg(log_level const lvl, const std::string& msg, double tstamp) { - std::deque& deque(lvl == error ? err_msg_ : warn_msg_); + std::deque& deque(lvl == error ? err_msg_ : warn_msg_); wsrep::unique_lock lock(mutex_); @@ -363,7 +363,7 @@ wsrep::reporter::report_log_msg(log_level const lvl, /* Log messages are not expected to be json formatted, so we escape the message strings here to keep the report file well formatted. */ - log_msg entry({tstamp, escape_json(msg)}); + log_msg_t entry({tstamp, escape_json(msg)}); deque.push_back(entry); write_file(tstamp); } diff --git a/wsrep-lib/src/transaction.cpp b/wsrep-lib/src/transaction.cpp index 451e94dd..7d9e31e6 100644 --- a/wsrep-lib/src/transaction.cpp +++ b/wsrep-lib/src/transaction.cpp @@ -1400,10 +1400,19 @@ bool wsrep::transaction::abort_or_interrupt( } return true; } - else if (client_service_.interrupted(lock)) + + if (client_service_.interrupted(lock)) { + assert(state() != s_must_abort && + state() != s_aborting && + state() != s_aborted); + + // Client was interrupted. Set the appropriate error and abort. + // For transactions in prepared state, it is OK to interrupt the + // statement, but transaction must remain in prepared state until + // commit or rollback. client_state_.override_error(wsrep::e_interrupted_error); - if (state() != s_must_abort) + if (state() != s_prepared) { state(lock, s_must_abort); } diff --git a/wsrep-lib/test/mock_client_state.hpp b/wsrep-lib/test/mock_client_state.hpp index 73b27755..89d38e32 100644 --- a/wsrep-lib/test/mock_client_state.hpp +++ b/wsrep-lib/test/mock_client_state.hpp @@ -176,6 +176,11 @@ namespace wsrep return false; } + bool is_prepared_xa() WSREP_OVERRIDE + { + return false; + } + bool is_xa_rollback() WSREP_OVERRIDE { return false; -- cgit v1.2.3