1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
|
#
# Test different deadlock scenarios in innodb and make sure that
# wsrep patch does not handle them as BF aborts.
#
--source include/galera_cluster.inc
--source include/have_debug.inc
--source include/have_debug_sync.inc
##############################################################################
# test case to verify that natural deadlock of trigger SP execution is
# handled correctly
##############################################################################
--echo
--echo Test phase 1 to make sure that natral deadlock in trigger SP execution is
--echo handled correctly
--echo
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
CREATE TABLE t1(a INT);
CREATE TABLE t2(f1 INT, f2 INT, f3 INT);
--disable_query_log
let $run=1000;
while($run)
{
INSERT INTO t2 VALUES (1, 2, 3);
dec $run;
}
--enable_query_log
DELIMITER |;
CREATE PROCEDURE proc()
BEGIN
INSERT INTO t2 VALUES(100, 200, 300);
UPDATE t2 SET f3 = f3 + 100;
END|
DELIMITER ;|
CREATE TRIGGER t1 BEFORE INSERT ON t1 FOR EACH ROW CALL proc();
--send INSERT INTO t1 VALUES(2);
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
--send INSERT INTO t1 VALUES(1);
--connection node_1
--error 0,ER_LOCK_DEADLOCK
--reap
--connection node_1a
--error 0,ER_LOCK_DEADLOCK
--reap
--connection node_1
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log
DROP TABLE t1;
DROP TABLE t2;
DROP PROCEDURE proc;
##############################################################################
#
# test case to verify that BF abort for SP execution is handled correctly
#
##############################################################################
--echo
--echo Test phase 2 to make sure that BF abort for SP execution is
--echo handled correctly
--echo
--connection node_1
SET SESSION wsrep_retry_autocommit = 0;
SET SESSION wsrep_sync_wait = 0;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
# Control connection for Galera sync point management
--connection node_1a
SET SESSION wsrep_retry_autocommit = 0;
SET SESSION wsrep_sync_wait = 0;
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
DELIMITER |;
CREATE PROCEDURE proc_update()
BEGIN
UPDATE t1 SET f2 = 'b';
END|
DELIMITER ;|
INSERT INTO t1 VALUES(1, 'a');
--connection node_1
SET debug_sync='wsrep_before_certification SIGNAL ready WAIT_FOR cont';
--send CALL proc_update
--connection node_1a
SET debug_sync='now WAIT_FOR ready';
--connection node_2
UPDATE t1 SET f2='c';
--connection node_1a
# wait for BF to happen
--let $wait_condition = SELECT VARIABLE_VALUE = $aborts_old + 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'
--source include/wait_condition.inc
SET debug_sync='now SIGNAL cont';
--connection node_1
--error ER_LOCK_DEADLOCK
--reap
--connection node_1a
SET debug_sync='RESET';
DROP PROCEDURE proc_update;
##############################################################################
#
# test case to verify that natural deadlock does not cause BF abort
#
##############################################################################
--connection node_1
--echo
--echo Test phase 3 to make sure natural deadlock is not treated as BF abort
--echo
TRUNCATE t1;
INSERT INTO t1 VALUES (1, 'a'), (2, 'a');
--connection node_1a
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
START TRANSACTION;
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
--connection node_1
START TRANSACTION;
UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
--connection node_1a
# this hangs for lock wait
--send UPDATE t1 SET f2 = 'b' WHERE f1 = 2
#
# classic deadlock happens here
#
--connection node_1
--error 0, ER_LOCK_DEADLOCK
UPDATE t1 SET f2 = 'c' WHERE f1 = 1;
--connection node_1a
--error 0, ER_LOCK_DEADLOCK
--reap
COMMIT;
#
# either one of SP executions was aborted because of natural deadlock, or in worst case
# they were ordered seqeuntailly, and both succeeded.
# anyways, we just check here that no BF aborts happened
#
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log
--connection node_1
ROLLBACK;
##############################################################################
#
# test case to verify that natural deadlock within SP exceution
# does not cause BF abort
#
##############################################################################
--echo
--echo Test phase 4 to make sure natural deadlock inside SP execution
--echo is not treated as BF abort
--echo
--connection node_1a
TRUNCATE t1;
INSERT INTO t1 VALUES (1, 'a'), (2, 'a');
--let $aborts_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
DELIMITER |;
CREATE PROCEDURE proc_update_1()
BEGIN
START TRANSACTION;
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
SELECT SLEEP(5);
UPDATE t1 SET f2 = 'b' WHERE f1 = 2;
COMMIT;
END|
DELIMITER ;|
DELIMITER |;
CREATE PROCEDURE proc_update_2()
BEGIN
START TRANSACTION;
UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
SELECT SLEEP(5);
UPDATE t1 SET f2 = 'c' WHERE f1 = 1;
COMMIT;
END|
DELIMITER ;|
--connection node_1
--send CALL proc_update_1
--connection node_1a
#
# calling proc_update_2 should cause a natural deadlock
# however, this test is not deterministic, and depends on the sleep() to
# cause expected ordering for update statement execution within SPs
# We therefore, allow both success and deadlock error for the result
#
--error 0, ER_LOCK_DEADLOCK
CALL proc_update_2;
#
# either one of SP executions was aborted because of natural deadlock, or in worst case
# they were ordered seqeuntailly, and both succeeded.
# anyways, we just check here that no BF aborts happened
#
--let $aborts_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_bf_aborts'`
--disable_query_log
--eval SELECT $aborts_new - $aborts_old AS wsrep__bf_aborts;
--enable_query_log
--connection node_1
--error 0, ER_LOCK_DEADLOCK
--reap
DROP PROCEDURE proc_update_1;
DROP PROCEDURE proc_update_2;
DROP TABLE t1;
|