Merge 10.4 into 10.5
This commit is contained in:
commit
627027a674
22
mysql-test/suite/galera/r/MDEV-20225.result
Normal file
22
mysql-test/suite/galera/r/MDEV-20225.result
Normal file
@ -0,0 +1,22 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT, f2 INT) ENGINE=InnoDB;
|
||||
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.f1);
|
||||
connection node_2;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
SET GLOBAL wsrep_slave_threads = 2;
|
||||
SET GLOBAL debug_dbug = 'd,sync.mdev_20225';
|
||||
DROP TRIGGER tr1;
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
connection node_2;
|
||||
SET GLOBAL debug_dbug = 'RESET';
|
||||
SET DEBUG_SYNC = 'now SIGNAL signal.mdev_20225_continue';
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL wsrep_slave_threads = 1;
|
||||
SHOW TRIGGERS;
|
||||
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
47
mysql-test/suite/galera/t/MDEV-20225.test
Normal file
47
mysql-test/suite/galera/t/MDEV-20225.test
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# MDEV-20225 - Verify that DROP TRIGGER gets keys assigned corresponding
|
||||
# to all affected tables.
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
CREATE TABLE t2 (f1 INT NOT NULL PRIMARY KEY AUTO_INCREMENT, f2 INT) ENGINE=InnoDB;
|
||||
|
||||
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (NULL, NEW.f1);
|
||||
|
||||
--connection node_2
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
SET GLOBAL wsrep_slave_threads = 2;
|
||||
SET GLOBAL debug_dbug = 'd,sync.mdev_20225';
|
||||
|
||||
--let $galera_connection_name = node_1a
|
||||
--let $galera_server_number = 1
|
||||
--source include/galera_connect.inc
|
||||
DROP TRIGGER tr1;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE STATE = 'debug sync point: now'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
|
||||
--connection node_1
|
||||
INSERT INTO t1 VALUES (NULL);
|
||||
# We must rely on sleep here. If the bug is fixed, the second applier
|
||||
# is not allowed to go past apply monitor which would trigger the bug,
|
||||
# so there is no sync point or condition to wait.
|
||||
--sleep 1
|
||||
|
||||
--connection node_2
|
||||
SET GLOBAL debug_dbug = 'RESET';
|
||||
SET DEBUG_SYNC = 'now SIGNAL signal.mdev_20225_continue';
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL wsrep_slave_threads = 1;
|
||||
|
||||
# Trigger should now be dropped on node_2.
|
||||
SHOW TRIGGERS;
|
||||
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
38
mysql-test/suite/galera/t/galera_sp_bf_abort.inc
Normal file
38
mysql-test/suite/galera/t/galera_sp_bf_abort.inc
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
#
|
||||
# Issue an INSERT for gap between 1 and 3 to node_2 and wait until it hits
|
||||
# apply monitor sync point on node_1
|
||||
#
|
||||
|
||||
--connection node_1a
|
||||
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||
--source include/galera_set_sync_point.inc
|
||||
|
||||
--connection node_2
|
||||
--eval $galera_sp_bf_abort_conflict
|
||||
|
||||
--connection node_1a
|
||||
--source include/galera_wait_sync_point.inc
|
||||
--source include/galera_clear_sync_point.inc
|
||||
|
||||
# Send a procedure to node_1 which should take a gap lock between
|
||||
# rows 1 and 3. It does not conflict with INSERT from node_2 in
|
||||
# certification. Park the UPDATE after replicate and let INSERT to
|
||||
# continue applying, generating a BF abort.
|
||||
|
||||
--let $galera_sync_point = after_replicate_sync
|
||||
--source include/galera_set_sync_point.inc
|
||||
|
||||
--connection node_1
|
||||
--send_eval CALL $galera_sp_bf_abort_proc
|
||||
|
||||
--connection node_1a
|
||||
--let $galera_sync_point = after_replicate_sync apply_monitor_slave_enter_sync
|
||||
--source include/galera_wait_sync_point.inc
|
||||
--source include/galera_clear_sync_point.inc
|
||||
|
||||
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||
--source include/galera_signal_sync_point.inc
|
||||
--let $galera_sync_point = after_replicate_sync
|
||||
--source include/galera_signal_sync_point.inc
|
||||
|
347
mysql-test/suite/galera/t/galera_sp_bf_abort.test
Normal file
347
mysql-test/suite/galera/t/galera_sp_bf_abort.test
Normal file
@ -0,0 +1,347 @@
|
||||
#
|
||||
# Test cases for stored procedure BF aborts.
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/galera_have_debug_sync.inc
|
||||
|
||||
--connection node_1
|
||||
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
|
||||
|
||||
# Control connection for Galera sync point management
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connection node_1a
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 1a: Procedure does and UPDATE which will suffer BF abort
|
||||
# but there is no actual conflict and non-conflicting INSERT.
|
||||
# The expected outcome is that both UPDATE and INSERT will succedd
|
||||
# and no errors are reported to the client, wsrep_local_replays is
|
||||
# incremented by one.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert()
|
||||
BEGIN
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 1b: Procedure does and UPDATE which will suffer BF abort
|
||||
# but there is no actual conflict and non-conflicting INSERT.
|
||||
# An EXIT HANDLER is declared for the procedure.
|
||||
# The expected outcome is that both UPDATE and INSERT will succedd
|
||||
# and no errors are reported to the client, wsrep_local_replays is
|
||||
# incremented by one.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert_with_exit_handler()
|
||||
BEGIN
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert_with_exit_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 1c: Procedure does and UPDATE which will suffer BF abort
|
||||
# but there is no actual conflict and non-conflicting INSERT.
|
||||
# A CONTINUE HANDLER is declared for the procedure.
|
||||
# The expected outcome is that both UPDATE and INSERT will succedd
|
||||
# and no errors are reported to the client, wsrep_local_replays is
|
||||
# incremented by one.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert_with_continue_handler()
|
||||
BEGIN
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert_with_continue_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 2a: UPDATE and INSERT are run inside a transaction and the transaction
|
||||
# will be BF aborted on COMMIT. The expected outcome is that the transaction
|
||||
# succeeds and no errors are reported to the client, wsrep_local_replays
|
||||
# is incremented by one.
|
||||
#
|
||||
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert_transaction()
|
||||
BEGIN
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
COMMIT;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert_transaction
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 2b: UPDATE and INSERT are run inside a transaction and the transaction
|
||||
# will be BF aborted on COMMIT. A CONTINUE HANDLER is declared for the
|
||||
# procedure. The expected outcome is that the transaction
|
||||
# succeeds and no errors are reported to the client, wsrep_local_replays
|
||||
# is incremented by one.
|
||||
#
|
||||
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert_transaction_with_continue_handler()
|
||||
BEGIN
|
||||
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
COMMIT;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert_transaction_with_continue_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
#
|
||||
# Case 2c: UPDATE and INSERT are run inside a transaction and the transaction
|
||||
# will be BF aborted on COMMIT. An EXIT HANDLE is declared for the procedure.
|
||||
# The expected outcome is that the transaction succeeds and no errors are
|
||||
# reported to the client, wsrep_local_replays is incremented by one.
|
||||
#
|
||||
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_update_insert_transaction_with_exit_handler()
|
||||
BEGIN
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET f2 = 'b';
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
COMMIT;
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_update_insert_transaction_with_exit_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
|
||||
#
|
||||
# Case 3a: Two INSERTs are run inside stored procedure, this time
|
||||
# the first INSERT will have a BF abort and real conflict. The expected outcome
|
||||
# is that the INSERT fails and an error is reported to the client.
|
||||
# wsrep_local_replays is not incremented.
|
||||
#
|
||||
# Notice that the resulting error code may be both
|
||||
# ER_DUP_ENTRY (procedure will exit with cert failure conflict state and
|
||||
# will be) or ER_LOCK_DEADLOCK depending on timing.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_insert_insert_conflict()
|
||||
BEGIN
|
||||
INSERT INTO t1 VALUES (2, 'd');
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--error ER_DUP_ENTRY,ER_LOCK_DEADLOCK
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
|
||||
#
|
||||
# Case 3b: Two INSERTs are run inside stored procedure, this time
|
||||
# the first INSERT will have a BF abort and real conflict.
|
||||
# An EXIT HANDLER is declared for the procedure. The expected outcome
|
||||
# is that the INSERT fails and an error is reported to the client.
|
||||
# wsrep_local_replays is not incremented.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_insert_insert_conflict_with_exit_handler()
|
||||
BEGIN
|
||||
DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT "Conflict exit handler";
|
||||
INSERT INTO t1 VALUES (2, 'd');
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict_with_exit_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
--connection node_1
|
||||
|
||||
#
|
||||
# Case 3c: Two INSERTs are run inside stored procedure, this time
|
||||
# the first INSERT will have a BF abort and real conflict.
|
||||
# A CONTINUE HANDLER is declared for the procedure. The expected outcome
|
||||
# is that the the first INSERT fails but the second is executed without
|
||||
# errors. wsrep_local_replays is not incremented.
|
||||
#
|
||||
DELIMITER |;
|
||||
CREATE PROCEDURE proc_insert_insert_conflict_with_continue_handler()
|
||||
BEGIN
|
||||
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT "Conflict continue handler";
|
||||
INSERT INTO t1 VALUES (2, 'd');
|
||||
INSERT INTO t1 VALUES (4, 'd');
|
||||
END|
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
|
||||
--let $wsrep_local_replays_orig = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--let $galera_sp_bf_abort_proc = proc_insert_insert_conflict_with_continue_handler
|
||||
--let $galera_sp_bf_abort_conflict = INSERT INTO t1 VALUES (2, 'c')
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
--source galera_sp_bf_abort.inc
|
||||
--connection node_1
|
||||
--reap
|
||||
SET SESSION wsrep_sync_wait = default;
|
||||
SELECT * FROM t1;
|
||||
--let $wsrep_local_replays_curr = `SELECT VARIABLE_VALUE FROM information_schema.global_status WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_curr - $wsrep_local_replays_orig = 0 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
DELETE FROM t1;
|
||||
|
||||
|
||||
DROP PROCEDURE proc_update_insert;
|
||||
DROP PROCEDURE proc_update_insert_with_continue_handler;
|
||||
DROP PROCEDURE proc_update_insert_with_exit_handler;
|
||||
DROP PROCEDURE proc_update_insert_transaction;
|
||||
DROP PROCEDURE proc_update_insert_transaction_with_continue_handler;
|
||||
DROP PROCEDURE proc_update_insert_transaction_with_exit_handler;
|
||||
DROP PROCEDURE proc_insert_insert_conflict;
|
||||
DROP PROCEDURE proc_insert_insert_conflict_with_exit_handler;
|
||||
DROP PROCEDURE proc_insert_insert_conflict_with_continue_handler;
|
||||
DROP TABLE t1;
|
106
sql/sp_head.cc
106
sql/sp_head.cc
@ -1345,6 +1345,69 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
|
||||
#endif /* WITH_WSREP */
|
||||
err_status= i->execute(thd, &ip);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
if (((thd->wsrep_trx().state() == wsrep::transaction::s_executing || thd->in_sub_stmt) &&
|
||||
(thd->is_fatal_error || thd->killed)))
|
||||
{
|
||||
WSREP_DEBUG("SP abort err status %d in sub %d trx state %d",
|
||||
err_status, thd->in_sub_stmt, thd->wsrep_trx().state());
|
||||
err_status= 1;
|
||||
thd->is_fatal_error= 1;
|
||||
/*
|
||||
SP was killed, and it is not due to a wsrep conflict.
|
||||
We skip after_command hook at this point because
|
||||
otherwise it clears the error, and cleans up the
|
||||
whole transaction. For now we just return and finish
|
||||
our handling once we are back to mysql_parse.
|
||||
|
||||
Same applies to a SP execution, which was aborted due
|
||||
to wsrep related conflict, but which is executing as sub statement.
|
||||
SP in sub statement level should not commit not rollback,
|
||||
we have to call for rollback is up-most SP level.
|
||||
*/
|
||||
WSREP_DEBUG("Skipping after_command hook for killed SP");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool must_replay= wsrep_must_replay(thd);
|
||||
if (must_replay)
|
||||
{
|
||||
WSREP_DEBUG("MUST_REPLAY set after SP, err_status %d trx state: %d",
|
||||
err_status, thd->wsrep_trx().state());
|
||||
}
|
||||
(void) wsrep_after_statement(thd);
|
||||
|
||||
/*
|
||||
Reset the return code to zero if the transaction was
|
||||
replayed succesfully.
|
||||
*/
|
||||
if (must_replay && !wsrep_current_error(thd))
|
||||
{
|
||||
err_status= 0;
|
||||
thd->get_stmt_da()->reset_diagnostics_area();
|
||||
}
|
||||
/*
|
||||
Final wsrep error status for statement is known only after
|
||||
wsrep_after_statement() call. If the error is set, override
|
||||
error in thd diagnostics area and reset wsrep client_state error
|
||||
so that the error does not get propagated via client-server protocol.
|
||||
*/
|
||||
if (wsrep_current_error(thd))
|
||||
{
|
||||
wsrep_override_error(thd, wsrep_current_error(thd),
|
||||
wsrep_current_error_status(thd));
|
||||
thd->wsrep_cs().reset_error();
|
||||
/* Reset also thd->killed if it has been set during BF abort. */
|
||||
if (thd->killed == KILL_QUERY)
|
||||
thd->killed= NOT_KILLED;
|
||||
/* if failed transaction was not replayed, must return with error from here */
|
||||
if (!must_replay) err_status = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
thd->m_digest= parent_digest;
|
||||
|
||||
if (i->free_list)
|
||||
@ -3604,49 +3667,6 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp)
|
||||
(char *)thd->security_ctx->host_or_ip,
|
||||
3);
|
||||
int res= mysql_execute_command(thd);
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd))
|
||||
{
|
||||
if ((thd->is_fatal_error || thd->killed_errno()) &&
|
||||
(thd->wsrep_trx().state() == wsrep::transaction::s_executing))
|
||||
{
|
||||
/*
|
||||
SP was killed, and it is not due to a wsrep conflict.
|
||||
We skip after_statement hook at this point because
|
||||
otherwise it clears the error, and cleans up the
|
||||
whole transaction. For now we just return and finish
|
||||
our handling once we are back to mysql_parse.
|
||||
*/
|
||||
WSREP_DEBUG("Skipping after_command hook for killed SP");
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool must_replay= wsrep_must_replay(thd);
|
||||
(void) wsrep_after_statement(thd);
|
||||
/*
|
||||
Reset the return code to zero if the transaction was
|
||||
replayed succesfully.
|
||||
*/
|
||||
if (res && must_replay && !wsrep_current_error(thd))
|
||||
res= 0;
|
||||
/*
|
||||
Final wsrep error status for statement is known only after
|
||||
wsrep_after_statement() call. If the error is set, override
|
||||
error in thd diagnostics area and reset wsrep client_state error
|
||||
so that the error does not get propagated via client-server protocol.
|
||||
*/
|
||||
if (wsrep_current_error(thd))
|
||||
{
|
||||
wsrep_override_error(thd, wsrep_current_error(thd),
|
||||
wsrep_current_error_status(thd));
|
||||
thd->wsrep_cs().reset_error();
|
||||
/* Reset also thd->killed if it has been set during BF abort. */
|
||||
if (thd->killed == KILL_QUERY)
|
||||
thd->reset_killed();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
MYSQL_QUERY_EXEC_DONE(res);
|
||||
*nextp= m_ip+1;
|
||||
return res;
|
||||
|
@ -9132,9 +9132,8 @@ SELECT_LEX_UNIT *LEX::parsed_select_expr_cont(SELECT_LEX_UNIT *unit,
|
||||
enum sub_select_type unit_type,
|
||||
bool distinct, bool oracle)
|
||||
{
|
||||
SELECT_LEX *sel1;
|
||||
if (!s2->next_select())
|
||||
sel1= s2;
|
||||
DBUG_ASSERT(!s2->next_select());
|
||||
SELECT_LEX *sel1= s2;
|
||||
SELECT_LEX *last= unit->pre_last_parse->next_select();
|
||||
|
||||
int cmp= oracle? 0 : cmp_unit_op(unit_type, last->get_linkage());
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "sql_handler.h" // mysql_ha_rm_tables
|
||||
#include "sp_cache.h" // sp_invalidate_cache
|
||||
#include <mysys_err.h>
|
||||
#include "debug_sync.h"
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
@ -507,7 +508,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL);
|
||||
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, tables);
|
||||
#endif
|
||||
|
||||
/* We should have only one table in table list. */
|
||||
@ -569,6 +570,17 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
||||
goto end;
|
||||
}
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_EXECUTE_IF("sync.mdev_20225",
|
||||
{
|
||||
const char act[]=
|
||||
"now "
|
||||
"wait_for signal.mdev_20225_continue";
|
||||
DBUG_ASSERT(!debug_sync_set_action(thd,
|
||||
STRING_WITH_LEN(act)));
|
||||
};);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
result= (create ?
|
||||
table->triggers->create_trigger(thd, tables, &stmt_query):
|
||||
table->triggers->drop_trigger(thd, tables, &stmt_query));
|
||||
|
@ -1669,7 +1669,6 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
|
||||
case SQLCOM_CREATE_TRIGGER:
|
||||
|
||||
DBUG_ASSERT(!table_list);
|
||||
DBUG_ASSERT(first_table);
|
||||
|
||||
if (thd->find_temporary_table(first_table))
|
||||
@ -1678,6 +1677,14 @@ static bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table,
|
||||
}
|
||||
return true;
|
||||
|
||||
case SQLCOM_DROP_TRIGGER:
|
||||
DBUG_ASSERT(table_list);
|
||||
if (thd->find_temporary_table(table_list))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
if (table && !thd->find_temporary_table(db, table))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user