summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@sun.com>2009-10-28 19:39:08 +0400
committerSergey Vojtovich <svoj@sun.com>2009-10-28 19:39:08 +0400
commit17ed7089756f9001d7bc6eac063d91b374de0181 (patch)
treee463afef840ef0b005614eae4b2fd868d2e051ff /sql
parent9a5a77eb68a35b3e806bb65f94ec9cd9ab9b1b5e (diff)
downloadmariadb-git-17ed7089756f9001d7bc6eac063d91b374de0181.tar.gz
BUG#43171 - Assertion failed: thd->transaction.xid_state.xid.is_null()
XA START may cause assertion failure/server crash when it is called after unilateral roll back issued by the Resource Manager (both in regular transaction and after XA transaction). The problem was that rm_error variable wasn't set/reset properly. mysql-test/r/xa.result: A test case for BUG#43171. mysql-test/t/xa.test: A test case for BUG#43171. sql/handler.cc: Setting rm_error when we're out of XA transaction has no special meaning. But it blocks reset of thd->transaction.xid structure later. sql/sql_parse.cc: Reset rm_error before we enter ha_rollback(), so thd->transaction.xid strucure is reinitialized.
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc3
-rw-r--r--sql/sql_parse.cc9
2 files changed, 10 insertions, 2 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index d07ebed8ab9..216228ed509 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1311,7 +1311,8 @@ int ha_rollback_trans(THD *thd, bool all)
}
trans->ha_list= 0;
trans->no_2pc=0;
- if (is_real_trans && thd->transaction_rollback_request)
+ if (is_real_trans && thd->transaction_rollback_request &&
+ thd->transaction.xid_state.xa_state != XA_NOTR)
thd->transaction.xid_state.rm_error= thd->main_da.sql_errno();
if (all)
thd->variables.tx_isolation=thd->session_tx_isolation;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2e150ca1542..7f19421beaf 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -122,6 +122,14 @@ static bool xa_trans_rolled_back(XID_STATE *xid_state)
*/
static bool xa_trans_rollback(THD *thd)
{
+ /*
+ Resource Manager error is meaningless at this point, as we perform
+ explicit rollback request by user. We must reset rm_error before
+ calling ha_rollback(), so thd->transaction.xid structure gets reset
+ by ha_rollback()/THD::transaction::cleanup().
+ */
+ thd->transaction.xid_state.rm_error= 0;
+
bool status= test(ha_rollback(thd));
thd->options&= ~(ulong) OPTION_BEGIN;
@@ -129,7 +137,6 @@ static bool xa_trans_rollback(THD *thd)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state= XA_NOTR;
- thd->transaction.xid_state.rm_error= 0;
return status;
}