summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2013-06-07 09:31:11 +0200
committerunknown <knielsen@knielsen-hq.org>2013-06-07 09:31:11 +0200
commitdbe2c5060edec13d591d176df08d0fc07c3aa6dd (patch)
treecad304799b2c4a53b41b71985ce83ab9d2f1c192
parent7b6ab5638ac8bd4bb604e3c39d5f21218ab17688 (diff)
downloadmariadb-git-dbe2c5060edec13d591d176df08d0fc07c3aa6dd.tar.gz
MDEV-4591:Setting gtid* values from inside a transaction might cause unexpected results
Now we give an error on attempts to set @@SESSION.gtid_domain_id or @@SESSION.gtid_seq_no when a transaction is active.
-rw-r--r--mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result23
-rw-r--r--mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test17
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/sys_vars.cc22
4 files changed, 65 insertions, 1 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result
index 59f288d4afd..8bf2016faea 100644
--- a/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result
+++ b/mysql-test/suite/rpl/r/rpl_gtid_errorhandling.result
@@ -29,6 +29,29 @@ include/start_slave.inc
SELECT * FROM t1;
a
1
+*** Test that setting @@gtid_domain_id or @@gtid_seq_no is not allowed inside a transaction. ***
+BEGIN;
+INSERT INTO t1 VALUES (100);
+SET SESSION gtid_domain_id= 100;
+ERROR HY000: Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a transaction
+SET SESSION gtid_seq_no= 100;
+ERROR HY000: Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a transaction
+SET @old_domain= @@GLOBAL.gtid_domain_id;
+SET GLOBAL gtid_domain_id= 100;
+SELECT @@SESSION.gtid_domain_id;
+@@SESSION.gtid_domain_id
+0
+SET GLOBAL gtid_domain_id= @old_domain;
+INSERT INTO t1 VALUES (101);
+SELECT * FROM t1 ORDER BY a;
+a
+1
+100
+101
+ROLLBACK;
+SELECT * FROM t1 ORDER BY a;
+a
+1
*** Test requesting an explicit GTID position that conflicts with newer GTIDs of our own in the binlog. ***
include/stop_slave.inc
RESET MASTER;
diff --git a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test
index f36f7fa8010..2070ec6a3ff 100644
--- a/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test
+++ b/mysql-test/suite/rpl/t/rpl_gtid_errorhandling.test
@@ -52,6 +52,23 @@ ALTER TABLE mysql.gtid_slave_pos ADD PRIMARY KEY (domain_id, sub_id);
SELECT * FROM t1;
+--echo *** Test that setting @@gtid_domain_id or @@gtid_seq_no is not allowed inside a transaction. ***
+BEGIN;
+INSERT INTO t1 VALUES (100);
+--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
+SET SESSION gtid_domain_id= 100;
+--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
+SET SESSION gtid_seq_no= 100;
+SET @old_domain= @@GLOBAL.gtid_domain_id;
+SET GLOBAL gtid_domain_id= 100;
+SELECT @@SESSION.gtid_domain_id;
+SET GLOBAL gtid_domain_id= @old_domain;
+INSERT INTO t1 VALUES (101);
+SELECT * FROM t1 ORDER BY a;
+ROLLBACK;
+SELECT * FROM t1 ORDER BY a;
+
+
--echo *** Test requesting an explicit GTID position that conflicts with newer GTIDs of our own in the binlog. ***
--connection slave
--source include/stop_slave.inc
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 9acdda3b78b..48809417a6c 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6551,3 +6551,7 @@ ER_GTID_START_FROM_BINLOG_HOLE
eng "The binlog on the master is missing the GTID %u-%u-%llu requested by the slave (even though both a prior and a subsequent sequence number does exist), and GTID strict mode is enabled"
ER_SLAVE_UNEXPECTED_MASTER_SWITCH
eng "Unexpected GTID received from master after reconnect. This normally indicates that the master server was replaced without restarting the slave threads. %s"
+ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
+ eng "Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a transaction"
+ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO
+ eng "Cannot modify @@session.gtid_domain_id or @@session.gtid_seq_no inside a stored function or trigger"
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index b25f979cf79..4066a04aea7 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1203,6 +1203,21 @@ static Sys_var_ulong Sys_pseudo_thread_id(
BLOCK_SIZE(1), NO_MUTEX_GUARD, IN_BINLOG,
ON_CHECK(check_has_super));
+static bool
+check_gtid_domain_id(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_has_super(self, thd, var))
+ return true;
+ if (var->type != OPT_GLOBAL &&
+ error_if_in_trans_or_substatement(thd,
+ ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO,
+ ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO))
+ return true;
+
+ return false;
+}
+
+
static Sys_var_uint Sys_gtid_domain_id(
"gtid_domain_id",
"Used with global transaction ID to identify logically independent "
@@ -1213,7 +1228,7 @@ static Sys_var_uint Sys_gtid_domain_id(
SESSION_VAR(gtid_domain_id),
CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, UINT_MAX32), DEFAULT(0),
BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG,
- ON_CHECK(check_has_super));
+ ON_CHECK(check_gtid_domain_id));
static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
@@ -1223,6 +1238,11 @@ static bool check_gtid_seq_no(sys_var *self, THD *thd, set_var *var)
if (check_has_super(self, thd, var))
return true;
+ if (error_if_in_trans_or_substatement(thd,
+ ER_STORED_FUNCTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO,
+ ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_GTID_DOMAIN_ID_SEQ_NO))
+ return true;
+
domain_id= thd->variables.gtid_domain_id;
server_id= thd->variables.server_id;
seq_no= (uint64)var->value->val_uint();