Commit 58c03e8f authored by Daniele Sciascia's avatar Daniele Sciascia

MDEV-15794 Fix and re-enable test galera_var_retry_autocommit

The test was not deterministic and would occasionally fail, due to the
use of `sleep`.
This patch is a complete rewrite of the test using proper sync points.
parent dc0613ed
...@@ -27,7 +27,5 @@ galera_ist_mysqldump : MDEV-13549 Galera test failures ...@@ -27,7 +27,5 @@ galera_ist_mysqldump : MDEV-13549 Galera test failures
galera_ssl_upgrade : MDEV-13549 Galera test failures galera_ssl_upgrade : MDEV-13549 Galera test failures
galera.MW-329 : wsrep_local_replays not stable galera.MW-329 : wsrep_local_replays not stable
galera.MW-328A : have_deadlocks test not stable galera.MW-328A : have_deadlocks test not stable
galera_var_retry_autocommit : MDEV-15794 Test failure on galera.galera_var_retry_autocommit
galera_var_auto_inc_control_on : MDEV-15803 Test failure on galera.galera_var_auto_inc_control_on galera_var_auto_inc_control_on : MDEV-15803 Test failure on galera.galera_var_auto_inc_control_on
query_cache : MDEV-15805 Test failure on galera.query_cache query_cache : MDEV-15805 Test failure on galera.query_cache
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f2 = SLEEP(5);
SET SESSION wsrep_retry_autocommit = 0; SET SESSION wsrep_retry_autocommit = 0;
INSERT INTO t1 (f1) VALUES (1),(2);; SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue';
INSERT INTO t1 (f1) VALUES (2);
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 1; SET SESSION wsrep_retry_autocommit = 1;
INSERT INTO t1 (f1) VALUES (3),(4);; SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue';
TRUNCATE TABLE t1; INSERT INTO t1 (f1) VALUES (2);
SELECT * FROM test.t1; SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
f1 f2
3 0
4 0
CREATE PROCEDURE repeated_truncate ()
BEGIN
DECLARE i INT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
SET i = 0;
WHILE i <= 1000 DO
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SET i = i + 1; SELECT COUNT(*) = 1 FROM t1;
END WHILE; COUNT(*) = 1
END| 1
CALL repeated_truncate(); SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 1; SET SESSION wsrep_retry_autocommit = 1;
INSERT INTO t1 (f1) VALUES (5),(6); SET GLOBAL debug_dbug = '+d,sync.wsrep_retry_autocommit';
SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue EXECUTE 2';
INSERT INTO t1 VALUES (2);;
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
TRUNCATE TABLE t1;
SET DEBUG_SYNC = 'now WAIT_FOR wsrep_retry_autocommit_reached';
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
SET DEBUG_SYNC = 'now SIGNAL wsrep_retry_autocommit_continue WAIT_FOR before_rep';
TRUNCATE TABLE t1;
SELECT COUNT(*) = 0 FROM t1;
COUNT(*) = 0
1
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SET SESSION wsrep_retry_autocommit = 1024; SET DEBUG_SYNC = 'RESET';
INSERT INTO t1 (f1) VALUES (7),(8);; SET GLOBAL debug_dbug = NULL;
include/diff_servers.inc [servers=1 2] DROP TABLE t1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 64;
SET GLOBAL debug_dbug = '+d,sync.wsrep_retry_autocommit';
SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue EXECUTE 64';
INSERT INTO t1 VALUES (2);
SELECT COUNT(*) = 1 FROM t1;
COUNT(*) = 1
1
SET DEBUG_SYNC = 'RESET';
SET GLOBAL debug_dbug = NULL;
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE repeated_truncate;
# #
# Test that the wsrep_retry_autocommit variable is respected. We use an INSERT that # Test that the wsrep_retry_autocommit variable is respected.
# proceeds very slowly due to extra SLEEP() in a trigger
# #
--source include/galera_cluster.inc --source include/galera_cluster.inc
--source include/have_innodb.inc --source include/have_innodb.inc
--source include/have_debug_sync.inc
--connection node_1 --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB;
CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW SET NEW.f2 = SLEEP(5);
# #
# With wsrep_retry_autocommit = 0, error is certain # With wsrep_retry_autocommit = 0, error is certain
# #
--connection node_1 --connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 0; SET SESSION wsrep_retry_autocommit = 0;
--send INSERT INTO t1 (f1) VALUES (1),(2); SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue';
--send INSERT INTO t1 (f1) VALUES (2)
--connection node_1a
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
--connection node_2 --connection node_2
--sleep 1
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
--connection node_1 --connection node_1
--error ER_LOCK_DEADLOCK --error ER_LOCK_DEADLOCK
--reap --reap
SELECT COUNT(*) = 0 FROM t1;
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
# #
# With wsrep_retry_autocommit = 1, success against one TRUNCATE # With wsrep_retry_autocommit = 1, success against one TRUNCATE
# #
--connection node_1 --connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 1; SET SESSION wsrep_retry_autocommit = 1;
--send INSERT INTO t1 (f1) VALUES (3),(4); SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue';
--send INSERT INTO t1 (f1) VALUES (2)
--connection node_1a
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
--connection node_2 --connection node_2
--sleep 1
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
--connection node_1 --connection node_1
--error 0
--reap --reap
SELECT * FROM test.t1; SELECT COUNT(*) = 1 FROM t1;
SET DEBUG_SYNC = 'RESET';
DROP TABLE t1;
# #
# With wsrep_retry_autocommit = 1, failure against multiple TRUNCATEs # With wsrep_retry_autcommit = 1, failure against multiple TRUNCATEs
# #
--connection node_1
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
SET SESSION wsrep_retry_autocommit = 1;
SET GLOBAL debug_dbug = '+d,sync.wsrep_retry_autocommit';
SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue EXECUTE 2';
--send INSERT INTO t1 VALUES (2);
--connection node_1a
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
--connection node_2 --connection node_2
DELIMITER |; TRUNCATE TABLE t1;
CREATE PROCEDURE repeated_truncate ()
BEGIN --connection node_1a
DECLARE i INT; SET DEBUG_SYNC = 'now WAIT_FOR wsrep_retry_autocommit_reached';
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; SELECT COUNT(*) = 0 FROM t1;
SET DEBUG_SYNC = 'now SIGNAL wsrep_retry_autocommit_continue WAIT_FOR before_rep';
SET i = 0;
WHILE i <= 1000 DO --connection node_2
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SET i = i + 1;
END WHILE; --connection node_1a
END| SELECT COUNT(*) = 0 FROM t1;
DELIMITER ;|
# Begin streaming TRUNCATEs
--let $truncate_connection_id = `SELECT CONNECTION_ID()`
--send CALL repeated_truncate()
--connection node_1 --connection node_1
SET SESSION wsrep_retry_autocommit = 1;
--sleep 1
--error ER_LOCK_DEADLOCK --error ER_LOCK_DEADLOCK
INSERT INTO t1 (f1) VALUES (5),(6); --reap
SET DEBUG_SYNC = 'RESET';
SET GLOBAL debug_dbug = NULL;
DROP TABLE t1;
# #
# With wsrep_retry_autocommit = 1024, success against multiple TRUNCATEs # With wsrep_retry_autocommit = 64, success against 64 TRUNCATEs
# #
--connection node_1 --connection node_1
SET SESSION wsrep_retry_autocommit = 1024; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB;
--send INSERT INTO t1 (f1) VALUES (7),(8);
--sleep 6 SET SESSION wsrep_retry_autocommit = 64;
SET GLOBAL debug_dbug = '+d,sync.wsrep_retry_autocommit';
SET DEBUG_SYNC = 'wsrep_before_replication SIGNAL before_rep WAIT_FOR continue EXECUTE 64';
# Once he stream of TRUNCATEs is complete --send INSERT INTO t1 VALUES (2)
--connection node_2
--reap --disable_query_log
--disable_result_log
--let $count = 64
while ($count)
{
--connection node_1a
SET DEBUG_SYNC = 'now WAIT_FOR before_rep';
--connection node_2
TRUNCATE TABLE t1;
--connection node_1a
SET DEBUG_SYNC = 'now WAIT_FOR wsrep_retry_autocommit_reached';
SELECT COUNT(*) = 1 FROM t1;
SET DEBUG_SYNC = 'now SIGNAL wsrep_retry_autocommit_continue';
--dec $count
}
--enable_result_log
--enable_query_log
# the INSERT will eventually be sucessfull
--connection node_1 --connection node_1
--error 0
--reap --reap
SELECT COUNT(*) = 1 FROM t1;
--let $diff_servers = 1 2 SET DEBUG_SYNC = 'RESET';
--source include/diff_servers.inc SET GLOBAL debug_dbug = NULL;
DROP TABLE t1; DROP TABLE t1;
DROP PROCEDURE repeated_truncate;
...@@ -7187,6 +7187,15 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, ...@@ -7187,6 +7187,15 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
com_statement_info[thd->get_command()].m_key); com_statement_info[thd->get_command()].m_key);
MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(),
thd->query_length()); thd->query_length());
DBUG_EXECUTE_IF("sync.wsrep_retry_autocommit",
{
const char act[]=
"now "
"SIGNAL wsrep_retry_autocommit_reached "
"WAIT_FOR wsrep_retry_autocommit_continue";
DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act)));
});
} }
mysql_parse(thd, rawbuf, length, parser_state); mysql_parse(thd, rawbuf, length, parser_state);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment