List:Commits« Previous MessageNext Message »
From:Jorgen Austvik Date:December 16 2008 11:33am
Subject:bzr commit into mysql-6.0-runtime branch (jorgen.austvik:2780) WL#4343
View as plain text  
#At file:///home/ja155679/devel/mysql/mysql-6.0-runtime/

 2780 Jorgen Austvik	2008-12-16
      WL#4343, Part 1. Add a functional test and, Part 3 start on stress test. Part 4 will
be added to the stress test later
added:
  mysql-test/suite/ddl_lock/
  mysql-test/suite/ddl_lock/README
  mysql-test/suite/ddl_lock/include/
  mysql-test/suite/ddl_lock/include/stress_settings.inc
  mysql-test/suite/ddl_lock/include/sync_lock.inc
  mysql-test/suite/ddl_lock/r/
  mysql-test/suite/ddl_lock/r/concurrent_ddl.result
  mysql-test/suite/ddl_lock/r/create_stress_tables.result
  mysql-test/suite/ddl_lock/r/stress_ddl.result
  mysql-test/suite/ddl_lock/r/stress_dml.result
  mysql-test/suite/ddl_lock/stress_init.txt
  mysql-test/suite/ddl_lock/stress_tests.txt
  mysql-test/suite/ddl_lock/t/
  mysql-test/suite/ddl_lock/t/concurrent_ddl.test
  mysql-test/suite/ddl_lock/t/create_stress_tables.test
  mysql-test/suite/ddl_lock/t/stress_ddl.test
  mysql-test/suite/ddl_lock/t/stress_dml.test
modified:
  sql/debug_sync.cc
  sql/lock.cc
  sql/mdl.cc
  sql/sql_base.cc
  sql/sql_table.cc

=== added directory 'mysql-test/suite/ddl_lock'
=== added file 'mysql-test/suite/ddl_lock/README'
--- a/mysql-test/suite/ddl_lock/README	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/README	2008-12-16 10:32:25 +0000
@@ -0,0 +1,22 @@
+*DDL LOCKING TEST SUITE*
+
+This is the test suite for WL#4343
+
+Tests:
+- concurrent_ddl.test - WL#4343 Part 1. (Functional testing of
+  concurrent DDL operations)
+
+*STRESS TESTING*
+
+Typical example of running the stress test for one hour:
+
+./mysql-test-run --stress  \
+                 --stress-suite=ddl_lock \
+                 --stress-threads=55 \
+                 --stress-test-duration=3600
+
+This stress test used the tests specified in stress_init.txt and
+stress_tests.txt.
+
+
+Jorgen.Austvik@stripped

=== added directory 'mysql-test/suite/ddl_lock/include'
=== added file 'mysql-test/suite/ddl_lock/include/stress_settings.inc'
--- a/mysql-test/suite/ddl_lock/include/stress_settings.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/include/stress_settings.inc	2008-12-16 10:32:25 +0000
@@ -0,0 +1,4 @@
+##
+## Standard settings (global variables) for the stress testing.
+##
+let $num_stress_rows= 5000;

=== added file 'mysql-test/suite/ddl_lock/include/sync_lock.inc'
--- a/mysql-test/suite/ddl_lock/include/sync_lock.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/include/sync_lock.inc	2008-12-16 10:32:25 +0000
@@ -0,0 +1,75 @@
+#
+# SUMMARY
+#
+#   Locks a table in one thread, run an SQL statement in another thread,
+#   and check that the SQL statement is locked.
+#
+# USAGE
+#
+#   let $lock_table= t1;          # The table to be locked
+#   let $sql= DROP TABLE t1 ;     # The SQL statement that should lock
+#
+# OPTIONAL
+#   let $sync= after_start_ddl;      # What to sync with to unlock the tables.
+#                                    # Default: wait_for_lock
+#   let $setup= HANDLER t1 OPEN;     # Statement to run before the locked
+#                                    # statement
+#   let $teardown= HANDLER t1 CLOSE; # Statement to run after the lock has
+#                                    # been unlocked
+#
+# EXAMPLE
+#   concurrent_ddl.test in ddl_lock suite.
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+--enable_warnings
+
+# Default value
+if (`SELECT LENGTH("$sync") = 0`) {
+  let $sync= mdl_enter_cond;
+}
+
+--echo # Connection waiter will run setup (if any)
+connection waiter;
+if (`SELECT LENGTH("$setup")`) {
+  eval $setup;
+}
+
+--echo # Using sync_lock.inc to synchronize on '$sync'
+
+--echo # Connection locker will lock the resource
+connection locker;
+
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+send;
+eval LOCK TABLES $lock_table READ;
+
+--echo # Connection waiter will wait for the resource to be locked, and then
+--echo # run the SQL that should lock.
+connection waiter;
+
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+# run mysql-test-run --debug for information about the signal
+--replace_result $sync <sync>
+eval SET DEBUG_SYNC= '$sync SIGNAL do_unlock';
+send;
+eval $sql;
+
+--echo # Connection locker will unlock the locked resources
+connection locker;
+UNLOCK TABLES;
+
+--echo # Connection waiter will wait for the SQL to return after the
+--echo # lock is unlocked, and run teardown if we have any
+connection waiter;
+reap;
+if (`SELECT LENGTH("$teardown")`) {
+  eval $teardown;
+}
+
+--echo # Cleaning up in default connection
+connection default;
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+--enable_warnings

=== added directory 'mysql-test/suite/ddl_lock/r'
=== added file 'mysql-test/suite/ddl_lock/r/concurrent_ddl.result'
--- a/mysql-test/suite/ddl_lock/r/concurrent_ddl.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/r/concurrent_ddl.result	2008-12-16 10:32:25 +0000
@@ -0,0 +1,397 @@
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a INT) ENGINE=<engine_type>;
+INSERT INTO t1 VALUES (1);
+# Connection locker: the connection that locks the resource
+# Connection waiter: the connection that waits for the resource
+# Both these connections are used the same way in all the test cases
+# In this test.
+##
+## 1.1 One connection holding a lock on a table, other performing
+##     alter, handler, truncate and drop on same object
+##
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (b INT);
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+RENAME TABLE t1 TO t2;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+RENAME TABLE t2 TO t1;
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+HANDLER t1 OPEN;
+# Using sync_lock.inc to synchronize on 'locked_external'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+HANDLER t1 READ FIRST;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+a	b
+1	NULL
+HANDLER t1 CLOSE;
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+TRUNCATE TABLE t1;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+DROP TABLE t1;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+##
+## 1.2 Two connections trying to perform alter on same table/view
+##
+CREATE TABLE t1(a INT, b CHAR(100) DEFAULT "test 1.2")
+ENGINE=<engine_type>;
+INSERT INTO t1 (a) VALUES (1), (2), (3), (4), (5);
+SET DEBUG_SYNC= 'alter_table_before_main_binlog
+                SIGNAL locked WAIT_FOR do_unlock';
+ALTER TABLE t1 ADD COLUMN (c CHAR(100) DEFAULT "test 1.2 locker");
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (d CHAR(100) DEFAULT "test 1.2 waiter");
+SET DEBUG_SYNC= 'RESET';
+SELECT SUM(a) FROM t1;
+SUM(a)
+15
+SELECT COUNT(*) FROM t1 WHERE NOT c LIKE "test 1.2 %";
+COUNT(*)
+0
+DROP TABLE t1;
+##
+## 1.3 One connection creating a table, another is trying to alter it
+##
+CREATE TABLE t1(a INT, b INT) ENGINE=<engine_type>;
+INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 4), (4, 5), (5, 6);
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+CREATE TABLE t2 ENGINE=<engine_type> AS SELECT *, SLEEP(1) FROM t1;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (c INT);
+SET DEBUG_SYNC= 'RESET';
+SELECT SUM(a), SUM(b) FROM t1;
+SUM(a)	SUM(b)
+15	20
+SELECT SUM(a), SUM(b) FROM t2;
+SUM(a)	SUM(b)
+15	20
+DROP TABLE t1;
+DROP TABLE t2;
+##
+## 1.4 One connection is selecting (using handler) while another is
+##     altering the table (select start first)
+##
+CREATE TABLE t1(a INT, b INT) ENGINE=<engine_type>;
+INSERT INTO t1 VALUES (1, 2), (3, 4);
+HANDLER t1 OPEN;
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+HANDLER t1 READ FIRST;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (c INT);
+a	b	c
+1	2	NULL
+HANDLER t1 CLOSE;
+SELECT * FROM t1 ORDER BY a;
+a	b	c
+1	2	NULL
+3	4	NULL
+HANDLER t1 OPEN;
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+HANDLER t1 READ FIRST;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+ALTER TABLE t1 DROP COLUMN b;
+a	c
+1	NULL
+HANDLER t1 CLOSE;
+SELECT * FROM t1 ORDER BY a;
+a	c
+1	NULL
+3	NULL
+SELECT * FROM t1 ORDER BY a;
+a	c
+1	NULL
+3	NULL
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+##
+## 1.5 One connection selecting (using handler), while another is
+##     altering the table - altering table starts first
+##
+CREATE TABLE t1(a INT, b CHAR(100)) ENGINE=<engine_type>;
+INSERT INTO t1 (a) VALUES (10);
+INSERT INTO t1 (a) VALUES (9);
+INSERT INTO t1 (a) VALUES (8);
+INSERT INTO t1 (a) VALUES (7);
+INSERT INTO t1 (a) VALUES (6);
+INSERT INTO t1 (a) VALUES (5);
+INSERT INTO t1 (a) VALUES (4);
+INSERT INTO t1 (a) VALUES (3);
+INSERT INTO t1 (a) VALUES (2);
+INSERT INTO t1 (a) VALUES (1);
+SET DEBUG_SYNC= 'alter_table_before_main_binlog
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER TABLE t1 ADD COLUMN (c CHAR(100) DEFAULT "test 1.5");
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+HANDLER t1 OPEN;
+HANDLER t1 READ FIRST;
+a	b	c
+10	NULL	test 1.5
+HANDLER t1 CLOSE;
+SELECT SUM(a) FROM t1;
+SUM(a)
+55
+SELECT COUNT(*) FROM t1 WHERE NOT c LIKE "test 1.5";
+COUNT(*)
+0
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+##
+## 1.6 Tow connections are long create/select, while another is
+##     altering the table
+##
+# Connections locker1..locker3 will run different SQL queries, which
+# will all lock on the same resource.
+CREATE TABLE t1(a INT, b INT) ENGINE=<engine_type>;
+INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 4), (4, 5), (5, 6);
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+CREATE TABLE t2 ENGINE=<engine_type> AS SELECT *, SLEEP(1) FROM t1;
+CREATE TABLE t3 LIKE t1;
+CREATE TABLE t4 ENGINE=<engine_type> AS SELECT *, SLEEP(1) FROM t1;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (c INT);
+SELECT SUM(a), SUM(b) FROM t2;
+SUM(a)	SUM(b)
+15	20
+SELECT SUM(a), SUM(b) FROM t3;
+SUM(a)	SUM(b)
+NULL	NULL
+SELECT SUM(a), SUM(b) FROM t4;
+SUM(a)	SUM(b)
+15	20
+# Closing connections locker1..locker3 since they are not used any more
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+##
+## 1.7 Both connections trying to rename the same table/view
+##     (including alter ... rename command)
+##
+CREATE TABLE t1(a INT, b CHAR(100)) ENGINE=<engine_type>;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER TABLE t1 RENAME t2;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'after_start_ddl SIGNAL do_unlock';
+ALTER TABLE t2 RENAME t3;
+SELECT SUM(a) FROM t3;
+SUM(a)
+NULL
+SELECT COUNT(*) FROM t3;
+COUNT(*)
+0
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t3;
+##
+## 1.8a Use list of tables in DROP TABLE and RENAME TABLE statements
+##
+CREATE TABLE t1(a INT) ENGINE=<engine_type>;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t_t1(a INT) ENGINE=<engine_type>;
+INSERT INTO t_t1 VALUES (1);
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+RENAME TABLE t1 TO t2, t_t1 TO t3;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+RENAME TABLE t2 TO t1, t3 TO t_t1;
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'RESET';
+# Connection waiter will run setup (if any)
+# Using sync_lock.inc to synchronize on 'mdl_enter_cond'
+# Connection locker will lock the resource
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL locked WAIT_FOR do_unlock';
+LOCK TABLES t1 READ;
+# Connection waiter will wait for the resource to be locked, and then
+# run the SQL that should lock.
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync> SIGNAL do_unlock';
+DROP TABLE t1, t_t1;
+# Connection locker will unlock the locked resources
+UNLOCK TABLES;
+# Connection waiter will wait for the SQL to return after the
+# lock is unlocked, and run teardown if we have any
+# Cleaning up in default connection
+SET DEBUG_SYNC= 'RESET';
+##
+## 1.9 Two connections trying to alter the same stored procedure
+##     and function
+##
+CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+ENGINE=<engine_type>;
+CREATE PROCEDURE t_proc ()
+BEGIN
+SELECT * FROM t1;
+END|
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn lock 1.9';
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn waiter 1.9';
+SET DEBUG_SYNC= 'RESET';
+DROP PROCEDURE t_proc;
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER FUNCTION t_func COMMENT 'Now with a comment from conn locker 1.9';
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+ALTER FUNCTION t_func COMMENT 'Now with a comment from conn waiter 1.9';
+SET DEBUG_SYNC= 'RESET';
+DROP FUNCTION t_func;
+DROP TABLE t1;
+##
+## 1.10 One Connection altering a stored procedure/function, while
+##      the other is dropping it.
+##
+CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+ENGINE=<engine_type>;
+CREATE PROCEDURE t_proc ()
+BEGIN
+SELECT * FROM t1;
+END|
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn lock 1.10';
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+DROP PROCEDURE t_proc;
+ERROR 42000: PROCEDURE test.t_proc does not exist
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER FUNCTION t_func COMMENT 'Now with a comment from conn lock 1.10';
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+DROP FUNCTION t_func;
+ERROR 42000: FUNCTION test.t_func does not exist
+SET DEBUG_SYNC= 'RESET';
+DROP table t1;
+##
+## 1.11, 1.12 and 1.13 - ALTER TABLE and TRUNCATE TABLE simoultaniously
+##
+CREATE TABLE t1(a INT, b CHAR(20) DEFAULT "test 1.11")
+ENGINE=<engine_type>;
+INSERT INTO t1 (a) VALUES (1);
+SET DEBUG_SYNC= '<sync> SIGNAL locked WAIT_FOR do_unlock';
+TRUNCATE TABLE t1;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync2> SIGNAL do_unlock';
+ALTER TABLE t1 ADD COLUMN (c INT);
+SET DEBUG_SYNC= 'RESET';
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+ALTER TABLE t1 ADD COLUMN (d INT);
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= '<sync3> SIGNAL do_unlock';
+TRUNCATE TABLE t1;
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+##
+## 1.14 Two connections are trying to alter the same event.
+##
+CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+SELECT MOD(29,9);
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+ALTER EVENT ev1 ON SCHEDULE EVERY 12 HOUR
+STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL do_unlock';
+ALTER EVENT ev1 ON SCHEDULE EVERY 4 HOUR
+STARTS CURRENT_TIMESTAMP + INTERVAL 4 HOUR;
+SET DEBUG_SYNC= 'RESET';
+DROP EVENT ev1;
+# Clean up connections

=== added file 'mysql-test/suite/ddl_lock/r/create_stress_tables.result'
--- a/mysql-test/suite/ddl_lock/r/create_stress_tables.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/r/create_stress_tables.result	2008-12-16 10:32:25 +0000
@@ -0,0 +1,40 @@
+SET GLOBAL query_cache_type = OFF;
+CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+ENGINE=<engine_type>;
+INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8);
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+SELECT MAX(id) FROM t1 INTO @max;
+INSERT INTO t1(id) SELECT id + @max FROM t1
+WHERE id + @max <= <num_stress_rows>;
+CREATE PROCEDURE t_proc (OUT b_p CHAR(100))
+BEGIN
+SELECT b INTO @b_p FROM t1 WHERE Id = 1;
+END|
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');

=== added file 'mysql-test/suite/ddl_lock/r/stress_ddl.result'
--- a/mysql-test/suite/ddl_lock/r/stress_ddl.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/r/stress_ddl.result	2008-12-16 10:32:25 +0000
@@ -0,0 +1,15 @@
+ALTER TABLE t1 ADD COLUMN <column_name> CHAR(200) DEFAULT "New column";
+CREATE INDEX <index_name> ON t1 (<column_name>);
+SELECT DISTINCT(<column_name>) FROM t1;
+<column_name>
+New column
+DROP INDEX <index_name> ON t1;
+ALTER TABLE t1 DROP COLUMN <column_name>;
+CREATE VIEW <view_name> AS SELECT DISTINCT b FROM t1;
+CREATE VIEW <all_view_name> AS SELECT id, b FROM t1;
+SELECT id FROM <all_view_name> WHERE id = <random_id>;
+id
+<random_id>
+DROP VIEW <view_name>, <all_view_name>;
+ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn <conn_id>';
+ALTER FUNCTION t_func COMMENT 'Now with a comment from conn <conn_id>';

=== added file 'mysql-test/suite/ddl_lock/r/stress_dml.result'
--- a/mysql-test/suite/ddl_lock/r/stress_dml.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/r/stress_dml.result	2008-12-16 10:32:25 +0000
@@ -0,0 +1,17 @@
+START TRANSACTION;
+UPDATE t1 SET b = "changed" WHERE id=<random>;
+SELECT id,b FROM t1 WHERE id=<random>;
+id	b
+<random>	changed
+COMMIT;
+START TRANSACTION;
+DELETE FROM t1 WHERE id=<random>;
+INSERT INTO t1 (id, b) VALUES (<random>, "newly_inserted");
+COMMIT;
+CALL t_proc(@b);
+SELECT @b;
+@b
+NULL
+SELECT t_func('world');
+t_func('world')
+Hello, world!

=== added file 'mysql-test/suite/ddl_lock/stress_init.txt'
--- a/mysql-test/suite/ddl_lock/stress_init.txt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/stress_init.txt	2008-12-16 10:32:25 +0000
@@ -0,0 +1 @@
+create_stress_tables

=== added file 'mysql-test/suite/ddl_lock/stress_tests.txt'
--- a/mysql-test/suite/ddl_lock/stress_tests.txt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/stress_tests.txt	2008-12-16 10:32:25 +0000
@@ -0,0 +1,13 @@
+#
+# 10% DDL transactions
+#
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_dml
+stress_ddl

=== added directory 'mysql-test/suite/ddl_lock/t'
=== added file 'mysql-test/suite/ddl_lock/t/concurrent_ddl.test'
--- a/mysql-test/suite/ddl_lock/t/concurrent_ddl.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/t/concurrent_ddl.test	2008-12-16 10:32:25 +0000
@@ -0,0 +1,586 @@
+##
+## Test for WL #4343 - DDL locking for all metadata objects
+##
+##
+## Test case 1: Concurrent users performing DDL operations
+##
+
+#
+# We need the Debug Sync Facility.
+#
+--source include/have_debug_sync.inc
+--source include/have_innodb.inc
+
+if (`SELECT LENGTH("$engine_type") = 0`) {
+  let $engine_type= MyISAM;
+# InnoDB;
+# MyISAM;
+}
+let $lock_table= t1;
+
+--disable_warnings
+SET DEBUG_SYNC= 'RESET';
+eval DROP TABLE IF EXISTS $lock_table;
+--enable_warnings
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE $lock_table(a INT) ENGINE=$engine_type;
+eval INSERT INTO $lock_table VALUES (1);
+
+# Connections we will use - create only once, in case we forget to unlock.
+--echo # Connection locker: the connection that locks the resource
+connect (locker,localhost,root,,);
+--echo # Connection waiter: the connection that waits for the resource
+connect (waiter,localhost,root,,);
+--echo # Both these connections are used the same way in all the test cases
+--echo # In this test.
+
+--echo ##
+--echo ## 1.1 One connection holding a lock on a table, other performing
+--echo ##     alter, handler, truncate and drop on same object
+--echo ##
+
+let $sql= ALTER TABLE $lock_table ADD COLUMN (b INT);
+--source suite/ddl_lock/include/sync_lock.inc
+
+let $sql= RENAME TABLE $lock_table TO t2;
+let $teardown= RENAME TABLE t2 TO $lock_table;
+--source suite/ddl_lock/include/sync_lock.inc
+let $teardown= ;
+
+let $sync= locked_external;
+let $setup= HANDLER $lock_table OPEN;
+let $teardown= HANDLER t1 CLOSE;
+let $sql= HANDLER $lock_table READ FIRST;
+--source suite/ddl_lock/include/sync_lock.inc
+let $setup= ;
+let $teardown= ;
+let $sync= ;
+
+# InnoDB needs other syncronization signal
+if (`SELECT STRCMP("$engine_type", "InnoDB") = 0`) {
+    let $sync= wait_for_lock;
+}
+let $sql= TRUNCATE TABLE $lock_table;
+--source suite/ddl_lock/include/sync_lock.inc
+let $sync= ;
+
+let $sql= DROP TABLE $lock_table;
+--source suite/ddl_lock/include/sync_lock.inc
+--echo ##
+--echo ## 1.2 Two connections trying to perform alter on same table/view
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b CHAR(100) DEFAULT "test 1.2")
+     ENGINE=$engine_type;
+
+# Some rows to make the alter table do something
+INSERT INTO t1 (a) VALUES (1), (2), (3), (4), (5);
+
+connection locker;
+SET DEBUG_SYNC= 'alter_table_before_main_binlog
+                SIGNAL locked WAIT_FOR do_unlock';
+send ALTER TABLE t1 ADD COLUMN (c CHAR(100) DEFAULT "test 1.2 locker");
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send ALTER TABLE t1 ADD COLUMN (d CHAR(100) DEFAULT "test 1.2 waiter");
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+SET DEBUG_SYNC= 'RESET';
+SELECT SUM(a) FROM t1;
+SELECT COUNT(*) FROM t1 WHERE NOT c LIKE "test 1.2 %";
+
+DROP TABLE t1;
+
+--echo ##
+--echo ## 1.3 One connection creating a table, another is trying to alter it
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b INT) ENGINE=$engine_type;
+
+# 5 rows, 1 sec sleep for each (see below)
+INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 4), (4, 5), (5, 6);
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+--replace_result $engine_type <engine_type>
+send;
+eval CREATE TABLE t2 ENGINE=$engine_type AS SELECT *, SLEEP(1) FROM t1;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send ALTER TABLE t1 ADD COLUMN (c INT);
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+SELECT SUM(a), SUM(b) FROM t1;
+SELECT SUM(a), SUM(b) FROM t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo ##
+--echo ## 1.4 One connection is selecting (using handler) while another is
+--echo ##     altering the table (select start first)
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b INT) ENGINE=$engine_type;
+INSERT INTO t1 VALUES (1, 2), (3, 4);
+
+connection locker;
+HANDLER t1 OPEN;
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+send HANDLER t1 READ FIRST;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send ALTER TABLE t1 ADD COLUMN (c INT);
+
+connection locker;
+reap;
+HANDLER t1 CLOSE;
+SELECT * FROM t1 ORDER BY a;
+
+connection waiter;
+reap;
+
+connection locker;
+HANDLER t1 OPEN;
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+send HANDLER t1 READ FIRST;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send ALTER TABLE t1 DROP COLUMN b;
+
+connection locker;
+reap;
+HANDLER t1 CLOSE;
+SELECT * FROM t1 ORDER BY a;
+
+connection waiter;
+reap;
+SELECT * FROM t1 ORDER BY a;
+
+# Clean up
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+
+--echo ##
+--echo ## 1.5 One connection selecting (using handler), while another is
+--echo ##     altering the table - altering table starts first
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b CHAR(100)) ENGINE=$engine_type;
+
+# Need some rows to make the alter table use some time
+let $i= 10;
+while ($i) {
+  eval INSERT INTO t1 (a) VALUES ($i);
+  dec $i;
+}
+
+connection locker;
+SET DEBUG_SYNC= 'alter_table_before_main_binlog
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER TABLE t1 ADD COLUMN (c CHAR(100) DEFAULT "test 1.5");
+
+connection waiter;
+
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send HANDLER t1 OPEN;
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+HANDLER t1 READ FIRST;
+HANDLER t1 CLOSE;
+
+connection default;
+SELECT SUM(a) FROM t1;
+SELECT COUNT(*) FROM t1 WHERE NOT c LIKE "test 1.5";
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+
+--echo ##
+--echo ## 1.6 Tow connections are long create/select, while another is
+--echo ##     altering the table
+--echo ##
+
+--echo # Connections locker1..locker3 will run different SQL queries, which
+--echo # will all lock on the same resource.
+connect (locker1,localhost,root,,);
+connect (locker2,localhost,root,,);
+connect (locker3,localhost,root,,);
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b INT) ENGINE=$engine_type;
+
+# 5 rows, 1 sec sleep for each = 5 sec sleep
+INSERT INTO t1 VALUES (1, 2), (2, 3), (3, 4), (4, 5), (5, 6);
+
+connection locker1;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+--replace_result $engine_type <engine_type>
+send;
+eval CREATE TABLE t2 ENGINE=$engine_type AS SELECT *, SLEEP(1) FROM t1;
+
+connection locker2;
+send;
+eval CREATE TABLE t3 LIKE t1;
+
+connection locker3;
+--replace_result $engine_type <engine_type>
+send;
+eval CREATE TABLE t4 ENGINE=$engine_type AS SELECT *, SLEEP(1) FROM t1;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'mdl_enter_cond SIGNAL do_unlock';
+send ALTER TABLE t1 ADD COLUMN (c INT);
+
+connection locker3;
+reap;
+
+connection locker2;
+reap;
+
+connection locker1;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+SELECT SUM(a), SUM(b) FROM t2;
+SELECT SUM(a), SUM(b) FROM t3;
+SELECT SUM(a), SUM(b) FROM t4;
+
+--echo # Closing connections locker1..locker3 since they are not used any more
+disconnect locker1;
+disconnect locker2;
+disconnect locker3;
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+
+--echo ##
+--echo ## 1.7 Both connections trying to rename the same table/view
+--echo ##     (including alter ... rename command)
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1(a INT, b CHAR(100)) ENGINE=$engine_type;
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER TABLE t1 RENAME t2;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'after_start_ddl SIGNAL do_unlock';
+send ALTER TABLE t2 RENAME t3;
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+SELECT SUM(a) FROM t3;
+SELECT COUNT(*) FROM t3;
+
+SET DEBUG_SYNC= 'RESET';
+DROP TABLE t3;
+
+##
+## 1.8 - Repeat with different engines: already supported, set $engine_type
+##
+
+--echo ##
+--echo ## 1.8a Use list of tables in DROP TABLE and RENAME TABLE statements
+--echo ##
+
+let $lock_table_2 = t_$lock_table;
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE $lock_table(a INT) ENGINE=$engine_type;
+eval INSERT INTO $lock_table VALUES (1);
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE $lock_table_2(a INT) ENGINE=$engine_type;
+eval INSERT INTO $lock_table_2 VALUES (1);
+
+
+let $sql= RENAME TABLE $lock_table TO t2, $lock_table_2 TO t3;
+let $teardown= RENAME TABLE t2 TO $lock_table, t3 TO $lock_table_2;
+--source suite/ddl_lock/include/sync_lock.inc
+let $teardown= ;
+
+let $sql= DROP TABLE $lock_table, $lock_table_2;
+--source suite/ddl_lock/include/sync_lock.inc
+
+--echo ##
+--echo ## 1.9 Two connections trying to alter the same stored procedure
+--echo ##     and function
+--echo ##
+
+connection default;
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+     ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE t_proc ()
+BEGIN
+   SELECT * FROM t1;
+END|
+delimiter ;|
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn lock 1.9';
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+send ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn waiter 1.9';
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+DROP PROCEDURE t_proc;
+
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER FUNCTION t_func COMMENT 'Now with a comment from conn locker 1.9';
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+send ALTER FUNCTION t_func COMMENT 'Now with a comment from conn waiter 1.9';
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+DROP FUNCTION t_func;
+DROP TABLE t1;
+
+--echo ##
+--echo ## 1.10 One Connection altering a stored procedure/function, while
+--echo ##      the other is dropping it.
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+     ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE t_proc ()
+BEGIN
+   SELECT * FROM t1;
+END|
+delimiter ;|
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn lock 1.10';
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+send DROP PROCEDURE t_proc;
+
+connection locker;
+# TODO: Remove when WL#4299 is fixed
+--error ER_SP_DOES_NOT_EXIST
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');
+
+connection locker;
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send ALTER FUNCTION t_func COMMENT 'Now with a comment from conn lock 1.10';
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'wait_for_lock SIGNAL do_unlock';
+send DROP FUNCTION t_func;
+
+connection locker;
+# TODO: Remove when WL#4299 is fixed
+--error ER_SP_DOES_NOT_EXIST
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+DROP table t1;
+
+--echo ##
+--echo ## 1.11, 1.12 and 1.13 - ALTER TABLE and TRUNCATE TABLE simoultaniously
+--echo ##
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE $lock_table(a INT, b CHAR(20) DEFAULT "test 1.11")
+     ENGINE=$engine_type;
+eval INSERT INTO $lock_table (a) VALUES (1);
+
+let $sync= locked_external;
+# InnoDB needs other syncronization signal
+if (`SELECT STRCMP("$engine_type", "InnoDB") = 0`) {
+    let $sync= after_lock_tables_takes_lock;
+}
+
+let sync2= after_lock_tables_takes_lock;
+if (`SELECT STRCMP("$engine_type", "InnoDB") = 0`) {
+    let $sync2= wait_for_lock;
+}
+
+let sync3= locked_external;
+if (`SELECT STRCMP("$engine_type", "InnoDB") = 0`) {
+    let $sync3= wait_for_lock;
+}
+
+connection locker;
+
+--replace_result $sync <sync>
+eval SET DEBUG_SYNC= '$sync SIGNAL locked WAIT_FOR do_unlock';
+send;
+eval TRUNCATE TABLE $lock_table;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--replace_result $sync2 <sync2>
+eval SET DEBUG_SYNC= '$sync2 SIGNAL do_unlock';
+send;
+eval ALTER TABLE $lock_table ADD COLUMN (c INT);
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+SET DEBUG_SYNC= 'RESET';
+
+connection locker;
+# --replace_result $sync2 <sync2>
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock
+                 SIGNAL locked WAIT_FOR do_unlock';
+send;
+eval ALTER TABLE $lock_table ADD COLUMN (d INT);
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+--replace_result $sync3 <sync3>
+eval SET DEBUG_SYNC= '$sync3 SIGNAL do_unlock';
+send;
+eval TRUNCATE TABLE $lock_table;
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+
+SET DEBUG_SYNC= 'RESET';
+eval DROP TABLE $lock_table;
+
+--echo ##
+--echo ## 1.14 Two connections are trying to alter the same event.
+--echo ##
+
+CREATE EVENT ev1 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
+SELECT MOD(29,9);
+
+connection locker;
+SET DEBUG_SYNC= 'locked_external SIGNAL locked WAIT_FOR do_unlock';
+send ALTER EVENT ev1 ON SCHEDULE EVERY 12 HOUR
+     STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR;
+
+connection waiter;
+SET DEBUG_SYNC= 'now WAIT_FOR locked';
+SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL do_unlock';
+send ALTER EVENT ev1 ON SCHEDULE EVERY 4 HOUR
+     STARTS CURRENT_TIMESTAMP + INTERVAL 4 HOUR;
+
+connection locker;
+reap;
+
+connection waiter;
+reap;
+
+connection default;
+SET DEBUG_SYNC= 'RESET';
+DROP EVENT ev1;
+
+--echo # Clean up connections
+disconnect waiter;
+disconnect locker;

=== added file 'mysql-test/suite/ddl_lock/t/create_stress_tables.test'
--- a/mysql-test/suite/ddl_lock/t/create_stress_tables.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/t/create_stress_tables.test	2008-12-16 10:32:25 +0000
@@ -0,0 +1,54 @@
+##
+## Test for WL #4343 - DDL locking for all metadata objects
+##
+
+##
+## Test case 3: Concurrent system scenarios - create tables
+##
+
+--source suite/ddl_lock/include/stress_settings.inc
+
+if (`SELECT LENGTH("$engine_type") = 0`) {
+  let $engine_type= myisam;
+}
+
+#
+# Create test table with some data
+#
+
+--replace_result $engine_type <engine_type>
+eval CREATE TABLE t1 (id INT PRIMARY KEY, b CHAR(100) DEFAULT "initial value")
+     ENGINE=$engine_type;
+
+# Need something to start with
+INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8);
+
+# Bulk load the correct number of rows
+while (`SELECT MAX(id) < $num_stress_rows FROM t1`)
+{
+   SELECT MAX(id) FROM t1 INTO @max;
+--replace_result $num_stress_rows <num_stress_rows>
+   eval INSERT INTO t1(id) SELECT id + @max FROM t1
+        WHERE id + @max <= $num_stress_rows;
+}
+
+#
+# Create stored Procedure
+#
+delimiter |;
+CREATE PROCEDURE t_proc (OUT b_p CHAR(100))
+BEGIN
+   SELECT b INTO @b_p FROM t1 WHERE Id = 1;
+END|
+delimiter ;|
+
+#
+# Create function
+#
+CREATE FUNCTION t_func (s CHAR(20)) RETURNS CHAR(30) DETERMINISTIC
+RETURN CONCAT('Hello, ', s, '!');
+
+#
+# Side effects: this test will create table t1, and routines t_proc
+#               and t_func. This is intentional.
+#

=== added file 'mysql-test/suite/ddl_lock/t/stress_ddl.test'
--- a/mysql-test/suite/ddl_lock/t/stress_ddl.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/t/stress_ddl.test	2008-12-16 10:32:25 +0000
@@ -0,0 +1,75 @@
+##
+## Test for WL #4343 - DDL locking for all metadata objects
+##
+
+##
+## Test case 3: Concurrent system scenarios - DDL load
+##
+
+# Detect whether or not this test is run from the stress test,
+# with the proper setup
+let $have_table= `SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
+                  WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'`;
+
+let $have_proc= `SELECT (COUNT(*) = 1) FROM INFORMATION_SCHEMA.ROUTINES
+                 WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='t_proc'`;
+
+let $have_func= `SELECT (COUNT(*) = 1) FROM INFORMATION_SCHEMA.ROUTINES
+                 WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='t_func'`;
+
+if (`SELECT ($have_table = 0) OR ($have_proc = 0) OR ($have_func = 0)`) {
+    --disable_query_log
+    --disable_result_log
+    --source suite/ddl_lock/t/create_stress_tables.test
+    --enable_result_log
+    --enable_query_log
+}
+
+# Use connection id so that the db objects created here get unique names
+let $conn_id= `SELECT CONNECTION_ID()`;
+
+let $col_name= c_$conn_id;
+let $idx_name= t1_indx_c_$conn_id;
+let $view_name= view_$conn_id;
+let $all_view_name= all_view_$conn_id;
+
+--source suite/ddl_lock/include/stress_settings.inc
+let $row_id= `SELECT ROUND(RAND() * $num_stress_rows)`;
+
+#
+# Table and Index
+#
+--replace_result $col_name <column_name>
+eval ALTER TABLE t1 ADD COLUMN $col_name CHAR(200) DEFAULT "New column";
+--replace_result $idx_name <index_name> $col_name <column_name>
+eval CREATE INDEX $idx_name ON t1 ($col_name);
+--replace_result $col_name <column_name>
+eval SELECT DISTINCT($col_name) FROM t1;
+--replace_result $idx_name <index_name>
+eval DROP INDEX $idx_name ON t1;
+--replace_result $col_name <column_name>
+eval ALTER TABLE t1 DROP COLUMN $col_name;
+
+#
+# View
+#
+--replace_result $view_name <view_name>
+eval CREATE VIEW $view_name AS SELECT DISTINCT b FROM t1;
+--replace_result $all_view_name <all_view_name>
+eval CREATE VIEW $all_view_name AS SELECT id, b FROM t1;
+--replace_result $all_view_name <all_view_name> $row_id <random_id>
+eval SELECT id FROM $all_view_name WHERE id = $row_id;
+--replace_result $all_view_name <all_view_name> $view_name <view_name>
+eval DROP VIEW $view_name, $all_view_name;
+
+#
+# Stored Procedure
+#
+--replace_result $conn_id <conn_id>
+eval ALTER PROCEDURE t_proc COMMENT 'Now with a comment from conn $conn_id';
+
+#
+# Function
+#
+--replace_result $conn_id <conn_id>
+eval ALTER FUNCTION t_func COMMENT 'Now with a comment from conn $conn_id';

=== added file 'mysql-test/suite/ddl_lock/t/stress_dml.test'
--- a/mysql-test/suite/ddl_lock/t/stress_dml.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ddl_lock/t/stress_dml.test	2008-12-16 10:32:25 +0000
@@ -0,0 +1,55 @@
+##
+## Test for WL #4343 - DDL locking for all metadata objects
+##
+
+##
+## Test case 3: Concurrent system scenarios - DML load
+##
+
+# Detect whether or not this test is run from the stress test,
+# with the proper setup
+let $have_table= `SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
+                  WHERE TABLE_SCHEMA='test' AND TABLE_NAME='t1'`;
+
+let $have_proc= `SELECT (COUNT(*) = 1) FROM INFORMATION_SCHEMA.ROUTINES
+                 WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='t_proc'`;
+
+let $have_func= `SELECT (COUNT(*) = 1) FROM INFORMATION_SCHEMA.ROUTINES
+                 WHERE ROUTINE_SCHEMA='test' AND ROUTINE_NAME='t_func'`;
+
+if (`SELECT ($have_table = 0) OR ($have_proc = 0) OR ($have_func = 0)`) {
+    --disable_query_log
+    --disable_result_log
+    --source suite/ddl_lock/t/create_stress_tables.test
+    --enable_result_log
+    --enable_query_log
+}
+
+--source suite/ddl_lock/include/stress_settings.inc
+
+let $row_id= `SELECT ROUND(RAND() * $num_stress_rows)`;
+
+START TRANSACTION;
+--replace_result $row_id <random>
+eval UPDATE t1 SET b = "changed" WHERE id=$row_id;
+--replace_result $row_id <random>
+eval SELECT id,b FROM t1 WHERE id=$row_id;
+COMMIT;
+
+START TRANSACTION;
+--replace_result $row_id <random>
+eval DELETE FROM t1 WHERE id=$row_id;
+--replace_result $row_id <random>
+eval INSERT INTO t1 (id, b) VALUES ($row_id, "newly_inserted");
+COMMIT;
+
+#
+# Call stored procedure
+#
+eval CALL t_proc(@b);
+SELECT @b;
+
+#
+# Call function
+#
+eval SELECT t_func('world');

=== modified file 'sql/debug_sync.cc'
--- a/sql/debug_sync.cc	2008-11-20 11:01:12 +0000
+++ b/sql/debug_sync.cc	2008-12-16 10:32:25 +0000
@@ -544,7 +544,7 @@ static void debug_sync_action_string(cha
     {
       if ((wtxt == result) && (wtxt < wend))
         *(wtxt++)= ' ';
-      wtxt= debug_sync_bmove_len(wtxt, wend, STRING_WITH_LEN("WAIT_FOR "));
+      wtxt= debug_sync_bmove_len(wtxt, wend, STRING_WITH_LEN(" WAIT_FOR "));
       wtxt= debug_sync_bmove_len(wtxt, wend, action->wait_for.ptr(),
                                  action->wait_for.length());
 

=== modified file 'sql/lock.cc'
--- a/sql/lock.cc	2008-10-23 16:29:52 +0000
+++ b/sql/lock.cc	2008-12-16 10:32:25 +0000
@@ -425,6 +425,7 @@ static int lock_external(THD *thd, TABLE
       (*tables)->current_lock= lock_type;
     }
   }
+  DEBUG_SYNC(thd, "locked_external");
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2008-10-14 12:08:56 +0000
+++ b/sql/mdl.cc	2008-12-16 10:32:25 +0000
@@ -15,6 +15,7 @@
 
 
 #include "mdl.h"
+#include "mysql_priv.h"
 
 #include <hash.h>
 #include <mysqld_error.h>
@@ -470,6 +471,8 @@ static inline const char* mdl_enter_cond
   mysys_var->current_mutex= &LOCK_mdl;
   mysys_var->current_cond= &COND_mdl;
 
+  DEBUG_SYNC(context->thd, "mdl_enter_cond");
+
   return set_thd_proc_info(context->thd, "Waiting for table",
                            calling_func, calling_file, calling_line);
 }
@@ -491,6 +494,8 @@ static inline void mdl_exit_cond(MDL_CON
   mysys_var->current_cond= 0;
   pthread_mutex_unlock(&mysys_var->mutex);
 
+  DEBUG_SYNC(context->thd, "mdl_exit_cond");
+
   (void) set_thd_proc_info(context->thd, old_msg, calling_func,
                            calling_file, calling_line);
 }

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2008-12-08 11:29:15 +0000
+++ b/sql/sql_base.cc	2008-12-16 10:32:25 +0000
@@ -4472,6 +4472,8 @@ int lock_tables(THD *thd, TABLE_LIST *ta
                                         flags, need_reopen)))
       DBUG_RETURN(-1);
 
+    DEBUG_SYNC(thd, "after_lock_tables_takes_lock");
+
     if (thd->lex->requires_prelocking() &&
         thd->lex->sql_command != SQLCOM_LOCK_TABLES)
     {

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-12-08 11:29:15 +0000
+++ b/sql/sql_table.cc	2008-12-16 10:32:25 +0000
@@ -6577,6 +6577,8 @@ bool mysql_alter_table(THD *thd,char *ne
         Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
         mysql_bin_log.write(&qinfo);
       }
+      DBUG_EXECUTE_IF("sleep_alter_rename_view", my_sleep(6000000););
+      DEBUG_SYNC(thd, "alter_rename_view");
       my_ok(thd);
     }
     pthread_mutex_unlock(&LOCK_open);
@@ -7170,22 +7172,31 @@ view_err:
     error=1;
     (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
   }
-  else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
+
+  else {
+
+    DEBUG_SYNC(thd, "alter_table_before_rename");
+
+    if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
                               new_alias, FN_FROM_IS_TMP) ||
            (new_name != table_name || new_db != db) && // we also do rename
            Table_triggers_list::change_table_name(thd, db, table_name,
                                                   new_db, new_alias))
-  {
-    /* Try to get everything back. */
-    error=1;
-    (void) quick_rm_table(new_db_type,new_db,new_alias, 0);
-    (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
-    (void) mysql_rename_table(old_db_type, db, old_name, db, alias,
-                            FN_FROM_IS_TMP);
+      {
+        /* Try to get everything back. */
+        error=1;
+        (void) quick_rm_table(new_db_type,new_db,new_alias, 0);
+        (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
+        (void) mysql_rename_table(old_db_type, db, old_name, db, alias,
+                                  FN_FROM_IS_TMP);
+      }
   }
 
+  DBUG_EXECUTE_IF("sleep_alter_rename_table", my_sleep(6000000););
+  DEBUG_SYNC(thd, "alter_rename_table");
+
   if (! error)
-  (void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
+    (void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
 
   pthread_mutex_unlock(&LOCK_open);
 
@@ -7199,6 +7210,7 @@ end_online:
   thd_proc_info(thd, "end");
 
   DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
+  DEBUG_SYNC(thd, "alter_table_before_main_binlog");
 
   ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
                       thd->query, thd->query_length,

Thread
bzr commit into mysql-6.0-runtime branch (jorgen.austvik:2780) WL#4343Jorgen Austvik16 Dec