Commit a4a9b08d authored by Andrei's avatar Andrei

MDEV-31949 III. Innodb flush_log_later for XA commit,rollback

The previous part I,II commits of the MDEV-31949 branch implement
XA-commit,rollback commands (shortcut as XAC,XAR here and elsewhere)
processing in the Engine from inside binlog group commit, similarly
how it's done to the normal transaction's commit.  Under enabled
binlogging the execution path is now the same for normal and xa
transactions:

       MYSQL_BIN_LOG::run_commit_ordered():
       ...
       /* for each hton do */
         hton->{commit_ordered,commit_by_xid,rollback_by_xid}
       ...
       return rc;

The current commit implements flush-log-later policy of durable write
at commit for the user xa. Unlike the normal trx case, XA-rollback
also needs a similar addressing.
parent 833e7e15
call mtr.add_suppression("Found 1 prepared XA transactions");
call mtr.add_suppression("unknown option");
CREATE TABLE t31949 (a INT PRIMARY KEY) ENGINE=Innodb;
CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND';
XA START '1';
INSERT INTO t31949 SET a=1;
XA END '1';
XA PREPARE '1';
# Kill and restart
# xid '1' most be recovered
XA RECOVER;
formatID gtrid_length bqual_length data
1 1 0 1
# COMMIT from an external connection
XA COMMIT '1';
# Kill and restart
# xid '1' must be committed
XA RECOVER;
formatID gtrid_length bqual_length data
select count(*) = 1 from t31949;
count(*) = 1
1
XA START '2';
INSERT INTO t31949 SET a=2;
XA END '2';
XA PREPARE '2';
# ROLLBACK from the native connection
XA ROLLBACK '2';
# Kill and restart
# xid '1' must be rolled back
XA RECOVER;
formatID gtrid_length bqual_length data
select count(*) = 1 from t31949;
count(*) = 1
1
XA START '3';
INSERT INTO t31949 SET a=3;
XA END '3';
XA PREPARE '3';
# COMMIT from the native connection
XA COMMIT '3';
# Kill and restart
# xid '3' must be committed
XA RECOVER;
formatID gtrid_length bqual_length data
select count(*) = 2 from t31949;
count(*) = 2
1
connect con4,127.0.0.1,root,,test,$MASTER_MYPORT,;
XA START '4';
INSERT INTO t31949 SET a=4;
XA END '4';
XA PREPARE '4';
disconnect con4;
connection default;
# ROLLBACK from an external connection
XA ROLLBACK '4';
# Kill and restart
# xid '4' must be rolled back
XA RECOVER;
formatID gtrid_length bqual_length data
select count(*) = 2 from t31949;
count(*) = 2
1
DROP TABLE t31949;
DROP VIEW v_processlist;
End of the tests
--source include/have_innodb.inc
--source include/have_binlog_format_row.inc
# MDEV-31949 slow xa on parallel slave
# Prove that XA-prepare,commit,rollback are crash-recoverable when
# the crash occurs after the OK is sent/received by the client.
# Both the external and native connection branches are tested.
call mtr.add_suppression("Found 1 prepared XA transactions");
call mtr.add_suppression("unknown option");
CREATE TABLE t31949 (a INT PRIMARY KEY) ENGINE=Innodb;
CREATE VIEW v_processlist as SELECT * FROM performance_schema.threads where type = 'FOREGROUND';
XA START '1';
INSERT INTO t31949 SET a=1;
XA END '1';
XA PREPARE '1';
--source include/kill_and_restart_mysqld.inc
--echo # xid '1' most be recovered
XA RECOVER;
--echo # COMMIT from an external connection
XA COMMIT '1';
--source include/kill_and_restart_mysqld.inc
--echo # xid '1' must be committed
XA RECOVER;
select count(*) = 1 from t31949;
XA START '2';
INSERT INTO t31949 SET a=2;
XA END '2';
XA PREPARE '2';
--echo # ROLLBACK from the native connection
XA ROLLBACK '2';
--source include/kill_and_restart_mysqld.inc
--echo # xid '1' must be rolled back
XA RECOVER;
select count(*) = 1 from t31949;
XA START '3';
INSERT INTO t31949 SET a=3;
XA END '3';
XA PREPARE '3';
--echo # COMMIT from the native connection
XA COMMIT '3';
--source include/kill_and_restart_mysqld.inc
--echo # xid '3' must be committed
XA RECOVER;
select count(*) = 2 from t31949;
--connect(con4,127.0.0.1,root,,test,$MASTER_MYPORT,)
--let $conn1_id=`SELECT connection_id()`
XA START '4';
INSERT INTO t31949 SET a=4;
XA END '4';
XA PREPARE '4';
--disconnect con4
--connection default
--let $wait_condition= SELECT count(*) = 0 FROM v_processlist WHERE PROCESSLIST_ID = $conn1_id
--source include/wait_condition.inc
--echo # ROLLBACK from an external connection
XA ROLLBACK '4';
--source include/kill_and_restart_mysqld.inc
--echo # xid '4' must be rolled back
XA RECOVER;
select count(*) = 2 from t31949;
# cleanup
DROP TABLE t31949;
DROP VIEW v_processlist;
--echo End of the tests
......@@ -17144,8 +17144,16 @@ innobase_commit_by_xid(
}
if (trx_t* trx = trx_get_trx_by_xid(xid)) {
THD *thd = current_thd;
if (thd)
thd_binlog_pos(thd, &trx->mysql_log_file_name,
&trx->mysql_log_offset);
if (trx->mysql_log_offset > 0)
trx->flush_log_later = true;
/* use cases are: disconnected xa, slave xa, recovery */
innobase_commit_low(trx);
trx->mysql_log_file_name = NULL;
ut_ad(trx->mysql_thd == NULL);
trx_deregister_from_2pc(trx);
ut_ad(!trx->will_lock); /* trx cache requirement */
......@@ -17184,7 +17192,14 @@ int innobase_rollback_by_xid(handlerton* hton, XID* xid)
trx->xid.null();
}
#endif /* WITH_WSREP */
THD *thd = current_thd;
if (thd)
thd_binlog_pos(thd, &trx->mysql_log_file_name,
&trx->mysql_log_offset);
if (trx->mysql_log_offset > 0)
trx->flush_log_later = true;
int ret = innobase_rollback_trx(trx);
trx->mysql_log_file_name = NULL;
ut_ad(!trx->will_lock);
trx->free();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment