summaryrefslogtreecommitdiffstats
path: root/wsrep-lib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
commit347c164c35eddab388009470e6848cb361ac93f8 (patch)
tree2c0c44eac690f510bb0a35b2a13b36d606b77b6b /wsrep-lib
parentReleasing progress-linux version 1:10.11.7-4~progress7.99u1. (diff)
downloadmariadb-347c164c35eddab388009470e6848cb361ac93f8.tar.xz
mariadb-347c164c35eddab388009470e6848cb361ac93f8.zip
Merging upstream version 1:10.11.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'wsrep-lib')
-rw-r--r--wsrep-lib/dbsim/db_client_service.hpp5
-rw-r--r--wsrep-lib/include/wsrep/client_service.hpp10
-rw-r--r--wsrep-lib/include/wsrep/reporter.hpp16
-rw-r--r--wsrep-lib/src/client_state.cpp3
-rw-r--r--wsrep-lib/src/reporter.cpp12
-rw-r--r--wsrep-lib/src/transaction.cpp13
-rw-r--r--wsrep-lib/test/mock_client_state.hpp5
7 files changed, 46 insertions, 18 deletions
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
@@ -195,6 +195,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
* a deadlock error rollback as it may be unexpected
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<log_msg> err_msg_;
- std::deque<log_msg> warn_msg_;
- std::deque<log_msg> events_;
+ std::deque<log_msg_t> err_msg_;
+ std::deque<log_msg_t> warn_msg_;
+ std::deque<log_msg_t> 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<log_msg>& events,
+ const std::deque<log_msg_t>& 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<log_msg>& msgs,
+ const std::deque<log_msg_t>& 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<log_msg>& deque(lvl == error ? err_msg_ : warn_msg_);
+ std::deque<log_msg_t>& deque(lvl == error ? err_msg_ : warn_msg_);
wsrep::unique_lock<wsrep::mutex> 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;