summaryrefslogtreecommitdiff
path: root/mysql-test/t/lock_sync.test
diff options
context:
space:
mode:
Diffstat (limited to 'mysql-test/t/lock_sync.test')
-rw-r--r--mysql-test/t/lock_sync.test118
1 files changed, 118 insertions, 0 deletions
diff --git a/mysql-test/t/lock_sync.test b/mysql-test/t/lock_sync.test
new file mode 100644
index 00000000000..73289685114
--- /dev/null
+++ b/mysql-test/t/lock_sync.test
@@ -0,0 +1,118 @@
+#
+# Locking related tests which use DEBUG_SYNC facility.
+#
+--source include/have_debug_sync.inc
+# We need InnoDB to be able use TL_WRITE_ALLOW_WRITE type of locks in our tests.
+--source include/have_innodb.inc
+# Until bug#41971 'Thread state on embedded server is always "Writing to net"'
+# is fixed this test can't be run on embedded version of server.
+--source include/not_embedded.inc
+
+# Save the initial number of concurrent sessions.
+--source include/count_sessions.inc
+
+
+--echo #
+--echo # Test for bug #45143 "All connections hang on concurrent ALTER TABLE".
+--echo #
+--echo # Concurrent execution of statements which required weak write lock
+--echo # (TL_WRITE_ALLOW_WRITE) on several instances of the same table and
+--echo # statements which tried to acquire stronger write lock (TL_WRITE,
+--echo # TL_WRITE_ALLOW_READ) on this table might have led to deadlock.
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+--echo # Create auxiliary connections used through the test.
+connect (con_bug45143_1,localhost,root,,test,,);
+connect (con_bug45143_3,localhost,root,,test,,);
+connect (con_bug45143_2,localhost,root,,test,,);
+connection default;
+--echo # Reset DEBUG_SYNC facility before using it.
+set debug_sync= 'RESET';
+--echo # Turn off logging so calls to locking subsystem performed
+--echo # for general_log table won't interfere with our test.
+set @old_general_log = @@global.general_log;
+set @@global.general_log= OFF;
+
+create table t1 (i int) engine=InnoDB;
+insert into t1 values (1);
+--echo # Prepare user lock which will be used for resuming execution of
+--echo # the first statement after it acquires TL_WRITE_ALLOW_WRITE lock.
+select get_lock("lock_bug45143_wait", 0);
+
+--echo # Switch to connection 'con_bug45143_1'.
+connection con_bug45143_1;
+--echo # Sending:
+--send insert into t1 values (get_lock("lock_bug45143_wait", 100));
+
+--echo # Switch to connection 'con_bug45143_2'.
+connection con_bug45143_2;
+--echo # Wait until the above INSERT takes TL_WRITE_ALLOW_WRITE lock on 't1'
+--echo # and then gets blocked on user lock 'lock_bug45143_wait'.
+let $wait_condition= select count(*)= 1 from information_schema.processlist
+ where state= 'User lock' and
+ info='insert into t1 values (get_lock("lock_bug45143_wait", 100))';
+--source include/wait_condition.inc
+--echo # Ensure that upcoming SELECT waits after acquiring TL_WRITE_ALLOW_WRITE
+--echo # lock for the first instance of 't1'.
+set debug_sync='thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
+--echo # Sending:
+--send select count(*) > 0 from t1 as a, t1 as b for update;
+
+--echo # Switch to connection 'con_bug45143_3'.
+connection con_bug45143_3;
+--echo # Wait until the above SELECT ... FOR UPDATE is blocked after
+--echo # acquiring lock for the the first instance of 't1'.
+set debug_sync= 'now WAIT_FOR parked';
+--echo # Send LOCK TABLE statement which will try to get TL_WRITE lock on 't1':
+--send lock table t1 write;
+
+--echo # Switch to connection 'default'.
+connection default;
+--echo # Wait until this LOCK TABLES statement starts waiting for table lock.
+let $wait_condition= select count(*)= 1 from information_schema.processlist
+ where state= 'Locked' and
+ info='lock table t1 write';
+--source include/wait_condition.inc
+--echo # Allow SELECT ... FOR UPDATE to resume.
+--echo # Since it already has TL_WRITE_ALLOW_WRITE lock on the first instance
+--echo # of 't1' it should be able to get lock on the second instance without
+--echo # waiting, even although there is another thread which has such lock
+--echo # on this table and also there is a thread waiting for a TL_WRITE on it.
+set debug_sync= 'now SIGNAL go';
+
+--echo # Switch to connection 'con_bug45143_2'.
+connection con_bug45143_2;
+--echo # Reap SELECT ... FOR UPDATE
+--reap
+
+--echo # Switch to connection 'default'.
+connection default;
+--echo # Resume execution of the INSERT statement.
+select release_lock("lock_bug45143_wait");
+
+--echo # Switch to connection 'con_bug45143_1'.
+connection con_bug45143_1;
+--echo # Reap INSERT statement.
+--reap
+
+--echo # Switch to connection 'con_bug45143_3'.
+connection con_bug45143_3;
+--echo # Reap LOCK TABLES statement.
+--reap
+unlock tables;
+
+--echo # Switch to connection 'default'.
+connection default;
+--echo # Do clean-up.
+disconnect con_bug45143_1;
+disconnect con_bug45143_2;
+disconnect con_bug45143_3;
+set debug_sync= 'RESET';
+set @@global.general_log= @old_general_log;
+drop table t1;
+
+
+# Check that all connections opened by test cases in this file are really
+# gone so execution of other tests won't be affected by their presence.
+--source include/wait_until_count_sessions.inc