innodb_bug38231.test 2.64 KB
Newer Older
vasil's avatar
vasil committed
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
#
# Bug#38231 Innodb crash in lock_reset_all_on_table() on TRUNCATE + LOCK / UNLOCK
# http://bugs.mysql.com/38231
#

-- source include/have_innodb.inc

SET storage_engine=InnoDB;

# we care only that the following SQL commands do not crash the server
-- disable_query_log
-- disable_result_log

DROP TABLE IF EXISTS bug38231;
CREATE TABLE bug38231 (a INT);

-- connect (con1,localhost,root,,)
-- connect (con2,localhost,root,,)
-- connect (con3,localhost,root,,)

-- connection con1
SET autocommit=0;
LOCK TABLE bug38231 WRITE;

-- connection con2
SET autocommit=0;
-- send
LOCK TABLE bug38231 WRITE;

vdimov's avatar
vdimov committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
# When con1 does UNLOCK below this will release either con2 or con3 which are
# both waiting on LOCK. At the end we must first --reap and UNLOCK the
# connection that has been released, otherwise it will wait forever. We assume
# that the released connection will be the first one that has gained the LOCK,
# thus we force the order here - con2 does LOCK first, then con3. In other
# words we wait for LOCK from con2 above to be exected before doing LOCK in
# con3.
-- connection con1
let $wait_condition =
  SELECT COUNT(*) = 1 FROM information_schema.processlist
  WHERE info = 'LOCK TABLE bug38231 WRITE';
-- source include/wait_condition.inc
# the above enables query log, re-disable it
-- disable_query_log

vasil's avatar
vasil committed
45 46 47 48 49 50 51 52 53 54
-- connection con3
SET autocommit=0;
-- send
LOCK TABLE bug38231 WRITE;

-- connection default
-- send
TRUNCATE TABLE bug38231;

-- connection con1
vasil's avatar
vasil committed
55 56 57 58 59 60 61 62 63 64 65 66 67 68
# Wait for TRUNCATE and the other two LOCKs to be executed; without this,
# sometimes UNLOCK executes before them. We assume there are no other
# sessions executing at the same time with the same SQL commands.
let $wait_condition =
  SELECT COUNT(*) = 1 FROM information_schema.processlist
  WHERE info = 'TRUNCATE TABLE bug38231';
-- source include/wait_condition.inc
let $wait_condition =
  SELECT COUNT(*) = 2 FROM information_schema.processlist
  WHERE info = 'LOCK TABLE bug38231 WRITE';
-- source include/wait_condition.inc
# the above enables query log, re-disable it
-- disable_query_log

vasil's avatar
vasil committed
69 70 71 72 73 74
# this crashes the server if the bug is present
UNLOCK TABLES;

# clean up

-- connection con2
vasil's avatar
vasil committed
75
-- reap
vasil's avatar
vasil committed
76 77 78
UNLOCK TABLES;

-- connection con3
vasil's avatar
vasil committed
79
-- reap
vasil's avatar
vasil committed
80 81 82
UNLOCK TABLES;

-- connection default
vasil's avatar
vasil committed
83
-- reap
vasil's avatar
vasil committed
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

-- disconnect con1
-- disconnect con2
-- disconnect con3

# test that TRUNCATE works with with row-level locks

-- enable_query_log
-- enable_result_log

INSERT INTO bug38231 VALUES (1), (10), (300);

-- connect (con4,localhost,root,,)

-- connection con4
SET autocommit=0;
SELECT * FROM bug38231 FOR UPDATE;

-- connection default
TRUNCATE TABLE bug38231;

-- connection con4
COMMIT;

-- connection default

-- disconnect con4

DROP TABLE bug38231;