diff options
author | Sergei Golubchik <serg@mariadb.org> | 2017-11-10 01:38:03 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2017-11-10 01:38:03 +0100 |
commit | 2a4e4335c4bcb7f7488c9b91bdc8a2da3da5cf61 (patch) | |
tree | eadf9e2e8c0d2fccdd1db226395b8232b67737d6 | |
parent | 7002291b8aa2e036a7adfd23d961dc09b4f01f46 (diff) | |
parent | 9572bbdc3791178b82d4c71a8e3948a3a35123d4 (diff) | |
download | mariadb-git-2a4e4335c4bcb7f7488c9b91bdc8a2da3da5cf61.tar.gz |
Merge branch 'github/10.0-galera' into 10.1
-rw-r--r-- | cmake/wsrep.cmake | 2 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/MW-388.result | 46 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/MW-402.result | 192 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/MW-388.test | 76 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/MW-402.test | 228 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_ftwrl.test | 7 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_suspend_slave.test | 4 | ||||
-rw-r--r-- | scripts/wsrep_sst_common.sh | 8 | ||||
-rw-r--r-- | sql/sql_class.cc | 11 | ||||
-rw-r--r-- | sql/sql_parse.cc | 18 | ||||
-rw-r--r-- | sql/wsrep_hton.cc | 3 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 3 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 11 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 1 | ||||
-rw-r--r-- | storage/xtradb/row/row0ins.cc | 11 |
15 files changed, 592 insertions, 29 deletions
diff --git a/cmake/wsrep.cmake b/cmake/wsrep.cmake index e6d1379aea3..b5dc8b9f157 100644 --- a/cmake/wsrep.cmake +++ b/cmake/wsrep.cmake @@ -26,7 +26,7 @@ ENDIF() OPTION(WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)" ${with_wsrep_default}) # Set the patch version -SET(WSREP_PATCH_VERSION "20") +SET(WSREP_PATCH_VERSION "21") # Obtain wsrep API version FILE(STRINGS "${MySQL_SOURCE_DIR}/wsrep/wsrep_api.h" WSREP_API_VERSION 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..17d347a11fb --- /dev/null +++ b/mysql-test/suite/galera/r/MW-388.result @@ -0,0 +1,46 @@ +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 wsrep_slave_threads = 2; +SET GLOBAL DEBUG = "d,sync.wsrep_apply_cb"; +Warnings: +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +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_after_replication SIGNAL wsrep_after_replication_reached WAIT_FOR wsrep_after_replication_continue'; +CALL insert_proc ();; +SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached"; +SET GLOBAL DEBUG = ""; +Warnings: +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +SET DEBUG_SYNC = "now SIGNAL wsrep_after_replication_continue"; +SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb"; +SELECT @errno = 1213; +@errno = 1213 +1 +SELECT * FROM t1; +f1 f2 +1 node 2 +3 node 1 +SELECT * FROM t1; +f1 f2 +1 node 2 +3 node 1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +DROP TABLE t1; +DROP PROCEDURE insert_proc; +SET GLOBAL debug = NULL; +Warnings: +Warning 1287 '@@debug' is deprecated and will be removed in a future release. Please use '@@debug_dbug' instead +SET debug_sync='RESET'; +SELECT @@debug_sync; +@@debug_sync +ON - current signal: '' diff --git a/mysql-test/suite/galera/r/MW-402.result b/mysql-test/suite/galera/r/MW-402.result new file mode 100644 index 00000000000..fdcf6e324b5 --- /dev/null +++ b/mysql-test/suite/galera/r/MW-402.result @@ -0,0 +1,192 @@ +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE); +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE c SET f2=1 where f1=1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +DELETE FROM p WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +2 0 +SELECT * FROM c; +f1 p_id f2 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE); +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE c SET f2=2 where f1=1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +UPDATE p set f1=11 WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +2 0 +11 0 +SELECT * FROM c; +f1 p_id f2 +1 11 0 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE); +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); +INSERT INTO c VALUES (1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE c SET p_id=2 where f1=1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +UPDATE p set f1=11 WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +2 0 +11 0 +SELECT * FROM c; +f1 p_id f2 +1 11 0 +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p set f1=21 WHERE f1 = 11; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +UPDATE c SET p_id=2 where f1=1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p; +f1 f2 +2 0 +11 0 +SELECT * FROM c; +f1 p_id f2 +1 2 0 +DROP TABLE c; +DROP TABLE p; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) +ON DELETE CASCADE, +CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1)); +INSERT INTO p1 VALUES (1, 0); +INSERT INTO p2 VALUES (1, 0); +INSERT INTO c VALUES (1, 1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +UPDATE p2 SET f2=2 where f1=1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +DELETE FROM p1 WHERE f1 = 1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +SELECT * FROM p1; +f1 f2 +SELECT * FROM p2; +f1 f2 +1 2 +SELECT * FROM c; +f1 p1_id p2_id f2 +DROP TABLE c; +DROP TABLE p1; +DROP TABLE p2; +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, +f2 INTEGER, +CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) +ON DELETE CASCADE, +CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) +ON DELETE CASCADE); +INSERT INTO p1 VALUES (1, 0); +INSERT INTO p2 VALUES (1, 0); +INSERT INTO c VALUES (1, 1, 1, 0); +SET AUTOCOMMIT=ON; +START TRANSACTION; +DELETE FROM p2 WHERE f1=1; +SET SESSION wsrep_sync_wait = 0; +SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync'; +DELETE FROM p1 WHERE f1=1; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'dbug='; +SET GLOBAL wsrep_provider_options = 'dbug=d,local_monitor_enter_sync'; +COMMIT; +SET SESSION wsrep_on = 0; +SET SESSION wsrep_on = 1; +SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync'; +SET GLOBAL wsrep_provider_options = 'signal=local_monitor_enter_sync'; +SET GLOBAL wsrep_provider_options = 'dbug='; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM p1; +f1 f2 +SELECT * FROM p2; +f1 f2 +1 0 +SELECT * FROM c; +f1 p1_id p2_id f2 +DROP TABLE c; +DROP TABLE p1; +DROP TABLE p2; 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..209695dca80 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-388.test @@ -0,0 +1,76 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.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 ;| + +# We need two slave threads here to guarantee progress. +# If we use only one thread the following could happen +# in node_1: +# We block the only slave thread in wsrep_apply_cb and we +# issue an INSERT (by calling the stored procedure) that will +# try to acquire galera's local monitor in pre_commit(). +# This usually works fine, except for when a commit cut event +# sneaks in the slave queue and gets a local seqno smaller than +# that of the INSERT. Because there is only one slave thread, +# commit cut is not processed and therefore does not advance +# local monitor, and our INSERT remains stuck there. +SET GLOBAL wsrep_slave_threads = 2; +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_after_replication SIGNAL wsrep_after_replication_reached WAIT_FOR wsrep_after_replication_continue'; +--send CALL insert_proc (); + +--connection node_1a +SET SESSION DEBUG_SYNC = "now WAIT_FOR wsrep_after_replication_reached"; + + +SET GLOBAL DEBUG = ""; +SET DEBUG_SYNC = "now SIGNAL wsrep_after_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 = 1213; +SELECT * FROM t1; + +--connection node_2 +SELECT * FROM t1; + +--connection node_1 +SET GLOBAL wsrep_slave_threads = DEFAULT; +DROP TABLE t1; +DROP PROCEDURE insert_proc; + +SET GLOBAL debug = NULL; +SET debug_sync='RESET'; + +# Make sure no pending signals are leftover to surprise subsequent tests. +SELECT @@debug_sync; diff --git a/mysql-test/suite/galera/t/MW-402.test b/mysql-test/suite/galera/t/MW-402.test new file mode 100644 index 00000000000..80f368b50c8 --- /dev/null +++ b/mysql-test/suite/galera/t/MW-402.test @@ -0,0 +1,228 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_debug_sync.inc +--source suite/galera/include/galera_have_debug_sync.inc + +# +# we must open connection node_1a here, MW-369.inc will use it later +# +--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 + +# +# cascading delete operation is replicated from node2 +# and this conflicts with an update for child table in node1 +# +# As a result, the update should fail for certification error +# +--connection node_1 + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON DELETE CASCADE); + + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); + +INSERT INTO c VALUES (1, 1, 0); + +--let $mw_369_parent_query = UPDATE c SET f2=1 where f1=1 +--let $mw_369_child_query = DELETE FROM p WHERE f1 = 1 + +--connection node_1a +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# cascading update operation is replicated from node2 +# and this conflicts with an update for child table in node1 +# +# As a result, the update should fail for certification error +# +--connection node_1 + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE); + + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); + +INSERT INTO c VALUES (1, 1, 0); + +--let $mw_369_parent_query = UPDATE c SET f2=2 where f1=1 +--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1 + +--connection node_1a +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# ON UPDATE CASCADE tests +# Here we update primary key of parent table to cause cascaded update +# on child table +# +# cascading update operation is replicated from node2 +# and this conflicts with an update for child table in node1 +# +# As a result, the update should fail for certification error +# +--connection node_1 + +CREATE TABLE p (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p_id INTEGER, f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p_id) REFERENCES p (f1) ON UPDATE CASCADE); + + +INSERT INTO p VALUES (1, 0); +INSERT INTO p VALUES (2, 0); + +INSERT INTO c VALUES (1, 1, 0); + +--let $mw_369_parent_query = UPDATE c SET p_id=2 where f1=1 +--let $mw_369_child_query = UPDATE p set f1=11 WHERE f1 = 1 + +--connection node_1a +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +# same as previous, but statements in different order +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +--let $mw_369_parent_query = UPDATE p set f1=21 WHERE f1 = 11 +--let $mw_369_child_query = UPDATE c SET p_id=2 where f1=1 + +--connection node_1a +--source MW-369.inc + +# Commit fails +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + + +--connection node_2 +SELECT * FROM p; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p; + +# +# CASCADE DELETE tests with two parent tables +# Here we cause cascaded operation on child table through +# one parent table and have other operation on the other +# parent table +# +# cascading update operation is replicated from node2 +# but this does not conflict with an update for the other parent table in node1 +# +# As a result, the update on p2 should succeed +# +--connection node_1 + +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) + ON DELETE CASCADE, + CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1)); + +INSERT INTO p1 VALUES (1, 0); +INSERT INTO p2 VALUES (1, 0); + +INSERT INTO c VALUES (1, 1, 1, 0); + +--let $mw_369_parent_query = UPDATE p2 SET f2=2 where f1=1 +--let $mw_369_child_query = DELETE FROM p1 WHERE f1 = 1 + +--connection node_1a +--source MW-369.inc + +# Commit succeeds +--connection node_1 +--reap + +--connection node_2 +SELECT * FROM p1; +SELECT * FROM p2; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p1; +DROP TABLE p2; + +# +# CASCADE DELETE tests with two parent tables +# Here we cause cascaded operation on child table through +# one parent table and issue other delete operation through the +# other parent table. The cascade progresses to same child table row where +# we should see the conflict to happen +# +# As a result, the update on p2 should fail +# +--connection node_1 + +CREATE TABLE p1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE p2 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=INNODB; +CREATE TABLE c (f1 INTEGER PRIMARY KEY, p1_id INTEGER, p2_id INTEGER, + f2 INTEGER, + CONSTRAINT fk_1 FOREIGN KEY (p1_id) REFERENCES p1 (f1) + ON DELETE CASCADE, + CONSTRAINT fk_2 FOREIGN KEY (p2_id) REFERENCES p2 (f1) + ON DELETE CASCADE); + +INSERT INTO p1 VALUES (1, 0); +INSERT INTO p2 VALUES (1, 0); + +INSERT INTO c VALUES (1, 1, 1, 0); + +--let $mw_369_parent_query = DELETE FROM p2 WHERE f1=1 +--let $mw_369_child_query = DELETE FROM p1 WHERE f1=1 + +--connection node_1a +--source MW-369.inc + +# Commit succeeds +--connection node_1 +--error ER_LOCK_DEADLOCK +--reap + +--connection node_2 +SELECT * FROM p1; +SELECT * FROM p2; +SELECT * FROM c; + +DROP TABLE c; +DROP TABLE p1; +DROP TABLE p2;
\ No newline at end of file diff --git a/mysql-test/suite/galera/t/galera_ftwrl.test b/mysql-test/suite/galera/t/galera_ftwrl.test index de8310e52d2..739255609ee 100644 --- a/mysql-test/suite/galera/t/galera_ftwrl.test +++ b/mysql-test/suite/galera/t/galera_ftwrl.test @@ -29,12 +29,11 @@ SELECT * FROM t1; UNLOCK TABLES; -SHOW TABLES; -SELECT COUNT(*) = 1 FROM t1; - --disable_query_log --eval SET GLOBAL wsrep_provider_options = "$wsrep_provider_options_orig"; --enable_query_log -DROP TABLE t1; +SHOW TABLES; +SELECT COUNT(*) = 1 FROM t1; +DROP TABLE t1; diff --git a/mysql-test/suite/galera/t/galera_suspend_slave.test b/mysql-test/suite/galera/t/galera_suspend_slave.test index dcc4a8d14c3..aa4543cf81c 100644 --- a/mysql-test/suite/galera/t/galera_suspend_slave.test +++ b/mysql-test/suite/galera/t/galera_suspend_slave.test @@ -25,7 +25,7 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; my $pid_filename = $ENV{'NODE_2_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -19 $mysqld_pid"); + system("kill -SIGSTOP $mysqld_pid"); exit(0); EOF @@ -37,7 +37,7 @@ INSERT INTO t1 VALUES (1); my $pid_filename = $ENV{'NODE_2_PIDFILE'}; my $mysqld_pid = `cat $pid_filename`; chomp($mysqld_pid); - system("kill -18 $mysqld_pid"); + system("kill -SIGCONT $mysqld_pid"); exit(0); EOF diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 723fd311f88..1ef4830661b 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -256,18 +256,18 @@ parse_cnf() # finally get the variable value (if variables has been specified multiple time use the last value only) # look in group+suffix - if [[ -n $WSREP_SST_OPT_CONF_SUFFIX ]]; then + if [ -n $WSREP_SST_OPT_CONF_SUFFIX ]; then reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF "${group}${WSREP_SST_OPT_CONF_SUFFIX}" | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) fi # look in group - if [[ -z $reval ]]; then + if [ -z $reval ]; then reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) fi # use default if we haven't found a value - if [[ -z $reval ]]; then - [[ -n $3 ]] && reval=$3 + if [ -z $reval ]; then + [ -n $3 ] && reval=$3 fi echo $reval } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c12f1ec4dc8..2ebcea2d6f4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4858,11 +4858,14 @@ extern "C" int thd_non_transactional_update(const MYSQL_THD thd) extern "C" int thd_binlog_format(const MYSQL_THD thd) { - if (((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()) && - thd->variables.option_bits & OPTION_BIN_LOG) + if (WSREP(thd)) + { + /* for wsrep binlog format is meaningful also when binlogging is off */ return (int) thd->wsrep_binlog_format(); - else - return BINLOG_FORMAT_UNSPEC; + } + if (mysql_bin_log.is_open() && (thd->variables.option_bits & OPTION_BIN_LOG)) + return (int) thd->variables.binlog_format; + return BINLOG_FORMAT_UNSPEC; } extern "C" void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e14531a40f0..7337a8aeb21 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5719,6 +5719,24 @@ finish: } if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR)) trans_rollback_stmt(thd); +#ifdef WITH_WSREP + else if (thd->spcont && + (thd->wsrep_conflict_state == MUST_ABORT || + thd->wsrep_conflict_state == CERT_FAILURE)) + { + /* + The error was cleared, but THD was aborted by wsrep and + wsrep_conflict_state is still set accordingly. This + situation is expected if we are running a stored procedure + that declares a handler that catches ER_LOCK_DEADLOCK error. + In which case the error may have been cleared in method + sp_rcontext::handle_sql_condition(). + */ + trans_rollback_stmt(thd); + thd->wsrep_conflict_state= NO_CONFLICT; + thd->killed= NOT_KILLED; + } +#endif /* WITH_WSREP */ else { /* If commit fails, we should be able to reset the OK status. */ diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc index 2733a91a3c9..75c1526cb15 100644 --- a/sql/wsrep_hton.cc +++ b/sql/wsrep_hton.cc @@ -505,6 +505,9 @@ wsrep_run_wsrep_commit(THD *thd, bool all) } mysql_mutex_lock(&thd->LOCK_wsrep_thd); + + DEBUG_SYNC(thd, "wsrep_after_replication"); + switch(rcode) { case 0: /* diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index 1d117766db4..b21041eb0f8 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -301,8 +301,9 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type) if (wsrep_inited == 1) wsrep_deinit(false); - char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider + char* tmp= strdup(wsrep_provider); // wsrep_init() rewrites provider //when fails + if (wsrep_init()) { my_error(ER_CANT_OPEN_LIBRARY, MYF(0), tmp); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 84f61956c47..acbffb3a386 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1291,12 +1291,11 @@ row_ins_foreign_check_on_constraint( #ifdef WITH_WSREP err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - clust_rec, - clust_index, - FALSE, - (node) ? TRUE : FALSE); + thr_get_trx(thr), + foreign, + clust_rec, + clust_index, + FALSE, FALSE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %d\n", err); diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 9baf85ab858..1cd0b6ede51 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -2435,4 +2435,3 @@ trx_start_for_ddl_low( ut_error; } - diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc index e8bae7427f4..62e194020bc 100644 --- a/storage/xtradb/row/row0ins.cc +++ b/storage/xtradb/row/row0ins.cc @@ -1297,12 +1297,11 @@ row_ins_foreign_check_on_constraint( #ifdef WITH_WSREP err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - clust_rec, - clust_index, - FALSE, - (node) ? TRUE : FALSE); + thr_get_trx(thr), + foreign, + clust_rec, + clust_index, + FALSE, FALSE); if (err != DB_SUCCESS) { fprintf(stderr, "WSREP: foreign key append failed: %d\n", err); |