diff options
author | Andrei Elkin <andrei.elkin@mariadb.com> | 2019-05-15 19:02:55 +0300 |
---|---|---|
committer | Andrei Elkin <andrei.elkin@mariadb.com> | 2019-12-23 21:49:57 +0200 |
commit | 10e9b66ef5997e5e3150009c7351bcc082a7e390 (patch) | |
tree | b6aa9fa43a3e032f2e93c930d64b1908e19f3517 | |
parent | a467411035a052f3d4cbf7584d6d993625cee4e9 (diff) | |
download | mariadb-git-10e9b66ef5997e5e3150009c7351bcc082a7e390.tar.gz |
MDEV-7974
FTWRL && XA ROLLBACK, xa.test is refined/corrected.
-rw-r--r-- | mysql-test/main/xa.result | 6 | ||||
-rw-r--r-- | mysql-test/main/xa.test | 3 | ||||
-rw-r--r-- | sql/log_event.cc | 10 | ||||
-rw-r--r-- | sql/xa.cc | 15 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 1 |
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); } /****************************************************************//** |