From: Sergey Glukhov Date: April 14 2011 9:36am Subject: bzr commit into mysql-trunk branch (sergey.glukhov:3313) List-Archive: http://lists.mysql.com/commits/135415 Message-Id: <201104140935.p3E9ZGN4021714@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At file:///home/gluh/MySQL/mysql-trunk/ based on revid:sergey.glukhov@stripped 3313 Sergey Glukhov 2011-04-14 [merge] automerge @ mysql-test/r/xa.result automerge @ mysql-test/t/xa.test automerge @ sql/transaction.cc automerge modified: mysql-test/r/xa.result mysql-test/t/xa.test sql/transaction.cc === modified file 'mysql-test/r/xa.result' --- a/mysql-test/r/xa.result 2011-04-12 10:59:59 +0000 +++ b/mysql-test/r/xa.result 2011-04-14 08:47:14 +0000 @@ -200,3 +200,32 @@ SELECT * FROM t1; a 1 DROP TABLE t1; +# +# Bug#12352846 - TRANS_XA_START(THD*): +# ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL() +# FAILED +# +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); +START TRANSACTION; +INSERT INTO t1 VALUES (1); +# Connection con2 +XA START 'xid1'; +# Sending: +INSERT INTO t2 SELECT a FROM t1; +# Connection default +# Waiting until INSERT ... is blocked +DELETE FROM t1; +COMMIT; +# Connection con2 +# Reaping: INSERT INTO t2 SELECT a FROM t1 +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +XA COMMIT 'xid1'; +ERROR XA102: XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected +XA START 'xid1'; +XA END 'xid1'; +XA PREPARE 'xid1'; +XA ROLLBACK 'xid1'; +# Connection default +DROP TABLE t1, t2; === modified file 'mysql-test/t/xa.test' --- a/mysql-test/t/xa.test 2011-04-12 10:59:59 +0000 +++ b/mysql-test/t/xa.test 2011-04-14 08:47:14 +0000 @@ -3,6 +3,8 @@ # -- source include/have_innodb.inc +--source include/not_embedded.inc + # Save the initial number of concurrent sessions --source include/count_sessions.inc @@ -326,6 +328,59 @@ SELECT * FROM t1; DROP TABLE t1; +--echo # +--echo # Bug#12352846 - TRANS_XA_START(THD*): +--echo # ASSERTION THD->TRANSACTION.XID_STATE.XID.IS_NULL() +--echo # FAILED +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (a INT); + +START TRANSACTION; +INSERT INTO t1 VALUES (1); + +--echo # Connection con2 +--connect (con2,localhost,root) +XA START 'xid1'; +--echo # Sending: +--send INSERT INTO t2 SELECT a FROM t1 + +--echo # Connection default +--connection default +let $wait_condition= + SELECT COUNT(*) = 1 FROM information_schema.processlist + WHERE state = "Sending data" + AND info = "INSERT INTO t2 SELECT a FROM t1"; +--echo # Waiting until INSERT ... is blocked +--source include/wait_condition.inc +DELETE FROM t1; +COMMIT; + +--echo # Connection con2 +--connection con2 +--echo # Reaping: INSERT INTO t2 SELECT a FROM t1 +--error ER_LOCK_DEADLOCK +--reap +--error ER_XA_RBDEADLOCK +XA COMMIT 'xid1'; +# This caused the assert to be triggered +XA START 'xid1'; + +XA END 'xid1'; +XA PREPARE 'xid1'; +XA ROLLBACK 'xid1'; + +--echo # Connection default +connection default; +DROP TABLE t1, t2; +disconnect con2; + + # Wait till all disconnects are completed --source include/wait_until_count_sessions.inc === modified file 'sql/transaction.cc' --- a/sql/transaction.cc 2011-04-12 10:59:59 +0000 +++ b/sql/transaction.cc 2011-04-14 08:47:14 +0000 @@ -75,6 +75,33 @@ static bool xa_trans_rolled_back(XID_STA /** + Rollback the active XA transaction. + + @note Resets rm_error before calling ha_rollback(), so + the thd->transaction.xid structure gets reset + by ha_rollback() / THD::transaction::cleanup(). + + @return TRUE if the rollback failed, FALSE otherwise. +*/ + +static bool xa_trans_force_rollback(THD *thd) +{ + /* + 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; + if (ha_rollback_trans(thd, true)) + { + my_error(ER_XAER_RMERR, MYF(0)); + return true; + } + return false; +} + + +/** Begin a new transaction. @note Beginning a transaction implicitly commits any current @@ -645,8 +672,7 @@ bool trans_xa_commit(THD *thd) if (xa_trans_rolled_back(&thd->transaction.xid_state)) { - if (ha_rollback_trans(thd, TRUE)) - my_error(ER_XAER_RMERR, MYF(0)); + xa_trans_force_rollback(thd); res= thd->is_error(); } else if (xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE) @@ -735,15 +761,7 @@ bool trans_xa_rollback(THD *thd) DBUG_RETURN(TRUE); } - /* - 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; - if ((res= test(ha_rollback_trans(thd, TRUE)))) - my_error(ER_XAER_RMERR, MYF(0)); + res= xa_trans_force_rollback(thd); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->transaction.all.modified_non_trans_table= FALSE; No bundle (reason: revision is a merge (you can force generation of a bundle with env var BZR_FORCE_BUNDLE=1)).