summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2019-05-15 19:02:55 +0300
committerAndrei Elkin <andrei.elkin@mariadb.com>2019-12-23 21:49:57 +0200
commit10e9b66ef5997e5e3150009c7351bcc082a7e390 (patch)
treeb6aa9fa43a3e032f2e93c930d64b1908e19f3517
parenta467411035a052f3d4cbf7584d6d993625cee4e9 (diff)
downloadmariadb-git-10e9b66ef5997e5e3150009c7351bcc082a7e390.tar.gz
MDEV-7974
FTWRL && XA ROLLBACK, xa.test is refined/corrected.
-rw-r--r--mysql-test/main/xa.result6
-rw-r--r--mysql-test/main/xa.test3
-rw-r--r--sql/log_event.cc10
-rw-r--r--sql/xa.cc15
-rw-r--r--storage/innobase/trx/trx0trx.cc1
5 files changed, 28 insertions, 7 deletions
diff --git a/mysql-test/main/xa.result b/mysql-test/main/xa.result
index 62e9c9b669e..71e76311c5a 100644
--- a/mysql-test/main/xa.result
+++ b/mysql-test/main/xa.result
@@ -355,11 +355,12 @@ DROP TABLE t1, t2, t3;
xa rollback 'testb',0x2030405060,11;
XA RECOVER;
formatID gtrid_length bqual_length data
+# MDEV-7974 related
# Check XA state when lock_wait_timeout happens
# More tests added to flush_read_lock.test
connect con_tmp,localhost,root,,;
set session lock_wait_timeout=1;
-create table asd (a int);
+create table asd (a int) engine=innodb;
xa start 'test1';
insert into asd values(1);
xa end 'test1';
@@ -407,9 +408,6 @@ connection default;
unlock tables;
connection con_tmp;
xa rollback 'test1';
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
xa recover;
formatID gtrid_length bqual_length data
drop table asd;
diff --git a/mysql-test/main/xa.test b/mysql-test/main/xa.test
index 6f56779ec17..3a247983c6a 100644
--- a/mysql-test/main/xa.test
+++ b/mysql-test/main/xa.test
@@ -480,11 +480,12 @@ XA RECOVER;
--source include/wait_until_count_sessions.inc
+--echo # MDEV-7974 related
--echo # Check XA state when lock_wait_timeout happens
--echo # More tests added to flush_read_lock.test
connect (con_tmp,localhost,root,,);
set session lock_wait_timeout=1;
-create table asd (a int);
+create table asd (a int) engine=innodb;
xa start 'test1';
insert into asd values(1);
xa end 'test1';
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 99c1eef7d3f..eb4a69b83d0 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -8007,7 +8007,12 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg,
/* Preserve any DDL or WAITED flag in the slave's binlog. */
if (thd_arg->rgi_slave)
flags2|= (thd_arg->rgi_slave->gtid_ev_flags2 & (FL_DDL|FL_WAITED));
- if (thd->transaction.xid_state.xid_cache_element &&
+ /*
+ A non-transaction DML in the middle of XA can create own separate from
+ the transaction GTID and event group.
+ */
+ if (is_transactional &&
+ thd->transaction.xid_state.xid_cache_element &&
thd->lex->xa_opt != XA_ONE_PHASE)
{
DBUG_ASSERT(thd->transaction.xid_state.xid_cache_element->xa_state == XA_IDLE ||
@@ -8355,7 +8360,8 @@ Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
if ((flags2 & FL_PREPARED_XA) && !is_flashback)
{
my_b_write_string(&cache, "XA START ");
- my_b_write(&cache, (uchar*) xid.serialize(), strlen(xid.buf));
+ xid.serialize();
+ my_b_write(&cache, (uchar*) xid.buf, strlen(xid.buf));
if (my_b_printf(&cache, "%s\n", print_event_info->delimiter))
goto err;
}
diff --git a/sql/xa.cc b/sql/xa.cc
index b077ffbec58..6e53e404189 100644
--- a/sql/xa.cc
+++ b/sql/xa.cc
@@ -624,6 +624,21 @@ bool trans_xa_rollback(THD *thd)
DBUG_RETURN(TRUE);
}
+ MDL_request mdl_request;
+ mdl_request.init(MDL_key::BACKUP, "", "", MDL_BACKUP_COMMIT,
+ MDL_STATEMENT);
+ if (thd->mdl_context.acquire_lock(&mdl_request,
+ thd->variables.lock_wait_timeout))
+ {
+ /*
+ We can't rollback an XA transaction on lock failure due to
+ Innodb redo log and bin log update is involved in rollback.
+ Return error to user for a retry.
+ */
+ my_error(ER_XAER_RMERR, MYF(0));
+ DBUG_RETURN(true);
+ }
+
if (xid_state.xid_cache_element->xa_state == XA_PREPARED &&
xid_state.is_binlogged() &&
(WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()))
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 7af25256773..4d81428a872 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -553,6 +553,7 @@ void trx_disconnect_prepared(trx_t *trx)
trx->mysql_thd= NULL;
/* todo/fixme: suggest to do it at innodb prepare */
trx->will_lock= 0;
+ trx_sys.rw_trx_hash.put_pins(trx);
}
/****************************************************************//**