Skip to content

Commit 8c7818a

Browse files
author
Andrei Elkin
committed
Bug#21942487 ASSERTION `STATIC_CAST<SQL_CMD_XA_COMMIT*>(THD->LEX->M_SQL_CMD)-> GET_XA_OPT()
Bug#22273964 INNODB: FAILING ASSERTION: TOTAL_TRX >= TRX_SYS->N_PREPARED_TRX **Problem description** An assertion of Bug#21942487 static_cast<Sql_cmd_xa_commit*>(thd->lex->m_sql_cmd)-> get_xa_opt() == XA_ONE_PHASE #8 0x0000000000e3a5e1 in ha_commit_low #9 0x00000000015158e6 in TC_LOG_DUMMY::commit #10 0x0000000001529bc3 in Sql_cmd_xa_commit::trans_xa_commit was caused by incorrect assumption by XA binlogging of wl6860 in that @@session.pseudo_slave_mode can be only set 1 through binlog. If fact the var can be set so manually. Another assert in Bug#22273964 takes place for the very same reason. **Solution** The most reliable way to identify that the executing thread is a binlog applier must include both the checking of rli_fake and @@session.pseudo_slave_mode. The former merely checking of the session variable as atttemp to identify the binlog applier is replaced by checking the conjuction of the two properties. Notice that load containting SET @@session.pseudo_slave_mode=1 and BINLOG '' pseudo-queries is not necessary authentic to mysqlbinlog output. Nevertheless it must be processable when it's manually engineered such way. A test is included to prove that as well. **Note** Beware of Bug #19502202 SERVER SHUTDOWN HANG SEEN IN SOME INNODB & RPL TESTS at testing with binlog.binlog_xa_prepared_disconnect that still fails sporadically.
1 parent feda5a9 commit 8c7818a

File tree

11 files changed

+153
-5
lines changed

11 files changed

+153
-5
lines changed

mysql-test/extra/binlog_tests/binlog_xa_prepared.test

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where typ
5656

5757
--inc $not_xa_trans_committed
5858
--eval call mtr.add_suppression("Found $prepared_at_server_restart prepared XA transactions")
59+
# Caused by bug#79416 fixes, see below.
60+
call mtr.add_suppression("Found 1 prepared XA transactions");
5961

6062
--inc $not_xa_trans_committed
6163
CREATE TABLE t (a INT) ENGINE=innodb;
@@ -151,6 +153,31 @@ if (`SELECT @@global.log_bin = 1`)
151153
--echo All transactions must be completed, to empty-list the following:
152154
XA RECOVER;
153155

156+
157+
# bug#79416 INNODB: FAILING ASSERTION: TOTAL_TRX >= TRX_SYS->N_PREPARED_TRX
158+
# Fixes' prove in that there must be no innodb assert at the server shutdown
159+
--connect (conn_bug79146, 127.0.0.1,root,,test,$MASTER_MYPORT,)
160+
CREATE TABLE t(a INT);
161+
XA START 'xa1';
162+
INSERT INTO t SET a = 1;
163+
XA END 'xa1';
164+
SET @@SESSION.pseudo_slave_mode=1;
165+
XA PREPARE 'xa1';
166+
167+
--connection default
154168
--source include/restart_mysqld.inc
155169

170+
XA ROLLBACK 'xa1';
171+
172+
# bug78695 ASSERTION `STATIC_CAST<SQL_CMD_XA_COMMIT*>(THD->LEX->M_SQL_CMD)-> GET_XA_OPT()
173+
# Fixes' prove in that there must be no assert at the xa commit
174+
XA START 'xa1';
175+
INSERT INTO t SET a = 1;
176+
XA END 'xa1';
177+
XA PREPARE 'xa1';
178+
SET @@SESSION.pseudo_slave_mode=1;
179+
XA COMMIT 'xa1';
180+
181+
DROP TABLE t;
182+
156183
--source include/gtid_utils_end.inc

mysql-test/r/xa_prepared_binlog_off.result

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ call mtr.add_suppression("You need to use --log-bin to make --log-slave-updates
22
include/gtid_utils.inc
33
CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND';
44
call mtr.add_suppression("Found 10 prepared XA transactions");
5+
call mtr.add_suppression("Found 1 prepared XA transactions");
56
CREATE TABLE t (a INT) ENGINE=innodb;
67
SET @@sql_log_bin = OFF;
78
CREATE TEMPORARY TABLE tmp1 (a int) ENGINE=innodb;
@@ -809,5 +810,19 @@ include/assert.inc [committed gno 130]
809810
All transactions must be completed, to empty-list the following:
810811
XA RECOVER;
811812
formatID gtrid_length bqual_length data
813+
CREATE TABLE t(a INT);
814+
XA START 'xa1';
815+
INSERT INTO t SET a = 1;
816+
XA END 'xa1';
817+
SET @@SESSION.pseudo_slave_mode=1;
818+
XA PREPARE 'xa1';
812819
# restart
820+
XA ROLLBACK 'xa1';
821+
XA START 'xa1';
822+
INSERT INTO t SET a = 1;
823+
XA END 'xa1';
824+
XA PREPARE 'xa1';
825+
SET @@SESSION.pseudo_slave_mode=1;
826+
XA COMMIT 'xa1';
827+
DROP TABLE t;
813828
include/gtid_utils_end.inc

mysql-test/suite/binlog/r/binlog_xa_handling.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8=';
77
XA END'';
88
XA PREPARE'';
99
XA COMMIT'';
10+
SET @sav.pseudo_slave_mode= @@session.pseudo_slave_mode;
11+
SELECT @@session.pseudo_slave_mode;
12+
@@session.pseudo_slave_mode
13+
0
14+
SET @@session.pseudo_slave_mode=1;
15+
Warnings:
16+
Warning 1231 'pseudo_slave_mode' is already ON.
17+
XA START 'xa';
18+
INSERT INTO t1 VALUES(10);
19+
BINLOG '
20+
SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA
21+
AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8=';
22+
XA END 'xa';
23+
XA PREPARE 'xa';
24+
XA COMMIT 'xa';
25+
SET @@session.pseudo_slave_mode= @sav.pseudo_slave_mode;
1026
DROP TABLE t1;
1127
RESET MASTER;
1228
CREATE TABLE t1 (c1 INT);

mysql-test/suite/binlog/r/binlog_xa_prepared_disconnect.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ include/gtid_utils.inc
22
RESET MASTER;
33
CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND';
44
call mtr.add_suppression("Found 10 prepared XA transactions");
5+
call mtr.add_suppression("Found 1 prepared XA transactions");
56
CREATE TABLE t (a INT) ENGINE=innodb;
67
SET @@sql_log_bin = OFF;
78
CREATE TEMPORARY TABLE tmp1 (a int) ENGINE=innodb;
@@ -811,6 +812,9 @@ master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`ro
811812
master-bin.000001 # Query # # BEGIN
812813
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Found 10 prepared XA transactions' COLLATE 'latin1_swedish_ci'))
813814
master-bin.000001 # Query # # COMMIT
815+
master-bin.000001 # Query # # BEGIN
816+
master-bin.000001 # Query # # use `mtr`; INSERT INTO test_suppressions (pattern) VALUES ( NAME_CONST('pattern',_latin1'Found 1 prepared XA transactions' COLLATE 'latin1_swedish_ci'))
817+
master-bin.000001 # Query # # COMMIT
814818
master-bin.000001 # Query # # use `test`; CREATE TABLE t (a INT) ENGINE=innodb
815819
master-bin.000001 # Query # # XA START X'7472785f30',X'',1
816820
master-bin.000001 # Query # # use `test`; INSERT INTO t SET a=0
@@ -919,5 +923,19 @@ include/assert.inc [committed gno 130]
919923
All transactions must be completed, to empty-list the following:
920924
XA RECOVER;
921925
formatID gtrid_length bqual_length data
926+
CREATE TABLE t(a INT);
927+
XA START 'xa1';
928+
INSERT INTO t SET a = 1;
929+
XA END 'xa1';
930+
SET @@SESSION.pseudo_slave_mode=1;
931+
XA PREPARE 'xa1';
922932
# restart
933+
XA ROLLBACK 'xa1';
934+
XA START 'xa1';
935+
INSERT INTO t SET a = 1;
936+
XA END 'xa1';
937+
XA PREPARE 'xa1';
938+
SET @@SESSION.pseudo_slave_mode=1;
939+
XA COMMIT 'xa1';
940+
DROP TABLE t;
923941
include/gtid_utils_end.inc

mysql-test/suite/binlog/t/binlog_xa_handling.test

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
--source include/have_log_bin.inc
1212

1313
CREATE TABLE t1(f1 int);
14+
1415
XA START'','';
1516
INSERT INTO t1 VALUES(10);
1617
BINLOG '
@@ -19,6 +20,29 @@ AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8=';
1920
XA END'';
2021
XA PREPARE'';
2122
XA COMMIT'';
23+
24+
#
25+
# Bug#21942487 ASSERTION
26+
# `STATIC_CAST<SQL_CMD_XA_COMMIT*>(THD->LEX->M_SQL_CMDQL_CMD)->
27+
# GET_XA_OPT()
28+
# The following block checks safety of processing of load masquaraded
29+
# as it's out of mysqlbing. The XA transaction must complete.
30+
#
31+
SET @sav.pseudo_slave_mode= @@session.pseudo_slave_mode;
32+
SELECT @@session.pseudo_slave_mode;
33+
# A warning out of the following query is improper and caused by a combination
34+
# of the above BINLOG processing and side effect of BUG#15891524.
35+
SET @@session.pseudo_slave_mode=1;
36+
XA START 'xa';
37+
INSERT INTO t1 VALUES(10);
38+
BINLOG '
39+
SOgWTg8BAAAAbgAAAHIAAAAAAAQANS42LjMtbTUtZGVidWctbG9nAAAAAAAAAAAAAAAAAAAAAAAA
40+
AAAAAAAAAAAAAAAAAABI6BZOEzgNAAgAEgAEBAQEEgAAVgAEGggAAAAICAgCAAAAAAVAYI8=';
41+
XA END 'xa';
42+
XA PREPARE 'xa';
43+
XA COMMIT 'xa';
44+
SET @@session.pseudo_slave_mode= @sav.pseudo_slave_mode;
45+
2246
DROP TABLE t1;
2347

2448
#

sql/handler.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,8 +1779,8 @@ int ha_commit_low(THD *thd, bool all, bool run_after_commit)
17791779
have to restore its local thread native transaction
17801780
context, previously saved at XA START.
17811781
*/
1782-
if (thd->variables.pseudo_slave_mode &&
1783-
thd->lex->sql_command == SQLCOM_XA_COMMIT)
1782+
if (thd->lex->sql_command == SQLCOM_XA_COMMIT &&
1783+
thd->binlog_applier_has_detached_trx())
17841784
{
17851785
DBUG_ASSERT(static_cast<Sql_cmd_xa_commit*>(thd->lex->m_sql_cmd)->
17861786
get_xa_opt() == XA_ONE_PHASE);

sql/rpl_rli.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ Relay_log_info::Relay_log_info(bool is_slave_recovery
115115
commit_order_mngr(NULL),
116116
sql_delay(0), sql_delay_end(0), m_flags(0), row_stmt_start_timestamp(0),
117117
long_find_row_note_printed(false), error_on_rli_init_info(false),
118-
thd_tx_priority(0)
118+
thd_tx_priority(0),
119+
is_native_trx_detached(false)
119120
{
120121
DBUG_ENTER("Relay_log_info::Relay_log_info");
121122

sql/rpl_rli.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,16 @@ class Relay_log_info : public Rpl_info
12771277
int thd_tx_priority;
12781278

12791279
public:
1280+
/*
1281+
The boolean is set to true when the binlog applier (rli_fake) thread
1282+
detaches any "native" engine transactions it has dealt with
1283+
at time of XA START processing.
1284+
The boolean is reset to false at the end of XA PREPARE
1285+
and XA COMMIT ONE PHASE, at the same time with the native transactions
1286+
re-attachment.
1287+
*/
1288+
bool is_native_trx_detached;
1289+
12801290
void set_thd_tx_priority(int priority)
12811291
{
12821292
thd_tx_priority= priority;

sql/sql_class.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4791,3 +4791,18 @@ void THD::claim_memory_ownership()
47914791
#endif /* HAVE_PSI_MEMORY_INTERFACE */
47924792
}
47934793

4794+
4795+
bool THD::binlog_applier_need_detach_trx()
4796+
{
4797+
return is_binlog_applier() ? rli_fake->is_native_trx_detached= true : false;
4798+
};
4799+
4800+
4801+
bool THD::binlog_applier_has_detached_trx()
4802+
{
4803+
bool rc= is_binlog_applier() && rli_fake->is_native_trx_detached;
4804+
4805+
if (rc)
4806+
rli_fake->is_native_trx_detached= false;
4807+
return rc;
4808+
}

sql/sql_class.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,28 @@ class THD :public MDL_context_owner,
15001500
/* Slave applier execution context */
15011501
Relay_log_info* rli_slave;
15021502

1503+
/**
1504+
The function checks whether the thread is processing queries from binlog,
1505+
as automatically generated by mysqlbinlog.
1506+
1507+
@return true when the thread is a binlog applier
1508+
*/
1509+
bool is_binlog_applier() { return rli_fake && variables.pseudo_slave_mode; }
1510+
1511+
/**
1512+
@return true when the thread is binlog applier.
1513+
@note When the thread is a binlog applier it memorizes a fact of that it
1514+
has detached "native" engine transactions associated with it.
1515+
*/
1516+
bool binlog_applier_need_detach_trx();
1517+
1518+
/**
1519+
@return true when the binlog applier (rli_fake) thread has detached
1520+
"native" engine transaction, see @c binlog_applier_detach_trx.
1521+
@note The binlog applier having detached transactions resets a memo
1522+
mark at once with this check.
1523+
*/
1524+
bool binlog_applier_has_detached_trx();
15031525
void reset_for_next_command();
15041526
/*
15051527
Constant for THD::where initialization in the beginning of every query.

sql/xa.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ bool Sql_cmd_xa_start::execute(THD *thd)
569569

570570
if (!st)
571571
{
572-
if (thd->variables.pseudo_slave_mode)
572+
if (thd->binlog_applier_need_detach_trx())
573573
{
574574
/*
575575
In case of slave thread applier or processing binlog by client,
@@ -683,7 +683,7 @@ bool Sql_cmd_xa_prepare::execute(THD *thd)
683683

684684
if (!st)
685685
{
686-
if (!thd->variables.pseudo_slave_mode ||
686+
if (!thd->binlog_applier_has_detached_trx() ||
687687
!(st= applier_reset_xa_trans(thd)))
688688
my_ok(thd);
689689
}

0 commit comments

Comments
 (0)