Implement variable legacy_xa_rollback_at_disconnect to support
backwards compatibility for applications that rely on the pre-10.5
behavior for connection disconnect, which is to rollback the
transaction (in violation of the XA specification).

Signed-off-by: Kristian Nielsen <kniel...@knielsen-hq.org>
---
 mysql-test/main/mysqld--help.result           |  8 +++++++
 mysql-test/main/xa.result                     | 16 +++++++++++++
 mysql-test/main/xa.test                       | 19 +++++++++++++++
 mysql-test/suite/rpl/r/rpl_xa.result          | 24 +++++++++++++++++++
 .../rpl/r/rpl_xa_gtid_pos_auto_engine.result  | 24 +++++++++++++++++++
 mysql-test/suite/rpl/t/rpl_xa.inc             | 23 ++++++++++++++++++
 .../sys_vars/r/sysvars_server_embedded.result | 10 ++++++++
 .../r/sysvars_server_notembedded.result       | 10 ++++++++
 sql/sql_class.cc                              |  7 +++++-
 sql/sql_class.h                               |  1 +
 sql/sys_vars.cc                               | 10 ++++++++
 sql/xa.h                                      |  1 +
 12 files changed, 152 insertions(+), 1 deletion(-)

diff --git a/mysql-test/main/mysqld--help.result 
b/mysql-test/main/mysqld--help.result
index 1a2a740cb77..ac5ab0a88b1 100644
--- a/mysql-test/main/mysqld--help.result
+++ b/mysql-test/main/mysqld--help.result
@@ -433,6 +433,13 @@ The following specify which files/extra groups are read 
(specified before remain
  --lc-time-names=name 
  Set the language used for the month names and the days of
  the week.
+ --legacy-xa-rollback-at-disconnect 
+ If a user session disconnects after putting a transaction
+ into the XA PREPAREd state, roll back the transaction.
+ Can be used for backwards compatibility to enable this
+ pre-10.5 behavior for applications that expect it. Note
+ that this violates the XA specification and should not be
+ used for new code
  --local-infile      Enable LOAD DATA LOCAL INFILE
  (Defaults to on; use --skip-local-infile to disable.)
  --lock-wait-timeout=# 
@@ -1566,6 +1573,7 @@ large-pages FALSE
 lc-messages en_US
 lc-messages-dir MYSQL_SHAREDIR/
 lc-time-names en_US
+legacy-xa-rollback-at-disconnect FALSE
 local-infile TRUE
 lock-wait-timeout 86400
 log-bin foo
diff --git a/mysql-test/main/xa.result b/mysql-test/main/xa.result
index faabf1cf695..58ad2a54edd 100644
--- a/mysql-test/main/xa.result
+++ b/mysql-test/main/xa.result
@@ -592,6 +592,22 @@ formatID   gtrid_length    bqual_length    data
 xa rollback '4';
 ERROR XA100: XA_RBROLLBACK: Transaction branch was rolled back
 set @@global.read_only=@sav_read_only;
+# MDEV-35019: Provide a way to enable "rollback XA on disconnect" behavior we 
had before 10.5.2
+# Test legacy_xa_rollback_at_disconnect option.
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 0);
+connect  con1,localhost,root,,;
+SET SESSION legacy_xa_rollback_at_disconnect= 1;
+XA START '5';
+INSERT INTO t1 VALUES (2, 0);
+XA END '5';
+XA PREPARE '5';
+disconnect con1;
+connection default;
+INSERT INTO t1 VALUES (3, 0);
+XA ROLLBACK '5';
+ERROR XAE04: XAER_NOTA: Unknown XID
+DROP TABLE t1;
 #
 # End of 10.5 tests
 #
diff --git a/mysql-test/main/xa.test b/mysql-test/main/xa.test
index e1ca39be9ab..dfc97002168 100644
--- a/mysql-test/main/xa.test
+++ b/mysql-test/main/xa.test
@@ -747,6 +747,25 @@ xa rollback '4';
 set @@global.read_only=@sav_read_only;
 
 
+--echo # MDEV-35019: Provide a way to enable "rollback XA on disconnect" 
behavior we had before 10.5.2
+--echo # Test legacy_xa_rollback_at_disconnect option.
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1, 0);
+connect (con1,localhost,root,,);
+SET SESSION legacy_xa_rollback_at_disconnect= 1;
+XA START '5';
+INSERT INTO t1 VALUES (2, 0);
+XA END '5';
+XA PREPARE '5';
+disconnect con1;
+
+connection default;
+--source include/wait_until_count_sessions.inc
+INSERT INTO t1 VALUES (3, 0);
+--error ER_XAER_NOTA
+XA ROLLBACK '5';
+DROP TABLE t1;
+
 --echo #
 --echo # End of 10.5 tests
 --echo #
diff --git a/mysql-test/suite/rpl/r/rpl_xa.result 
b/mysql-test/suite/rpl/r/rpl_xa.result
index 061c7b360d0..7b58d3d6e06 100644
--- a/mysql-test/suite/rpl/r/rpl_xa.result
+++ b/mysql-test/suite/rpl/r/rpl_xa.result
@@ -280,4 +280,28 @@ disconnect con1;
 connection master;
 xa commit '1';
 drop table t2, t1;
+# MDEV-35019 Provide a way to enable "rollback XA on disconnect" behavior we 
had before 10.5.2
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (3);
+connect con1, localhost,root;
+SET SESSION legacy_xa_rollback_at_disconnect= 1;
+XA START '3';
+INSERT INTO t1 VALUES (2);
+XA END '3';
+XA PREPARE '3';
+disconnect con1;
+connection master;
+include/save_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+3
+connection slave;
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+3
+connection master;
+DROP TABLE t1;
 include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_xa_gtid_pos_auto_engine.result 
b/mysql-test/suite/rpl/r/rpl_xa_gtid_pos_auto_engine.result
index 35625cc7026..2cb9b6c4290 100644
--- a/mysql-test/suite/rpl/r/rpl_xa_gtid_pos_auto_engine.result
+++ b/mysql-test/suite/rpl/r/rpl_xa_gtid_pos_auto_engine.result
@@ -289,6 +289,30 @@ disconnect con1;
 connection master;
 xa commit '1';
 drop table t2, t1;
+# MDEV-35019 Provide a way to enable "rollback XA on disconnect" behavior we 
had before 10.5.2
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (3);
+connect con1, localhost,root;
+SET SESSION legacy_xa_rollback_at_disconnect= 1;
+XA START '3';
+INSERT INTO t1 VALUES (2);
+XA END '3';
+XA PREPARE '3';
+disconnect con1;
+connection master;
+include/save_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+3
+connection slave;
+include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+a
+1
+3
+connection master;
+DROP TABLE t1;
 connection slave;
 include/stop_slave.inc
 SET @@global.gtid_pos_auto_engines="";
diff --git a/mysql-test/suite/rpl/t/rpl_xa.inc 
b/mysql-test/suite/rpl/t/rpl_xa.inc
index d22d2d2ef3d..050b9597ccc 100644
--- a/mysql-test/suite/rpl/t/rpl_xa.inc
+++ b/mysql-test/suite/rpl/t/rpl_xa.inc
@@ -431,3 +431,26 @@ disconnect con1;
 connection master;
 xa commit '1';
 drop table t2, t1;
+
+--echo # MDEV-35019 Provide a way to enable "rollback XA on disconnect" 
behavior we had before 10.5.2
+CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1), (3);
+
+connect con1, localhost,root;
+SET SESSION legacy_xa_rollback_at_disconnect= 1;
+XA START '3';
+INSERT INTO t1 VALUES (2);
+XA END '3';
+XA PREPARE '3';
+--disconnect con1
+
+--connection master
+--source include/save_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--connection slave
+--source include/sync_with_master_gtid.inc
+SELECT * FROM t1 ORDER BY a;
+
+--connection master
+DROP TABLE t1;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result 
b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index fcd1ee9a141..d45ab7f80c8 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -1532,6 +1532,16 @@ NUMERIC_BLOCK_SIZE       NULL
 ENUM_VALUE_LIST        NULL
 READ_ONLY      NO
 COMMAND_LINE_ARGUMENT  NULL
+VARIABLE_NAME  LEGACY_XA_ROLLBACK_AT_DISCONNECT
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE  BOOLEAN
+VARIABLE_COMMENT       If a user session disconnects after putting a 
transaction into the XA PREPAREd state, roll back the transaction. Can be used 
for backwards compatibility to enable this pre-10.5 behavior for applications 
that expect it. Note that this violates the XA specification and should not be 
used for new code
+NUMERIC_MIN_VALUE      NULL
+NUMERIC_MAX_VALUE      NULL
+NUMERIC_BLOCK_SIZE     NULL
+ENUM_VALUE_LIST        OFF,ON
+READ_ONLY      NO
+COMMAND_LINE_ARGUMENT  OPTIONAL
 VARIABLE_NAME  LICENSE
 VARIABLE_SCOPE GLOBAL
 VARIABLE_TYPE  VARCHAR
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result 
b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 1d5e9499c7a..73e853f12a5 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -1642,6 +1642,16 @@ NUMERIC_BLOCK_SIZE       NULL
 ENUM_VALUE_LIST        NULL
 READ_ONLY      NO
 COMMAND_LINE_ARGUMENT  NULL
+VARIABLE_NAME  LEGACY_XA_ROLLBACK_AT_DISCONNECT
+VARIABLE_SCOPE SESSION
+VARIABLE_TYPE  BOOLEAN
+VARIABLE_COMMENT       If a user session disconnects after putting a 
transaction into the XA PREPAREd state, roll back the transaction. Can be used 
for backwards compatibility to enable this pre-10.5 behavior for applications 
that expect it. Note that this violates the XA specification and should not be 
used for new code
+NUMERIC_MIN_VALUE      NULL
+NUMERIC_MAX_VALUE      NULL
+NUMERIC_BLOCK_SIZE     NULL
+ENUM_VALUE_LIST        OFF,ON
+READ_ONLY      NO
+COMMAND_LINE_ARGUMENT  OPTIONAL
 VARIABLE_NAME  LICENSE
 VARIABLE_SCOPE GLOBAL
 VARIABLE_TYPE  VARCHAR
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 7913f1a40d2..cd0418553fa 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1552,7 +1552,12 @@ void THD::cleanup(void)
   close_temporary_tables();
 
   if (transaction->xid_state.is_explicit_XA())
-    trans_xa_detach(this);
+  {
+    if (unlikely(variables.legacy_xa_rollback_at_disconnect))
+      xa_trans_force_rollback(this);
+    else
+      trans_xa_detach(this);
+  }
   else
     trans_rollback(this);
 
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 7e5d9ac96e3..c0e304dd95f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -846,6 +846,7 @@ typedef struct system_variables
   uint in_subquery_conversion_threshold;
   ulong optimizer_max_sel_arg_weight;
   ulonglong max_rowid_filter_size;
+  my_bool legacy_xa_rollback_at_disconnect;
 
   vers_asof_timestamp_t vers_asof_timestamp;
   ulong vers_alter_history;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 9a4180ae000..18374544126 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -6761,3 +6761,13 @@ static Sys_var_ulonglong Sys_max_rowid_filter_size(
        SESSION_VAR(max_rowid_filter_size), CMD_LINE(REQUIRED_ARG),
        VALID_RANGE(1024, (ulonglong)~(intptr)0), DEFAULT(128*1024),
        BLOCK_SIZE(1));
+
+static Sys_var_mybool Sys_legacy_xa_rollback_at_disconnect(
+       "legacy_xa_rollback_at_disconnect",
+       "If a user session disconnects after putting a transaction into the XA "
+       "PREPAREd state, roll back the transaction. Can be used for backwards "
+       "compatibility to enable this pre-10.5 behavior for applications that "
+       "expect it. Note that this violates the XA specification and should not 
"
+       "be used for new code",
+       SESSION_VAR(legacy_xa_rollback_at_disconnect), CMD_LINE(OPT_ARG),
+       DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG);
diff --git a/sql/xa.h b/sql/xa.h
index 0b2d0696642..4260033d0fb 100644
--- a/sql/xa.h
+++ b/sql/xa.h
@@ -45,6 +45,7 @@ bool xid_cache_insert(XID *xid);
 bool xid_cache_insert(THD *thd, XID_STATE *xid_state, XID *xid);
 void xid_cache_delete(THD *thd, XID_STATE *xid_state);
 
+bool xa_trans_force_rollback(THD *thd);
 bool trans_xa_start(THD *thd);
 bool trans_xa_end(THD *thd);
 bool trans_xa_prepare(THD *thd);
-- 
2.39.2

_______________________________________________
commits mailing list -- commits@lists.mariadb.org
To unsubscribe send an email to commits-le...@lists.mariadb.org

Reply via email to