[MDEV-24981] LOAD INDEX may cause rollback of prepared XA transaction Created: 2021-02-25  Updated: 2023-04-27

Status: Open
Project: MariaDB Server
Component/s: XA
Affects Version/s: 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5

Type: Bug Priority: Major
Reporter: Daniele Sciascia Assignee: Sergei Golubchik
Resolution: Unresolved Votes: 0
Labels: regression

Issue Links:
Blocks
Duplicate
is duplicated by MDEV-25516 Assertion `m_thd == _current_thd()' f... Closed
Relates
relates to MDEV-21516 Assertion `lock_rec_find_set_bit(lock... Confirmed
relates to MDEV-30550 Assertion `state() == s_executing || ... Confirmed

 Description   

A statement such as LOAD INDEX INTO may cause a prepared XA to rollback.
For instance, consider the following case:

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
XA START 'a';
INSERT INTO t1 VALUES (1);
XA END 'a';
XA PREPARE 'a';
LOAD INDEX INTO cache t1 KEY(PRIMARY);
Table	Op	Msg_type	Msg_text
test.t1	preload_keys	Error	XAER_RMFAIL: The command cannot be executed when global transaction is in the  PREPARED state
test.t1	preload_keys	error	Corrupt
XA COMMIT 'a';
SELECT COUNT(*) FROM t1;
COUNT(*)
0

After XA PREPARE the user attempts to LOAD INDEX, internally, it causes a trans_rollback_implicit(), which will roll back the underlying XA transaction. After XA COMMIT the transaction left no side effects.
I would expect LOAD INDEX to not rollback the underlying XA transaction, and fail immediately with "XAER_RMFAIL: The command cannot be executed when global transaction is in PREPARED state".



 Comments   
Comment by Daniele Sciascia [ 2021-02-25 ]

I believe that trans_rollback_implicit() is missing the following check at the beginning:

if (trans_check(thd))
  DBUG_RETURN(TRUE);

Comment by Alice Sherepa [ 2021-02-25 ]

MariaDB 10.0,10.1,10.4,10.5,10.6 behaves as in description.
10.2,10.3:

10.2 5ecaf52d42a1e464c

MariaDB [test]> CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) Engine=Innodb;
Query OK, 0 rows affected (0.05 sec)
 
MariaDB [test]> XA START 'a';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> INSERT INTO t1 VALUES (1);
Query OK, 1 row affected (0.00 sec)
 
MariaDB [test]> XA END 'a';
Query OK, 0 rows affected (0.00 sec)
 
MariaDB [test]> XA PREPARE 'a';
Query OK, 0 rows affected (0.01 sec)
 
MariaDB [test]> XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|        1 |            1 |            0 | a    |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)
 
MariaDB [test]> LOAD INDEX INTO cache t1 KEY(PRIMARY);
+---------+--------------+----------+-----------------------------------------------------------------------------------------------+
| Table   | Op           | Msg_type | Msg_text                                                                                      |
+---------+--------------+----------+-----------------------------------------------------------------------------------------------+
| test.t1 | preload_keys | Error    | XAER_RMFAIL: The command cannot be executed when global transaction is in the  PREPARED state |
| test.t1 | preload_keys | error    | Corrupt                                                                                       |
+---------+--------------+----------+-----------------------------------------------------------------------------------------------+
2 rows in set (0.01 sec)
 
MariaDB [test]> XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
|       -1 |            1 |            0 | a    |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)
 
MariaDB [test]> XA COMMIT 'a';
ERROR 1397 (XAE04): XAER_NOTA: Unknown XID
MariaDB [test]> SELECT COUNT(*) FROM t1;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  PREPARED state

Generated at Thu Feb 08 09:34:11 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.