diff --git a/libbinlogevents/include/control_events.h b/libbinlogevents/include/control_events.h index dfbd5f8..88a2e78 100644 --- a/libbinlogevents/include/control_events.h +++ b/libbinlogevents/include/control_events.h @@ -738,6 +738,9 @@ public: depends on the binlog-version currently in use. */ XA_prepare_event(const char *buf, const Format_description_event *fde); + + bool is_one_phase() const { return one_phase; } + #ifndef HAVE_MYSYS /* todo: we need to find way how to exploit server's code of diff --git a/sql/binlog.cc b/sql/binlog.cc index 013104a..f1a0210 100644 --- a/sql/binlog.cc +++ b/sql/binlog.cc @@ -9513,7 +9513,7 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log, Format_description_log_event *fdle, my_off_t *valid_pos) { Log_event *ev; - HASH xids; + HASH xids; // mysql internal xa txns' ids. MEM_ROOT mem_root; std::set xa_prepared; @@ -9541,6 +9541,11 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log, Format_description_log_event *fdle, !strncmp(((Query_log_event*)ev)->query, "XA START", 8))) in_transaction= TRUE; + /* + TDSQL: XA COMMIT/XA ROLLBACK is an independent separate event group which + doesn't have a begin/xa start head, so here we can ignore + XA COMMIT/XA ROLLBACK. + */ if (ev->get_type_code() == binary_log::QUERY_EVENT && !strcmp(((Query_log_event*)ev)->query, "COMMIT")) { @@ -9561,8 +9566,13 @@ int MYSQL_BIN_LOG::recover(IO_CACHE *log, Format_description_log_event *fdle, { DBUG_ASSERT(in_transaction == TRUE); in_transaction= FALSE; + // TDSQL: one phase commits use XA PREPARE event as end, but they are not + // prepared but ended. XA_prepare_log_event *xev=(XA_prepare_log_event *)ev; - xa_prepared.insert(xev->get_xid_str()); + if (!xev->is_one_phase()) + { + xa_prepared.insert(xev->get_xid_str()); + } } /*