1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-24981 LOAD INDEX may cause rollback of prepared XA transaction

XAER_RMFAIL means the admin statement was not allowed, it's not a
per-table message, so must fail the whole statement. And must
not rollback, obviously, it's not allowed after prepare.

Also, remove duplicate XAER_RMFAIL in open_tables(),
check_has_uncommitted_xa() already issues it.
This commit is contained in:
Sergei Golubchik
2025-07-18 20:32:45 +02:00
parent d6cb7255e9
commit 288db5fa5f
4 changed files with 40 additions and 11 deletions

View File

@@ -1,5 +1,4 @@
call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction"); call mtr.add_suppression("Deadlock found when trying to get lock; try restarting transaction");
drop table if exists t1, t2;
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
xa start 'test1'; xa start 'test1';
insert t1 values (10); insert t1 values (10);
@@ -595,6 +594,26 @@ formatID gtrid_length bqual_length data
xa rollback '4'; xa rollback '4';
ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
set @@global.read_only=@sav_read_only; set @@global.read_only=@sav_read_only;
#
# End of 10.5 tests # End of 10.5 tests
# #
# MDEV-24981 LOAD INDEX may cause rollback of prepared XA transaction
#
create table t1 (f1 integer primary key) engine=innodb;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
PRIMARY KEY (`f1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
xa start 'a';
insert into t1 values (1);
xa end 'a';
xa prepare 'a';
load index into cache t1 key(primary);
ERROR XAE07: XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state
xa commit 'a';
select count(*) from t1;
count(*)
1
drop table t1;
# End of 10.11 tests

View File

@@ -1,7 +1,7 @@
# #
# WL#1756 # WL#1756
# #
-- source include/have_innodb.inc --source include/have_innodb.inc
--source include/not_embedded.inc --source include/not_embedded.inc
# Save the initial number of concurrent sessions # Save the initial number of concurrent sessions
@@ -12,10 +12,6 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting
call mtr.add_suppression("InnoDB: Transaction was aborted due to "); call mtr.add_suppression("InnoDB: Transaction was aborted due to ");
--enable_query_log --enable_query_log
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
create table t1 (a int) engine=innodb; create table t1 (a int) engine=innodb;
xa start 'test1'; xa start 'test1';
insert t1 values (10); insert t1 values (10);
@@ -752,7 +748,21 @@ xa rollback '4';
set @@global.read_only=@sav_read_only; set @@global.read_only=@sav_read_only;
--echo # End of 10.5 tests
--echo # --echo #
--echo # End of 10.5 tests --echo # MDEV-24981 LOAD INDEX may cause rollback of prepared XA transaction
--echo # --echo #
create table t1 (f1 integer primary key) engine=innodb;
show create table t1;
xa start 'a';
insert into t1 values (1);
xa end 'a';
xa prepare 'a';
--error ER_XAER_RMFAIL
load index into cache t1 key(primary);
xa commit 'a';
select count(*) from t1;
drop table t1;
--echo # End of 10.11 tests

View File

@@ -565,6 +565,9 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Disable_wsrep_on_guard wsrep_on_guard(thd, disable_wsrep_on); Disable_wsrep_on_guard wsrep_on_guard(thd, disable_wsrep_on);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (thd->transaction->xid_state.check_has_uncommitted_xa())
DBUG_RETURN(TRUE);
fill_check_table_metadata_fields(thd, &field_list); fill_check_table_metadata_fields(thd, &field_list);
if (protocol->send_result_set_metadata(&field_list, if (protocol->send_result_set_metadata(&field_list,

View File

@@ -4598,10 +4598,7 @@ bool open_tables(THD *thd, const DDL_options_st &options,
if (!table->schema_table) if (!table->schema_table)
{ {
if (thd->transaction->xid_state.check_has_uncommitted_xa()) if (thd->transaction->xid_state.check_has_uncommitted_xa())
{
thd->transaction->xid_state.er_xaer_rmfail();
DBUG_RETURN(true); DBUG_RETURN(true);
}
else else
break; break;
} }