Bug #98709 After executing the statement ‘xa parpare’, it may be lost
Submitted: 22 Feb 2020 5:35 Modified: 22 Feb 2020 13:45
Reporter: kfpanda kf Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server: XA transactions Severity:S3 (Non-critical)
Version:8.0 OS:Any
Assigned to: CPU Architecture:Any

[22 Feb 2020 5:35] kfpanda kf
Description:
After executing the statement 'xa parpare', the prepare state may be lost if the database is crashed. The reason for this problem is that the statement xa prepare does not ensure that the innodb log is written to disk。

How to repeat:
I wrote a test case that reproduced the problem with a high probability.

-----------  Code adjustments required for test cases.

diff --git a/sql/xa.cc b/sql/xa.cc
index 353640efe26..9874b6a0cbb 100644
--- a/sql/xa.cc
+++ b/sql/xa.cc
@@ -1135,6 +1135,7 @@ bool Sql_cmd_xa_prepare::trans_xa_prepare(THD *thd) {
     }
   }

+  DBUG_EXECUTE_IF("simulate_crash_after_xa_prepare", DBUG_SUICIDE(););
   return thd->is_error() || !xid_state->has_state(XID_STATE::XA_PREPARED);
 }

--------test cases:  binlog_gtid.bug_xa_prepare_lost.test

--source include/force_restart.inc
--source include/not_valgrind.inc
--source include/have_binlog_format_row.inc
--source include/have_debug.inc

call mtr.add_suppression("Found 1 prepared XA transactions");

# For reseting mysql.gtid_executed table
RESET MASTER;

--let $master_uuid= `SELECT @@GLOBAL.SERVER_UUID`

CREATE TABLE t1 (a INT) ENGINE=InnoDB;

FLUSH LOGS;
XA START '1';
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
XA END '1';
SET @@GLOBAL.DEBUG= '+d, simulate_crash_after_xa_prepare';
--error 2013
XA PREPARE '1';

--enable_reconnect
--echo # Restart the master server
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
--source include/wait_until_connected_again.inc
--disable_reconnect

XA ROLLBACK '1';
DROP TABLE t1;

--------------- Execute the test case

==============================================================================
                  TEST NAME                       RESULT  TIME (ms) COMMENT
------------------------------------------------------------------------------
[ 33%] binlog_gtid.bug_xa_prepare_lost 'mix'     [ skipped ]  Doesn't support --binlog-format = 'mixed'
[ 66%] binlog_gtid.bug_xa_prepare_lost 'row'     [ fail ]
        Test ended at 2020-02-21 15:35:10

CURRENT_TEST: binlog_gtid.bug_xa_prepare_lost
mysqltest: At line 30: Query 'XA ROLLBACK '1'' failed.
ERROR 1397 (XAE04): XAER_NOTA: Unknown XID

The result from queries just before the failure was:
call mtr.add_suppression("Found 1 prepared XA transactions");
RESET MASTER;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
FLUSH LOGS;
XA START '1';
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
XA END '1';
SET @@GLOBAL.DEBUG= '+d, simulate_crash_after_xa_prepare';
XA PREPARE '1';
ERROR HY000: Lost connection to MySQL server during query
# Restart the master server
safe_process[18390]: Child process: 18391, exit: 1

Suggested fix:
The cause of the problem function Sql_cmd_xa_prepare::trans_xa_prepare does not ensure that the innodb log for xa prepare is written to disk.
[22 Feb 2020 5:39] kfpanda kf
After executing the statement 'xa parpare', the prepare statement be lost if the database is crashed. The reason for this problem is that the statement xa prepare does not ensure that the innodb log is written to disk。
[22 Feb 2020 13:45] MySQL Verification Team
Hello!

Thank you for the report.
Imho this is duplicate of Bug #98616, please see Bug #98616.

Thanks,
Umesh