Skip to content

Commit 03dd699

Browse files
committed
MDEV-37315 Assertion `!xid_state.xid_cache_element' failed in trans_xa_rollback
trying to commit a "hanging" prepared XA transaction is currently not allowed within an another active XA transaction. it should equally be not allowed if a current XA transaction is in the rollback-only state.
1 parent 288db5f commit 03dd699

File tree

3 files changed

+140
-2
lines changed

3 files changed

+140
-2
lines changed

mysql-test/main/xa.result

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,4 +616,73 @@ select count(*) from t1;
616616
count(*)
617617
1
618618
drop table t1;
619+
#
620+
# MDEV-37315 Assertion `!xid_state.xid_cache_element' failed in trans_xa_rollback
621+
#
622+
create table t1 (a int) engine=innodb;
623+
create table t2 (b int) engine=innodb;
624+
create table t3 (c int) engine=innodb;
625+
insert t1 values (1);
626+
insert t2 values (2);
627+
connect con1,localhost,root;
628+
xa start 'r:foo';
629+
insert t3 values (3);
630+
xa end 'r:foo';
631+
xa prepare 'r:foo';
632+
disconnect con1;
633+
connection default;
634+
xa recover;
635+
formatID gtrid_length bqual_length data
636+
1 5 0 r:foo
637+
xa start 'r:bar';
638+
select * from t1 for update;
639+
a
640+
1
641+
connect con2,localhost,root;
642+
xa start 'r:baz';
643+
update t2 set b=12;
644+
update t1 set a=13;
645+
connection default;
646+
xa rollback 'r:foo';
647+
ERROR XAE09: XAER_OUTSIDE: Some work is done outside global transaction
648+
select * from t2 for update;
649+
Got one of the listed errors
650+
xa rollback 'r:foo';
651+
ERROR XAE09: XAER_OUTSIDE: Some work is done outside global transaction
652+
connection con2;
653+
disconnect con2;
654+
connection default;
655+
xa rollback 'r:bar';
656+
xa rollback 'r:foo';
657+
connect con1,localhost,root;
658+
xa start 'c:foo';
659+
insert t3 values (103);
660+
xa end 'c:foo';
661+
xa prepare 'c:foo';
662+
disconnect con1;
663+
connection default;
664+
xa recover;
665+
formatID gtrid_length bqual_length data
666+
1 5 0 c:foo
667+
xa start 'c:bar';
668+
select * from t1 for update;
669+
a
670+
1
671+
connect con2,localhost,root;
672+
xa start 'c:baz';
673+
update t2 set b=102;
674+
update t1 set a=103;
675+
connection default;
676+
xa commit 'c:foo';
677+
ERROR XAE09: XAER_OUTSIDE: Some work is done outside global transaction
678+
select * from t2 for update;
679+
Got one of the listed errors
680+
xa commit 'c:foo';
681+
ERROR XAE09: XAER_OUTSIDE: Some work is done outside global transaction
682+
connection con2;
683+
disconnect con2;
684+
connection default;
685+
xa rollback 'c:bar';
686+
xa commit 'c:foo';
687+
drop table t1,t2,t3;
619688
# End of 10.11 tests

mysql-test/main/xa.test

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,4 +765,73 @@ xa commit 'a';
765765
select count(*) from t1;
766766
drop table t1;
767767

768+
--echo #
769+
--echo # MDEV-37315 Assertion `!xid_state.xid_cache_element' failed in trans_xa_rollback
770+
--echo #
771+
create table t1 (a int) engine=innodb;
772+
create table t2 (b int) engine=innodb;
773+
create table t3 (c int) engine=innodb;
774+
insert t1 values (1);
775+
insert t2 values (2);
776+
777+
connect con1,localhost,root;
778+
xa start 'r:foo';
779+
insert t3 values (3);
780+
xa end 'r:foo';
781+
xa prepare 'r:foo';
782+
disconnect con1;
783+
connection default;
784+
xa recover;
785+
786+
xa start 'r:bar';
787+
select * from t1 for update;
788+
connect con2,localhost,root;
789+
xa start 'r:baz';
790+
update t2 set b=12;
791+
send update t1 set a=13;
792+
connection default;
793+
--error ER_XAER_OUTSIDE
794+
xa rollback 'r:foo';
795+
--error ER_LOCK_DEADLOCK,ER_XAER_RMFAIL
796+
select * from t2 for update;
797+
--error ER_XAER_OUTSIDE
798+
xa rollback 'r:foo';
799+
connection con2;
800+
reap;
801+
disconnect con2;
802+
connection default;
803+
xa rollback 'r:bar';
804+
xa rollback 'r:foo';
805+
806+
connect con1,localhost,root;
807+
xa start 'c:foo';
808+
insert t3 values (103);
809+
xa end 'c:foo';
810+
xa prepare 'c:foo';
811+
disconnect con1;
812+
connection default;
813+
xa recover;
814+
815+
xa start 'c:bar';
816+
select * from t1 for update;
817+
connect con2,localhost,root;
818+
xa start 'c:baz';
819+
update t2 set b=102;
820+
send update t1 set a=103;
821+
connection default;
822+
--error ER_XAER_OUTSIDE
823+
xa commit 'c:foo';
824+
--error ER_LOCK_DEADLOCK,ER_XAER_RMFAIL
825+
select * from t2 for update;
826+
--error ER_XAER_OUTSIDE
827+
xa commit 'c:foo';
828+
connection con2;
829+
reap;
830+
disconnect con2;
831+
connection default;
832+
xa rollback 'c:bar';
833+
xa commit 'c:foo';
834+
835+
drop table t1,t2,t3;
836+
768837
--echo # End of 10.11 tests

sql/xa.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ bool trans_xa_commit(THD *thd)
625625
if (!xid_state.is_explicit_XA() ||
626626
!xid_state.xid_cache_element->xid.eq(thd->lex->xid))
627627
{
628-
if (thd->in_multi_stmt_transaction_mode())
628+
if (thd->in_multi_stmt_transaction_mode() || xid_state.xid_cache_element)
629629
{
630630
/*
631631
Not allow to commit from inside an not-"native" to xid
@@ -799,7 +799,7 @@ bool trans_xa_rollback(THD *thd)
799799
if (!xid_state.is_explicit_XA() ||
800800
!xid_state.xid_cache_element->xid.eq(thd->lex->xid))
801801
{
802-
if (thd->in_multi_stmt_transaction_mode())
802+
if (thd->in_multi_stmt_transaction_mode() || xid_state.xid_cache_element)
803803
{
804804
my_error(ER_XAER_OUTSIDE, MYF(0));
805805
DBUG_RETURN(TRUE);

0 commit comments

Comments
 (0)