summaryrefslogtreecommitdiff
path: root/mysql-test/suite
diff options
context:
space:
mode:
authorDaniele Sciascia <daniele.sciascia@galeracluster.com>2017-07-11 12:55:03 +0200
committerJan Lindström <jan.lindstrom@mariadb.com>2017-11-08 12:21:51 +0200
commit76f1195f5b8e77f7fe81d2fb1a62ca56d701f710 (patch)
tree46e0f2ec090add8f9128f4d420b00657a2f1e49e /mysql-test/suite
parent3cecb1bab381c256e43f0f095a7a02b115dfc7bc (diff)
downloadmariadb-git-76f1195f5b8e77f7fe81d2fb1a62ca56d701f710.tar.gz
MW-388 Fix conflict handling of SPs with DECLARE ... HANDLER
It is possible for a stored procedure that has an error handler that catches SQLEXCEPTION to call thd->clear_error() on a thd that failed certification. And because the error is cleared, wsrep patch proceeds with the normal path and may try to commit statements that should actually abort. This patch catches the situation where wsrep_conflict_state is still set, but the thd's error has been cleared, and rolls back the statement in such cases.
Diffstat (limited to 'mysql-test/suite')
-rw-r--r--mysql-test/suite/galera/r/MW-388.result33
-rw-r--r--mysql-test/suite/galera/t/MW-388.test54
2 files changed, 87 insertions, 0 deletions
diff --git a/mysql-test/suite/galera/r/MW-388.result b/mysql-test/suite/galera/r/MW-388.result
new file mode 100644
index 00000000000..f81f1e1a9fb
--- /dev/null
+++ b/mysql-test/suite/galera/r/MW-388.result
@@ -0,0 +1,33 @@
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
+CREATE PROCEDURE insert_proc ()
+BEGIN
+DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+BEGIN
+GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
+END;
+INSERT INTO t1 VALUES (1, 'node 1'),(2, 'node 1');
+INSERT INTO t1 VALUES (3, 'node 1');
+END|
+SET GLOBAL DEBUG = "d,sync.wsrep_apply_cb";
+INSERT INTO t1 VALUES (1, 'node 2');;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+SET SESSION wsrep_sync_wait = 0;
+SET SESSION DEBUG_SYNC = 'wsrep_before_replication SIGNAL wsrep_before_replication_reached WAIT_FOR wsrep_before_replication_continue';
+CALL insert_proc ();;
+SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_before_replication_reached";
+SET GLOBAL DEBUG = "";
+SET DEBUG_SYNC = "now SIGNAL wsrep_before_replication_continue";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+SELECT @errno;
+@errno
+1213
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+SELECT * FROM t1;
+f1 f2
+1 node 2
+3 node 1
+DROP TABLE t1;
+DROP PROCEDURE insert_proc;
diff --git a/mysql-test/suite/galera/t/MW-388.test b/mysql-test/suite/galera/t/MW-388.test
new file mode 100644
index 00000000000..59b28dba236
--- /dev/null
+++ b/mysql-test/suite/galera/t/MW-388.test
@@ -0,0 +1,54 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connection node_1
+CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(255)) Engine=InnoDB;
+
+DELIMITER |;
+CREATE PROCEDURE insert_proc ()
+BEGIN
+ DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
+ BEGIN
+ GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
+ END;
+ INSERT INTO t1 VALUES (1, 'node 1'),(2, 'node 1');
+ INSERT INTO t1 VALUES (3, 'node 1');
+END|
+DELIMITER ;|
+
+SET GLOBAL DEBUG = "d,sync.wsrep_apply_cb";
+
+--connection node_2
+--send INSERT INTO t1 VALUES (1, 'node 2');
+
+--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
+--connection node_1a
+SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
+
+--connection node_1
+SET SESSION wsrep_sync_wait = 0;
+SET SESSION DEBUG_SYNC = 'wsrep_before_replication SIGNAL wsrep_before_replication_reached WAIT_FOR wsrep_before_replication_continue';
+--send CALL insert_proc ();
+
+--connection node_1a
+SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_before_replication_reached";
+
+--connection node_1a
+SET GLOBAL DEBUG = "";
+SET DEBUG_SYNC = "now SIGNAL wsrep_before_replication_continue";
+SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
+
+--connection node_2
+--reap
+
+--connection node_1
+# We expect no errors here, because the handler in insert_proc() caught the deadlock error
+--reap
+SELECT @errno;
+SELECT * FROM t1;
+
+--connection node_2
+SELECT * FROM t1;
+
+DROP TABLE t1;
+DROP PROCEDURE insert_proc; \ No newline at end of file