Below is the list of changes that have just been committed into a local
6.0 repository of istruewing. When istruewing does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2008-02-13 23:37:45+01:00, istruewing@stripped +25 -0
Conversion of backup test to the Test Synchronization Facility
Not to be pushed. This is an example for changing the
synchronization facility.
It contains the pre-review version of the patch for the
Test Synchronization Facility
plus sync points in the backup code and synchronization
statements as replacements for the user level locks.
libmysqld/CMakeLists.txt@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +1 -1
Pre-review version of WL 4259 - Test Synchronization Facility
libmysqld/Makefile.am@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +1 -0
Pre-review version of WL 4259 - Test Synchronization Facility
mysql-test/mysql-test-run.pl@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +8 -0
Pre-review version of WL 4259 - Test Synchronization Facility
mysql-test/r/backup_progress.result@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +31 -37
Changed result for conversion to the Test Synchronization Facility
mysql-test/r/grant.result@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +4 -4
Pre-review version of WL 4259 - Test Synchronization Facility
mysql-test/r/merge.result@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +117 -86
Pre-review version of WL 4259 - Test Synchronization Facility
mysql-test/t/backup_progress.test@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +31 -63
Changed test for conversion to the Test Synchronization Facility
mysql-test/t/merge.test@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +294 -63
Pre-review version of WL 4259 - Test Synchronization Facility
mysys/thr_lock.c@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +13 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/CMakeLists.txt@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +1 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/Makefile.am@stripped, 2008-02-13 23:37:41+01:00, istruewing@stripped +2 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/backup/data_backup.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +2 -0
New synchronization points for conversion to the
Test Synchronization Facility
sql/backup/kernel.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +4 -0
New synchronization points for conversion to the
Test Synchronization Facility
sql/item_func.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +2 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/lex.h@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +7 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/lock.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +2 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/mysqld.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +27 -1
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_base.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +6 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_class.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +9 -1
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_class.h@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +7 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_lex.h@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +4 -1
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_parse.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +15 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_table.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +1 -0
Pre-review version of WL 4259 - Test Synchronization Facility
sql/sql_yacc.yy@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +107 -0
Pre-review version of WL 4259 - Test Synchronization Facility
storage/myisammrg/ha_myisammrg.cc@stripped, 2008-02-13 23:37:42+01:00, istruewing@stripped +4 -0
Pre-review version of WL 4259 - Test Synchronization Facility
diff -Nrup a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
--- a/libmysqld/CMakeLists.txt 2007-12-13 13:47:11 +01:00
+++ b/libmysqld/CMakeLists.txt 2008-02-13 23:37:41 +01:00
@@ -187,7 +187,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libm
../sql/strfunc.cc ../sql/table.cc ../sql/thr_malloc.cc
../sql/time.cc ../sql/tztime.cc ../sql/uniques.cc ../sql/unireg.cc
../sql/partition_info.cc ../sql/sql_connect.cc
- ../sql/scheduler.cc
+ ../sql/scheduler.cc ../sql/mysql_test_sync.cc
${GEN_SOURCES}
${LIB_SOURCES})
diff -Nrup a/libmysqld/Makefile.am b/libmysqld/Makefile.am
--- a/libmysqld/Makefile.am 2008-02-08 21:22:26 +01:00
+++ b/libmysqld/Makefile.am 2008-02-13 23:37:41 +01:00
@@ -80,6 +80,7 @@ sqlsources = derror.cc field.cc field_co
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \
+ mysql_test_sync.cc \
sql_servers.cc ddl_blocker.cc si_objects.cc
libmysqld_int_a_SOURCES= $(libmysqld_sources)
diff -Nrup a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
--- a/mysql-test/mysql-test-run.pl 2008-02-08 17:02:56 +01:00
+++ b/mysql-test/mysql-test-run.pl 2008-02-13 23:37:41 +01:00
@@ -268,6 +268,7 @@ my @default_valgrind_args= ("--show-reac
my @valgrind_args;
my $opt_valgrind_path;
my $opt_callgrind;
+my $opt_test_synchronize= 300; # Default timeout for WAIT_FOR actions.
our $opt_stress= "";
our $opt_stress_suite= "main";
@@ -617,6 +618,7 @@ sub command_line_setup () {
'valgrind-option=s' => \@valgrind_args,
'valgrind-path=s' => \$opt_valgrind_path,
'callgrind' => \$opt_callgrind,
+ 'test-synchronize=i' => \$opt_test_synchronize,
# Stress testing
'stress' => \$opt_stress,
@@ -3590,6 +3592,10 @@ sub mysqld_arguments ($$$$) {
# see BUG#28359
mtr_add_arg($args, "%s--connect-timeout=60", $prefix);
+ # Enable the TEST SYNCHRONIZE facility, set default wait timeout.
+ # Facility stays disabled if timeout value is zero.
+ mtr_add_arg($args, "%s--test-synchronize=%s", $prefix,
+ $opt_test_synchronize);
# When mysqld is run by a root user(euid is 0), it will fail
# to start unless we specify what user to run as. If not running
@@ -5032,6 +5038,8 @@ Options for coverage, profiling etc
can be specified more then once
valgrind-path=[EXE] Path to the valgrind executable
callgrind Instruct valgrind to use callgrind
+ test-synchronize=NUM Set default timeout for WAIT_FOR test synchronize
+ actions. Disable facility with NUM=0.
Misc options
diff -Nrup a/mysql-test/r/backup_progress.result b/mysql-test/r/backup_progress.result
--- a/mysql-test/r/backup_progress.result 2007-12-20 21:32:15 +01:00
+++ b/mysql-test/r/backup_progress.result 2008-02-13 23:37:41 +01:00
@@ -1,6 +1,6 @@
DROP DATABASE IF EXISTS backup_progress;
DROP TABLE IF EXISTS backup_progress.t1_res;
-SET GLOBAL debug="d,backup_debug:d,backup";
+SET GLOBAL debug="+d,backup_debug,backup";
CREATE DATABASE backup_progress;
con1: Create table and new users.
CREATE TABLE backup_progress.t1 (a char(30)) ENGINE=MYISAM;
@@ -25,48 +25,44 @@ INSERT INTO backup_progress.t3 VALUES ("
INSERT INTO backup_progress.t3 VALUES ("03 Test #1 - progress");
INSERT INTO backup_progress.t3 VALUES ("04 Test #1 - progress");
Do backup of database
-SELECT get_lock("bp_starting_state", 0);
-get_lock("bp_starting_state", 0)
-1
+con2: Activate sync points for the backup statement.
+TEST SYNCHRONIZE before_backup_start_backup SIGNAL started WAIT_FOR do_run;
+TEST SYNCHRONIZE after_backup_start_backup SIGNAL phase1 WAIT_FOR backup;
+TEST SYNCHRONIZE after_backup_validated SIGNAL validated WAIT_FOR do_phase2;
+TEST SYNCHRONIZE before_backup_binlog SIGNAL phase2 WAIT_FOR finish;
con2: Send backup command.
BACKUP DATABASE backup_progress to 'backup_progress_orig.bak';
-con1: Checking locks.
+con1: Wait for the backup to be started.
+TEST SYNCHRONIZE now WAIT_FOR started;
con1: Checking progress.
+con1: Display progress
INSERT INTO backup_progress.t1_res (id) SELECT backup_id FROM mysql.online_backup WHERE command LIKE "BACKUP DATABASE backup_progress%";
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
starting
-con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-get_lock("bp_running_state", 0)
-1
-con1: Checking locks.
+con1: Let backup step to running state.
+TEST SYNCHRONIZE now SIGNAL do_run WAIT_FOR phase1;
con1: Checking progress.
+con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
running
-con1: Advance the lock.
-SELECT get_lock("bp_vp_state", 0);
-get_lock("bp_vp_state", 0)
-1
-con1: Checking locks.
+con1: Let backup do the backup phase1.
+TEST SYNCHRONIZE now SIGNAL backup WAIT_FOR validated;
con1: Checking progress.
+con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
validity point
-con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-get_lock("bp_running_state", 0)
-1
-con1: Checking locks.
+con1: Let backup do the backup phase2.
+TEST SYNCHRONIZE now SIGNAL do_phase2 WAIT_FOR phase2;
con1: Checking progress.
+con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
running
-con1: Advance the lock.
-SELECT release_lock("bp_running_state");
-release_lock("bp_running_state")
-1
+con1: Let backup finish.
+TEST SYNCHRONIZE now SIGNAL finish;
con2: Finish backup command
backup_id
#
@@ -97,33 +93,31 @@ backup_id object start_time stop_time to
# backup kernel # # 0 0 0 running
# backup kernel # # 0 0 0 complete
Do restore of database
-SELECT get_lock("bp_starting_state", 0);
-get_lock("bp_starting_state", 0)
-1
DELETE FROM backup_progress.t1_res;
+con2: Activate sync points for the backup statement.
+TEST SYNCHRONIZE before_backup_start_restore SIGNAL started WAIT_FOR do_run;
+TEST SYNCHRONIZE after_backup_start_restore SIGNAL running WAIT_FOR finish;
con2: Send restore command.
RESTORE FROM 'backup_progress_orig.bak';
-con1: Checking locks.
+con1: Wait for the restore to be started.
+TEST SYNCHRONIZE now WAIT_FOR started;
con1: Checking progress.
+con1: Display progress
select * from backup_progress.t1_res;
id
INSERT INTO backup_progress.t1_res (id) SELECT backup_id FROM mysql.online_backup WHERE command LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
starting
-con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-get_lock("bp_running_state", 0)
-1
-con1: Checking locks.
+con1: Let restore step to running state.
+TEST SYNCHRONIZE now SIGNAL do_run WAIT_FOR running;
con1: Checking progress.
+con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
backup_state
running
-con1: Advance the lock.
-SELECT release_lock("bp_running_state");
-release_lock("bp_running_state")
-1
+con1: Let restore do its job and finish.
+TEST SYNCHRONIZE now SIGNAL finish;
con2: Finish restore command
backup_id
#
diff -Nrup a/mysql-test/r/grant.result b/mysql-test/r/grant.result
--- a/mysql-test/r/grant.result 2008-02-05 10:25:53 +01:00
+++ b/mysql-test/r/grant.result 2008-02-13 23:37:41 +01:00
@@ -213,14 +213,14 @@ set sql_quote_show_create=0;
show grants for drop_user@localhost;
Grants for drop_user@localhost
GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
-GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION
-GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost'
+GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON `test`.t1 TO 'drop_user'@'localhost'
set sql_mode="ansi_quotes";
show grants for drop_user@localhost;
Grants for drop_user@localhost
GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION
-GRANT ALL PRIVILEGES ON test.* TO 'drop_user'@'localhost' WITH GRANT OPTION
-GRANT SELECT (a) ON test.t1 TO 'drop_user'@'localhost'
+GRANT ALL PRIVILEGES ON "test".* TO 'drop_user'@'localhost' WITH GRANT OPTION
+GRANT SELECT (a) ON "test".t1 TO 'drop_user'@'localhost'
set sql_quote_show_create=1;
show grants for drop_user@localhost;
Grants for drop_user@localhost
diff -Nrup a/mysql-test/r/merge.result b/mysql-test/r/merge.result
--- a/mysql-test/r/merge.result 2007-12-13 13:56:17 +01:00
+++ b/mysql-test/r/merge.result 2008-02-13 23:37:41 +01:00
@@ -1,3 +1,4 @@
+TEST SYNCHRONIZE RESET;
drop table if exists t1,t2,t3,t4,t5,t6;
drop database if exists mysqltest;
create table t1 (a int not null primary key auto_increment, message char(20));
@@ -1071,28 +1072,59 @@ UNLOCK TABLES;
DROP TABLE t1, t2, t3, t4;
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
+connection con1
+TEST SYNCHRONIZE after_admin_flush SIGNAL admin_flush WAIT_FOR end_repair;
REPAIR TABLE t1;
+connection default;
+TEST SYNCHRONIZE NOW WAIT_FOR admin_flush;
+TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 3;
+TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL end_repair;
INSERT INTO t2 VALUES (1);
+TEST SYNCHRONIZE NOW SIGNAL end_repair;
+connection con1
Table Op Msg_type Msg_text
test.t1 repair status OK
+connection default;
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2;
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
LOCK TABLE t1 WRITE;
-INSERT INTO t2 VALUES (1);
REPAIR TABLE t1;
Table Op Msg_type Msg_text
test.t1 repair status OK
+connection con1
+TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 3;
+TEST SYNCHRONIZE after_insert SIGNAL end_repair;
+TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL end_repair;
+INSERT INTO t2 VALUES (1);
+connection default;
+TEST SYNCHRONIZE NOW WAIT_FOR end_repair;
UNLOCK TABLES;
+connection con1
+connection default;
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2;
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
LOCK TABLE t1 WRITE;
+connection con1
+TEST SYNCHRONIZE before_lock_tables_takes_lock
+SIGNAL opened WAIT_FOR flushed;
+TEST SYNCHRONIZE wait_for_lock SIGNAL locked EXECUTE 2;
+TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL locked;
+TEST SYNCHRONIZE after_insert SIGNAL locked;
INSERT INTO t1 VALUES (1);
+connection default
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
FLUSH TABLES;
-FLUSH TABLES;
+TEST SYNCHRONIZE NOW WAIT_FOR locked;
SELECT * FROM t1;
c1
UNLOCK TABLES;
+connection con1
+connection default
+TEST SYNCHRONIZE RESET;
DROP TABLE t1;
#
# Extra tests for Bug#26379 - Combination of FLUSH TABLE and
@@ -1611,6 +1643,7 @@ c1
33
DELETE FROM t4 WHERE c1 = 33;
DROP TRIGGER t3_ai;
+UNLOCK TABLES;
#
# Trigger with table use on child
DELETE FROM t4 WHERE c1 = 4;
@@ -1793,9 +1826,9 @@ ALTER TABLE t2 UNION=(t3,t1);
SELECT * FROM t2;
ERROR HY000: Table 't3' is differently defined or of non-MyISAM type or doesn't exist
DROP TABLE t1, t2, t3;
-CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
-CREATE TABLE t2 (c1 INT) ENGINE= MyISAM;
-CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2);
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
SELECT * FROM t3;
@@ -1807,88 +1840,25 @@ SELECT * FROM t3;
c1
2
DROP TABLE t1, t2, t3;
-CREATE TABLE t1 (id INTEGER, grp TINYINT, id_rev INTEGER);
-SET @rnd_max= 2147483647;
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-SET @rnd= RAND();
-SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
-SET @id_rev= @rnd_max - @id;
-SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
-INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
-set @@read_buffer_size=2*1024*1024;
-CREATE TABLE t2 SELECT * FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-CREATE TABLE t3 (id INTEGER, grp TINYINT, id_rev INTEGER)
-ENGINE= MRG_MYISAM UNION= (t1, t2);
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-130
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-80
-SELECT COUNT(*) FROM t3;
-COUNT(*)
-210
-SELECT COUNT(DISTINCT a1.id) FROM t3 AS a1, t3 AS a2
-WHERE a1.id = a2.id GROUP BY a2.grp;
+CREATE TABLE t1 (c1 REAL) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 REAL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(0.1);
+INSERT INTO t2 VALUES(0.2);
+CREATE TABLE t3 (c1 REAL) ENGINE=MRG_MYISAM UNION=(t1,t2);
+connection con1
+TEST SYNCHRONIZE before_acos_function SIGNAL 'select' WAIT_FOR truncated;
+SELECT ACOS(c1) FROM t3;
+connection default
+TEST SYNCHRONIZE NOW WAIT_FOR 'select';
+TEST SYNCHRONIZE before_wait_locked_tname SIGNAL truncated;
TRUNCATE TABLE t1;
-SELECT COUNT(*) FROM t1;
-COUNT(*)
-0
-SELECT COUNT(*) FROM t2;
-COUNT(*)
-80
-SELECT COUNT(*) FROM t3;
-COUNT(*)
-80
+TEST SYNCHRONIZE NOW SIGNAL truncated;
+connection con1
+connection default
+SELECT ACOS(c1) FROM t3;
+ACOS(c1)
+1.369438406004566
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2, t3;
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
@@ -1984,3 +1954,64 @@ test.t1 optimize status OK
FLUSH TABLES m1, t1;
UNLOCK TABLES;
DROP TABLE t1, m1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+connection con1
+TEST SYNCHRONIZE before_myisammrg_attach SIGNAL attach WAIT_FOR flushed;
+INSERT INTO m1 VALUES (2);
+connection default;
+TEST SYNCHRONIZE NOW WAIT_FOR attach;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
+FLUSH TABLE m1;
+connection con1
+connection default;
+SELECT * FROM m1;
+c1
+2
+TEST SYNCHRONIZE RESET;
+DROP TABLE m1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+connection con1
+TEST SYNCHRONIZE before_myisammrg_attach SIGNAL attach WAIT_FOR store_lock1;
+TEST SYNCHRONIZE before_myisammrg_store_lock
+SIGNAL store_lock2 WAIT_FOR flushed;
+INSERT INTO m1 VALUES (2);
+connection default;
+TEST SYNCHRONIZE NOW WAIT_FOR attach;
+TEST SYNCHRONIZE before_myisammrg_store_lock
+SIGNAL store_lock1 WAIT_FOR store_lock2;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
+FLUSH TABLE m1;
+connection con1
+connection default;
+SELECT * FROM m1;
+c1
+2
+TEST SYNCHRONIZE RESET;
+DROP TABLE m1, t1;
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+connection con1
+TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 2;
+TEST SYNCHRONIZE before_lock_tables_takes_lock
+SIGNAL opened WAIT_FOR flushed EXECUTE 2;
+TEST SYNCHRONIZE wait_for_lock SIGNAL locked EXECUTE 4;
+TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL refresh EXECUTE 2;
+TEST SYNCHRONIZE after_insert SIGNAL locked EXECUTE 2;
+INSERT INTO t1 VALUES (1);
+connection default;
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed EXECUTE 2;
+FLUSH TABLES;
+TEST SYNCHRONIZE NOW WAIT_FOR refresh;
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE;
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+FLUSH TABLES;
+TEST SYNCHRONIZE NOW WAIT_FOR locked;
+UNLOCK TABLES;
+connection con1
+connection default;
+TEST SYNCHRONIZE RESET;
+DROP TABLE t1;
diff -Nrup a/mysql-test/t/backup_progress.test b/mysql-test/t/backup_progress.test
--- a/mysql-test/t/backup_progress.test 2007-12-20 21:32:16 +01:00
+++ b/mysql-test/t/backup_progress.test 2008-02-13 23:37:41 +01:00
@@ -19,7 +19,7 @@ connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
# Setup the server to use the backup breakpoints
-SET GLOBAL debug="d,backup_debug:d,backup";
+SET GLOBAL debug="+d,backup_debug,backup";
#
# Test 1 - Check output of backup.
@@ -58,20 +58,19 @@ INSERT INTO backup_progress.t3 VALUES ("
--echo Do backup of database
-SELECT get_lock("bp_starting_state", 0);
-
connection con2;
+--echo con2: Activate sync points for the backup statement.
+TEST SYNCHRONIZE before_backup_start_backup SIGNAL started WAIT_FOR do_run;
+TEST SYNCHRONIZE after_backup_start_backup SIGNAL phase1 WAIT_FOR backup;
+TEST SYNCHRONIZE after_backup_validated SIGNAL validated WAIT_FOR do_phase2;
+TEST SYNCHRONIZE before_backup_binlog SIGNAL phase2 WAIT_FOR finish;
--echo con2: Send backup command.
send BACKUP DATABASE backup_progress to 'backup_progress_orig.bak';
connection con1;
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_starting_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "BACKUP DATABASE %";
---source include/wait_condition.inc
+--echo con1: Wait for the backup to be started.
+TEST SYNCHRONIZE now WAIT_FOR started;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -80,19 +79,12 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "BACKUP DATABASE backup_progress%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
INSERT INTO backup_progress.t1_res (id) SELECT backup_id FROM mysql.online_backup WHERE command LIKE "BACKUP DATABASE backup_progress%";
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_running_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "BACKUP DATABASE %";
---source include/wait_condition.inc
+--echo con1: Let backup step to running state.
+TEST SYNCHRONIZE now SIGNAL do_run WAIT_FOR phase1;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -101,18 +93,11 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "BACKUP DATABASE backup_progress%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT get_lock("bp_vp_state", 0);
-
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_vp_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "BACKUP DATABASE %";
---source include/wait_condition.inc
+--echo con1: Let backup do the backup phase1.
+TEST SYNCHRONIZE now SIGNAL backup WAIT_FOR validated;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -121,18 +106,11 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "BACKUP DATABASE backup_progress%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_running_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "BACKUP DATABASE %";
---source include/wait_condition.inc
+--echo con1: Let backup do the backup phase2.
+TEST SYNCHRONIZE now SIGNAL do_phase2 WAIT_FOR phase2;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -141,11 +119,11 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "BACKUP DATABASE backup_progress%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT release_lock("bp_running_state");
+--echo con1: Let backup finish.
+TEST SYNCHRONIZE now SIGNAL finish;
connection con2;
--echo con2: Finish backup command
@@ -162,22 +140,19 @@ connection con1;
--echo Do restore of database
-SELECT get_lock("bp_starting_state", 0);
-
connection con2;
DELETE FROM backup_progress.t1_res;
+--echo con2: Activate sync points for the backup statement.
+TEST SYNCHRONIZE before_backup_start_restore SIGNAL started WAIT_FOR do_run;
+TEST SYNCHRONIZE after_backup_start_restore SIGNAL running WAIT_FOR finish;
--echo con2: Send restore command.
send RESTORE FROM 'backup_progress_orig.bak';
connection con1;
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_starting_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
---source include/wait_condition.inc
+--echo con1: Wait for the restore to be started.
+TEST SYNCHRONIZE now WAIT_FOR started;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -186,20 +161,13 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
select * from backup_progress.t1_res;
INSERT INTO backup_progress.t1_res (id) SELECT backup_id FROM mysql.online_backup WHERE command LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT get_lock("bp_running_state", 0);
-
-# Wait for lock to be acquired and execution to reach breakpoint
---echo con1: Checking locks.
-let $wait_condition = SELECT state = "debug_sync_point: bp_running_state"
- FROM INFORMATION_SCHEMA.PROCESSLIST
- WHERE info LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
---source include/wait_condition.inc
+--echo con1: Let restore step to running state.
+TEST SYNCHRONIZE now SIGNAL do_run WAIT_FOR running;
# Wait for row to be written to progress table.
--echo con1: Checking progress.
@@ -208,11 +176,11 @@ let $wait_condition = SELECT backup_stat
WHERE command LIKE "RESTORE FROM 'backup_progress_orig.bak'%";
--source include/wait_condition.inc
---echo: Display progress
+--echo con1: Display progress
SELECT backup_state FROM mysql.online_backup AS ob JOIN backup_progress.t1_res as t1 ON ob.backup_id = t1.id;
---echo con1: Advance the lock.
-SELECT release_lock("bp_running_state");
+--echo con1: Let restore do its job and finish.
+TEST SYNCHRONIZE now SIGNAL finish;
connection con2;
--echo con2: Finish restore command
diff -Nrup a/mysql-test/t/merge.test b/mysql-test/t/merge.test
--- a/mysql-test/t/merge.test 2007-12-13 13:56:18 +01:00
+++ b/mysql-test/t/merge.test 2008-02-13 23:37:41 +01:00
@@ -2,7 +2,9 @@
# Test of MERGE TABLES
#
+# Clean up resources used in this test case.
--disable_warnings
+TEST SYNCHRONIZE RESET;
drop table if exists t1,t2,t3,t4,t5,t6;
drop database if exists mysqltest;
--enable_warnings
@@ -693,12 +695,6 @@ DROP TABLE t1, t2, t3, t4;
#
# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
-# Preparation
-connect (con1,localhost,root,,);
-connect (con2,localhost,root,,);
-connection default;
-#
-# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
# Problem #1
# A thread trying to lock a MERGE table performed busy waiting while
# REPAIR TABLE or a similar table administration task was ongoing on one or
@@ -720,12 +716,39 @@ connection default;
#
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
-send REPAIR TABLE t1;
+#
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # When reaching repair code, signal admin_flush and wait for end_repair.
+ TEST SYNCHRONIZE after_admin_flush SIGNAL admin_flush WAIT_FOR end_repair;
+ send REPAIR TABLE t1;
+#
+--echo connection default;
+connection default;
+# Wait that the other thread reaches repair.
+TEST SYNCHRONIZE NOW WAIT_FOR admin_flush;
+#
+# If the bug exists, INSERT will loop infinitely in getting its lock.
+# Bail out if lock retry is done 3 times.
+TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 3;
+# When the bug is fixed, we wait for refresh of repaired table.
+# In this case resume repair thread so that we do not deadlock.
+TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL end_repair;
+# Succeeds with bug fixed.
+INSERT INTO t2 VALUES (1);
+#
+# Resume the other thread. (non-bug fixed case)
+TEST SYNCHRONIZE NOW SIGNAL end_repair;
+#
+ --echo connection con1
connection con1;
- sleep 1; # let repair run into its sleep
- INSERT INTO t2 VALUES (1);
+ reap;
+ disconnect con1;
+#
+--echo connection default;
connection default;
-reap;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2;
#
# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
@@ -740,20 +763,39 @@ DROP TABLE t1, t2;
# This is the same test case as for
# Bug#26867 - LOCK TABLES + REPAIR + merge table result in memory/cpu hogging
#
-#
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
CREATE TABLE t2 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1) INSERT_METHOD= LAST;
LOCK TABLE t1 WRITE;
- connection con1;
+REPAIR TABLE t1;
+#
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # If the bug exists, the insert will loop infinitely in getting its lock.
+ # Bail out if lock retry is done 3 times.
+ TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 3;
+ # If the bug exists, resume repair thread after reaching the retry limit.
+ TEST SYNCHRONIZE after_insert SIGNAL end_repair;
+ # If the bug is fixed, we wait for refresh of repaired table.
+ # In this case resume repair thread so that we do not deadlock.
+ TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL end_repair;
send INSERT INTO t2 VALUES (1);
+#
+--echo connection default;
connection default;
-sleep 1; # Let INSERT go into thr_multi_lock().
-REPAIR TABLE t1;
-sleep 2; # con1 performs busy waiting during this sleep.
+# Wait for signal from insert. Would be infinite with bug and no retry limit.
+TEST SYNCHRONIZE NOW WAIT_FOR end_repair;
UNLOCK TABLES;
+#
+ --echo connection con1
connection con1;
+ # Succeeds with bug fixed.
reap;
+ disconnect con1;
+#
+--echo connection default;
connection default;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2;
#
# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
@@ -775,28 +817,54 @@ DROP TABLE t1, t2;
# FLUSH TABLES must happen while the INSERT was on its way from
# wait_for_tables() to the next call of thr_multi_lock(). This needed to be
# supported by a sleep to make it repeatable.
+# In >= 5.0, when waiting after open_tables() one FLUSH is sufficient
+# to allow the INSERT to step in.
#
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
LOCK TABLE t1 WRITE;
- connection con1;
+#
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # After open, wait for flush.
+ TEST SYNCHRONIZE before_lock_tables_takes_lock
+ SIGNAL opened WAIT_FOR flushed;
+ # If bug is fixed, INSERT will go into wait_for_lock.
+ # Retain action after use. First used by general_log.
+ TEST SYNCHRONIZE wait_for_lock SIGNAL locked EXECUTE 2;
+ # Alternatively INSERT can wait for refresh in open_table().
+ TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL locked;
+ # If bug is not fixed, INSERT will succeed. Pretend locked.
+ TEST SYNCHRONIZE after_insert SIGNAL locked;
send INSERT INTO t1 VALUES (1);
+#
+--echo connection default
connection default;
-sleep 1; # Let INSERT go into thr_multi_lock().
-FLUSH TABLES;
-sleep 1; # Let INSERT go through wait_for_tables() where it sleeps.
+# Wait until INSERT opened the table.
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+#
+# Let INSERT exploit the gap when flush waits wthout lock
+# for other threads to close the tables.
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
FLUSH TABLES;
-# This should give no result. But it will with sleep(2) at the right place.
+#
+# Wait until INSERT is locked (bug fixed) or finished (bug not fixed).
+TEST SYNCHRONIZE NOW WAIT_FOR locked;
+#
+# This should give no result. But it will if the bug exists.
SELECT * FROM t1;
UNLOCK TABLES;
+#
+ --echo connection con1
connection con1;
reap;
+ disconnect con1;
+#
+--echo connection default
connection default;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
DROP TABLE t1;
#
-# Bug#26379 - Combination of FLUSH TABLE and REPAIR TABLE corrupts a MERGE table
-# Cleanup
-disconnect con1;
-disconnect con2;
#
--echo #
--echo # Extra tests for Bug#26379 - Combination of FLUSH TABLE and
@@ -1122,6 +1190,7 @@ SELECT @a;
SELECT * FROM t4 ORDER BY c1;
DELETE FROM t4 WHERE c1 = 33;
DROP TRIGGER t3_ai;
+UNLOCK TABLES;
--echo #
--echo # Trigger with table use on child
DELETE FROM t4 WHERE c1 = 4;
@@ -1225,11 +1294,12 @@ DROP TABLE t1, t2, t3;
#
# Bug#25038 - Waiting TRUNCATE
+# Truncate failed with error message when table was in use by MERGE.
#
# Show that truncate of child table after use of parent table works.
-CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
-CREATE TABLE t2 (c1 INT) ENGINE= MyISAM;
-CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2);
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
INSERT INTO t1 VALUES (1);
INSERT INTO t2 VALUES (2);
SELECT * FROM t3;
@@ -1238,49 +1308,44 @@ SELECT * FROM t3;
DROP TABLE t1, t2, t3;
#
# Show that truncate of child table waits while parent table is used.
-# (test partly borrowed from count_distinct3.)
-CREATE TABLE t1 (id INTEGER, grp TINYINT, id_rev INTEGER);
-SET @rnd_max= 2147483647;
-let $1 = 10;
-while ($1)
-{
- SET @rnd= RAND();
- SET @id = CAST(@rnd * @rnd_max AS UNSIGNED);
- SET @id_rev= @rnd_max - @id;
- SET @grp= CAST(127.0 * @rnd AS UNSIGNED);
- INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
- dec $1;
-}
-set @@read_buffer_size=2*1024*1024;
-CREATE TABLE t2 SELECT * FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-CREATE TABLE t3 (id INTEGER, grp TINYINT, id_rev INTEGER)
- ENGINE= MRG_MYISAM UNION= (t1, t2);
-SELECT COUNT(*) FROM t1;
-SELECT COUNT(*) FROM t2;
-SELECT COUNT(*) FROM t3;
-connect (con1,localhost,root,,);
- # As t3 contains random numbers, results are different from test to test.
- # That's okay, because we test only that select doesn't yield an
- # error. Note, that --disable_result_log doesn't suppress error output.
- --disable_result_log
- send SELECT COUNT(DISTINCT a1.id) FROM t3 AS a1, t3 AS a2
- WHERE a1.id = a2.id GROUP BY a2.grp;
+CREATE TABLE t1 (c1 REAL) ENGINE=MyISAM;
+CREATE TABLE t2 (c1 REAL) ENGINE=MyISAM;
+INSERT INTO t1 VALUES(0.1);
+INSERT INTO t2 VALUES(0.2);
+CREATE TABLE t3 (c1 REAL) ENGINE=MRG_MYISAM UNION=(t1,t2);
+#
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # When reaching acos(), send 'select' and wait for truncated.
+ TEST SYNCHRONIZE before_acos_function SIGNAL 'select' WAIT_FOR truncated;
+ send SELECT ACOS(c1) FROM t3;
+#
+--echo connection default
connection default;
-sleep 1;
+# Wait for con1 to reach acos().
+TEST SYNCHRONIZE NOW WAIT_FOR 'select';
+#
+# With bug fix present, TRUNCATE runs into wait_for_locked_table_names().
+TEST SYNCHRONIZE before_wait_locked_tname SIGNAL truncated;
TRUNCATE TABLE t1;
+#
+# With bug fix not present, we need to signal after TRUNCATE.
+TEST SYNCHRONIZE NOW SIGNAL truncated;
+#
+ --echo connection con1
connection con1;
+ # In non-debug server, the order of select and truncate is undetermined.
+ # So we may have one or two rows here.
+ --disable_result_log
reap;
--enable_result_log
disconnect con1;
+#
+--echo connection default
connection default;
-SELECT COUNT(*) FROM t1;
-SELECT COUNT(*) FROM t2;
-SELECT COUNT(*) FROM t3;
+SELECT ACOS(c1) FROM t3;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
DROP TABLE t1, t2, t3;
#
@@ -1380,4 +1445,170 @@ OPTIMIZE TABLE t1;
FLUSH TABLES m1, t1;
UNLOCK TABLES;
DROP TABLE t1, m1;
+#
+# In-depth test.
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # Wait for flush before attaching children.
+ TEST SYNCHRONIZE before_myisammrg_attach SIGNAL attach WAIT_FOR flushed;
+ send INSERT INTO m1 VALUES (2);
+--echo connection default;
+connection default;
+#
+# Wait for con1 to reach attach_merge_children(), then flush and signal.
+TEST SYNCHRONIZE NOW WAIT_FOR attach;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
+FLUSH TABLE m1;
+#
+ --echo connection con1
+ connection con1;
+ reap;
+ disconnect con1;
+--echo connection default;
+connection default;
+SELECT * FROM m1;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
+DROP TABLE m1, t1;
+#
+# Test derived from test program for
+# Bug#30273 - merge tables: Can't lock file (errno: 155)
+# Second test try to step in between lock_count() and store_lock().
+#
+CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
+CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1) INSERT_METHOD=LAST;
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ # When reaching attach_merge_children(), signal attach and
+ # wait for store_lock1 before attaching children.
+ # Then run through attach of children until store_lock().
+ # Signal store_lock2 and wait for flushed.
+ TEST SYNCHRONIZE before_myisammrg_attach SIGNAL attach WAIT_FOR store_lock1;
+ TEST SYNCHRONIZE before_myisammrg_store_lock
+ SIGNAL store_lock2 WAIT_FOR flushed;
+ send INSERT INTO m1 VALUES (2);
+--echo connection default;
+connection default;
+#
+# Wait for con1 to reach attach.
+TEST SYNCHRONIZE NOW WAIT_FOR attach;
+# Run until myisammrg store_lock(),
+# then signal store_lock1 and
+# wait for con1 to go through attach until store_lock() (store_lock2),
+# then flush and signal flushed.
+TEST SYNCHRONIZE before_myisammrg_store_lock
+ SIGNAL store_lock1 WAIT_FOR store_lock2;
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
+FLUSH TABLE m1;
+#
+ --echo connection con1
+ connection con1;
+ reap;
+ disconnect con1;
+--echo connection default;
+connection default;
+SELECT * FROM m1;
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
+DROP TABLE m1, t1;
+
+#
+# Coverage test for get_user_var().
+# Same test as for Bug#26379, Problem #3.
+# But mysql_test_sync_lock_retry_limit set to null.
+#
+#CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+#LOCK TABLE t1 WRITE;
+# --echo connection con1
+# connect (con1,localhost,root,,);
+# # Set a null integer value.
+# SET @mysql_test_sync_lock_retry_limit= NULL;
+# TEST SYNCHRONIZE before_lock_tables_takes_lock
+# SIGNAL opened WAIT_FOR flushed;
+# TEST SYNCHRONIZE wait_for_lock SIGNAL locked EXECUTE 2;
+# TEST SYNCHRONIZE after_insert SIGNAL locked;
+# send INSERT INTO t1 VALUES (1);
+#--echo connection default;
+#connection default;
+#TEST SYNCHRONIZE NOW WAIT_FOR opened;
+#TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed;
+#FLUSH TABLES;
+#TEST SYNCHRONIZE NOW WAIT_FOR locked;
+#UNLOCK TABLES;
+# --echo connection con1
+# connection con1;
+# reap;
+# disconnect con1;
+#--echo connection default;
+#connection default;
+# Clear test_sync signal.
+#TEST SYNCHRONIZE RESET;
+#DROP TABLE t1;
+#
+# Coverage test for mysql_lock_retry_limit().
+# Similar test as for Bug#26379, Problem #3.
+# But mysql_lock_retry limit set to 2 and FLUSH repeated
+# so that the INSERT results in ER_LOCK_WAIT_TIMEOUT.
+#
+CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
+LOCK TABLE t1 WRITE;
+#
+ --echo connection con1
+ connect (con1,localhost,root,,);
+ TEST SYNCHRONIZE mysql_lock_retry HIT_LIMIT 2;
+ # After open, wait for flush.
+ TEST SYNCHRONIZE before_lock_tables_takes_lock
+ SIGNAL opened WAIT_FOR flushed EXECUTE 2;
+ # If bug is fixed, INSERT will go into wait_for_lock.
+ # Retain action after use. First used by general_log.
+ TEST SYNCHRONIZE wait_for_lock SIGNAL locked EXECUTE 4;
+ # Alternatively INSERT can wait for refresh in open_table().
+ TEST SYNCHRONIZE before_open_table_wait_refresh SIGNAL refresh EXECUTE 2;
+ # If bug is not fixed, INSERT will succeed. Pretend locked.
+ TEST SYNCHRONIZE after_insert SIGNAL locked EXECUTE 2;
+ #SET debug='+d,test_sync_point,test_sync_exec:+i';
+ send INSERT INTO t1 VALUES (1);
+#
+--echo connection default;
+connection default;
+#SET debug='+d,test_sync_point,test_sync_exec:+i';
+#
+# Wait until INSERT opened the table.
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+#
+# Let INSERT exploit the gap when flush waits wthout lock
+# for other threads to close the tables.
+TEST SYNCHRONIZE after_flush_unlock SIGNAL flushed EXECUTE 2;
+FLUSH TABLES;
+#
+# Wait until INSERT waits for refresh.
+# Then we need to close and reopen the table to let it succed another open.
+TEST SYNCHRONIZE NOW WAIT_FOR refresh;
+UNLOCK TABLES;
+LOCK TABLE t1 WRITE;
+#
+# Wait until INSERT opened the table the second time.
+# Then flush the second time.
+TEST SYNCHRONIZE NOW WAIT_FOR opened;
+FLUSH TABLES;
+#
+# Wait until INSERT is locked (bug fixed) or finished (bug not fixed).
+TEST SYNCHRONIZE NOW WAIT_FOR locked;
+UNLOCK TABLES;
+#
+ --echo connection con1
+ connection con1;
+ # Succeeds if TEST SYNCHRONIZE is disabled
+ --error 0, ER_LOCK_WAIT_TIMEOUT
+ reap;
+ disconnect con1;
+#
+--echo connection default;
+connection default;
+#
+# Clear test_sync signal.
+TEST SYNCHRONIZE RESET;
+DROP TABLE t1;
diff -Nrup a/mysys/thr_lock.c b/mysys/thr_lock.c
--- a/mysys/thr_lock.c 2008-01-28 13:52:34 +01:00
+++ b/mysys/thr_lock.c 2008-02-13 23:37:41 +01:00
@@ -386,6 +386,12 @@ static inline my_bool have_specific_lock
static void wake_up_waiters(THR_LOCK *lock);
+/**
+ Global pointer to be set if callback function is defined
+ (e.g. in mysqld). See mysql_test_sync.cc.
+*/
+void (*test_sync_wait_for_lock_callback_ptr)(void);
+
static enum enum_thr_lock_result
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
@@ -397,6 +403,13 @@ wait_for_lock(struct st_lock_list *wait,
enum enum_thr_lock_result result= THR_LOCK_ABORTED;
my_bool can_deadlock= test(data->owner->info->n_cursors);
DBUG_ENTER("wait_for_lock");
+
+ /*
+ One can use this to signal when a thread is going to wait for a lock.
+ See mysql_test_sync.cc.
+ */
+ if (test_sync_wait_for_lock_callback_ptr)
+ (*test_sync_wait_for_lock_callback_ptr)();
if (!in_wait_list)
{
diff -Nrup a/sql/CMakeLists.txt b/sql/CMakeLists.txt
--- a/sql/CMakeLists.txt 2008-02-08 21:44:29 +01:00
+++ b/sql/CMakeLists.txt 2008-02-13 23:37:41 +01:00
@@ -78,6 +78,7 @@ ADD_EXECUTABLE(mysqld
sql_connect.cc scheduler.cc
ddl_blocker.cc si_objects.cc
sql_profile.cc
+ mysql_test_sync.cc mysql_test_sync.h
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
diff -Nrup a/sql/Makefile.am b/sql/Makefile.am
--- a/sql/Makefile.am 2008-02-08 21:44:55 +01:00
+++ b/sql/Makefile.am 2008-02-13 23:37:41 +01:00
@@ -87,6 +87,7 @@ noinst_HEADERS = item.h item_func.h item
event_data_objects.h event_scheduler.h \
sql_partition.h partition_info.h partition_element.h \
probes.h \
+ mysql_test_sync.h \
contributors.h sql_servers.h ddl_blocker.h si_objects.h
mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
@@ -132,6 +133,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.
sql_plugin.cc sql_binlog.cc \
sql_builtin.cc sql_tablespace.cc partition_info.cc \
sql_servers.cc sha2.cc \
+ mysql_test_sync.cc \
ddl_blocker.cc si_objects.cc
if HAVE_DTRACE
diff -Nrup a/sql/backup/data_backup.cc b/sql/backup/data_backup.cc
--- a/sql/backup/data_backup.cc 2007-12-13 15:08:42 +01:00
+++ b/sql/backup/data_backup.cc 2008-02-13 23:37:42 +01:00
@@ -653,10 +653,12 @@ int write_table_data(THD* thd, Backup_in
timing of the validity point.
*/
BACKUP_BREAKPOINT("bp_vp_state");
+ TEST_SYNCHRONIZE(thd, after_backup_validated);
info.save_vp_time(vp_time);
report_ob_vp_time(info.backup_prog_id, vp_time);
report_ob_state(info.backup_prog_id, BUP_RUNNING);
BACKUP_BREAKPOINT("bp_running_state");
+ TEST_SYNCHRONIZE(thd, before_backup_binlog);
if (mysql_bin_log.is_open())
report_ob_binlog_info(info.backup_prog_id,
diff -Nrup a/sql/backup/kernel.cc b/sql/backup/kernel.cc
--- a/sql/backup/kernel.cc 2008-02-12 01:17:51 +01:00
+++ b/sql/backup/kernel.cc 2008-02-13 23:37:42 +01:00
@@ -168,6 +168,7 @@ execute_backup_command(THD *thd, LEX *le
0, "", lex->backup_dir.str, thd->query);
report_ob_time(backup_prog_id, start, 0);
BACKUP_BREAKPOINT("bp_starting_state");
+ TEST_SYNCHRONIZE(thd, before_backup_start_restore);
Restore_info info(thd,*stream);
@@ -184,6 +185,7 @@ execute_backup_command(THD *thd, LEX *le
report_ob_state(backup_prog_id, BUP_RUNNING);
BACKUP_BREAKPOINT("bp_running_state");
+ TEST_SYNCHRONIZE(thd, after_backup_start_restore);
/*
Freeze all DDL operations by turning on DDL blocker.
@@ -287,6 +289,7 @@ execute_backup_command(THD *thd, LEX *le
0, "", lex->backup_dir.str, thd->query);
report_ob_time(backup_prog_id, start, 0);
BACKUP_BREAKPOINT("bp_starting_state");
+ TEST_SYNCHRONIZE(thd, before_backup_start_backup);
info.backup_prog_id= backup_prog_id;
@@ -297,6 +300,7 @@ execute_backup_command(THD *thd, LEX *le
info.save_start_time(start);
report_ob_state(backup_prog_id, BUP_RUNNING);
BACKUP_BREAKPOINT("bp_running_state");
+ TEST_SYNCHRONIZE(thd, after_backup_start_backup);
info.save_errors();
diff -Nrup a/sql/item_func.cc b/sql/item_func.cc
--- a/sql/item_func.cc 2008-02-08 21:45:30 +01:00
+++ b/sql/item_func.cc 2008-02-13 23:37:42 +01:00
@@ -1689,6 +1689,8 @@ double Item_func_pow::val_real()
double Item_func_acos::val_real()
{
DBUG_ASSERT(fixed == 1);
+ /* One can use this to defer SELECT processing. */
+ TEST_SYNCHRONIZE(current_thd, before_acos_function);
// the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
volatile double value= args[0]->val_real();
if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
diff -Nrup a/sql/lex.h b/sql/lex.h
--- a/sql/lex.h 2008-02-08 21:22:28 +01:00
+++ b/sql/lex.h 2008-02-13 23:37:42 +01:00
@@ -105,6 +105,7 @@ static SYMBOL symbols[] = {
{ "CHECK", SYM(CHECK_SYM)},
{ "CHECKSUM", SYM(CHECKSUM_SYM)},
{ "CIPHER", SYM(CIPHER_SYM)},
+ { "CLEAR", SYM(CLEAR_SYM)},
{ "CLIENT", SYM(CLIENT_SYM)},
{ "CLOSE", SYM(CLOSE_SYM)},
{ "COALESCE", SYM(COALESCE)},
@@ -234,6 +235,7 @@ static SYMBOL symbols[] = {
{ "HAVING", SYM(HAVING)},
{ "HELP", SYM(HELP_SYM)},
{ "HIGH_PRIORITY", SYM(HIGH_PRIORITY)},
+ { "HIT_LIMIT", SYM(HIT_LIMIT_SYM)},
{ "HOST", SYM(HOST_SYM)},
{ "HOSTS", SYM(HOSTS_SYM)},
{ "HOUR", SYM(HOUR_SYM)},
@@ -478,6 +480,7 @@ static SYMBOL symbols[] = {
{ "SHARE", SYM(SHARE_SYM)},
{ "SHOW", SYM(SHOW)},
{ "SHUTDOWN", SYM(SHUTDOWN)},
+ { "SIGNAL", SYM(SIGNAL_SYM)},
{ "SIGNED", SYM(SIGNED_SYM)},
{ "SIMPLE", SYM(SIMPLE_SYM)},
{ "SLAVE", SYM(SLAVE)},
@@ -526,16 +529,19 @@ static SYMBOL symbols[] = {
{ "SUSPEND", SYM(SUSPEND_SYM)},
{ "SWAPS", SYM(SWAPS_SYM)},
{ "SWITCHES", SYM(SWITCHES_SYM)},
+ { "SYNCHRONIZE", SYM(SYNCHRONIZE_SYM)},
{ "TABLE", SYM(TABLE_SYM)},
{ "TABLES", SYM(TABLES)},
{ "TABLESPACE", SYM(TABLESPACE)},
{ "TEMPORARY", SYM(TEMPORARY)},
{ "TEMPTABLE", SYM(TEMPTABLE_SYM)},
{ "TERMINATED", SYM(TERMINATED)},
+ { "TEST", SYM(TEST_SYM)},
{ "TEXT", SYM(TEXT_SYM)},
{ "THAN", SYM(THAN_SYM)},
{ "THEN", SYM(THEN_SYM)},
{ "TIME", SYM(TIME_SYM)},
+ { "TIMEOUT", SYM(TIMEOUT_SYM)},
{ "TIMESTAMP", SYM(TIMESTAMP)},
{ "TIMESTAMPADD", SYM(TIMESTAMP_ADD)},
{ "TIMESTAMPDIFF", SYM(TIMESTAMP_DIFF)},
@@ -582,6 +588,7 @@ static SYMBOL symbols[] = {
{ "VARCHARACTER", SYM(VARCHAR)},
{ "VARIABLES", SYM(VARIABLES)},
{ "VARYING", SYM(VARYING)},
+ { "WAIT_FOR", SYM(WAIT_FOR_SYM)},
{ "WAIT", SYM(WAIT_SYM)},
{ "WARNINGS", SYM(WARNINGS)},
{ "WEEK", SYM(WEEK_SYM)},
diff -Nrup a/sql/lock.cc b/sql/lock.cc
--- a/sql/lock.cc 2007-12-21 20:27:43 +01:00
+++ b/sql/lock.cc 2008-02-13 23:37:42 +01:00
@@ -351,6 +351,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,
*/
reset_lock_data_and_free(&sql_lock);
retry:
+ TEST_SYNCHRONIZE(thd, mysql_lock_retry);
if (flags & MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN)
{
*need_reopen= TRUE;
@@ -1112,6 +1113,7 @@ bool wait_for_locked_table_names(THD *th
result=1;
break;
}
+ TEST_SYNCHRONIZE(thd, before_wait_locked_tname);
wait_for_condition(thd, &LOCK_open, &COND_refresh);
pthread_mutex_lock(&LOCK_open);
}
diff -Nrup a/sql/mysqld.cc b/sql/mysqld.cc
--- a/sql/mysqld.cc 2008-02-12 01:17:49 +01:00
+++ b/sql/mysqld.cc 2008-02-13 23:37:42 +01:00
@@ -495,6 +495,7 @@ uint mysqld_port_timeout;
uint delay_key_write_options, protocol_version;
uint lower_case_table_names;
uint tc_heuristic_recover= 0;
+uint opt_test_synchronize= 0;
uint volatile thread_count, thread_running;
ulonglong thd_startup_options;
ulong back_log, connect_timeout, concurrency, server_id;
@@ -1336,6 +1337,8 @@ void clean_up(bool print_message)
#ifdef USE_REGEX
my_regex_end();
#endif
+ /* End the test synchronization facility. See mysql_test_sync.cc */
+ test_sync_end();
#if !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
@@ -3015,6 +3018,7 @@ SHOW_VAR com_status_vars[]= {
{"stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
{"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
{"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
+ {"test_synchronize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TEST_SYNC]), SHOW_LONG_STATUS},
{"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
{"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
{"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
@@ -3310,6 +3314,10 @@ static int init_common_variables(const c
sys_var_slow_log_path.value= my_strdup(s, MYF(0));
sys_var_slow_log_path.value_length= strlen(s);
+ /* Initialize the test synchronization facility. See mysql_test_sync.cc */
+ if (opt_test_synchronize && test_sync_init())
+ return 1; /* purecov: tested */
+
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1;
if (my_database_names_init())
@@ -5427,7 +5435,8 @@ enum options_mysqld
#if HAVE_POOL_OF_THREADS == 1
OPT_POOL_OF_THREADS,
#endif
- OPT_SLAVE_EXEC_MODE
+ OPT_SLAVE_EXEC_MODE,
+ OPT_TEST_SYNCHRONIZE
};
@@ -6170,6 +6179,12 @@ log and this option does nothing anymore
"Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
(uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"test-synchronize", OPT_TEST_SYNCHRONIZE,
+ "Enable the TEST SYNCHRONIZE facility "
+ "and optionally specify a default wait timeout in seconds. "
+ "A zero value keeps the facility disabled.",
+ (uchar**) &opt_test_synchronize, 0,
+ 0, GET_INT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
{"temp-pool", OPT_TEMP_POOL,
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
(uchar**) &use_temp_pool, (uchar**) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
@@ -7326,6 +7341,7 @@ static void mysql_init_variables(void)
bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
bzero((char *) &global_status_var, sizeof(global_status_var));
opt_large_pages= 0;
+ opt_test_synchronize= 0;
key_map_full.set_all();
/* Character sets */
@@ -7983,6 +7999,16 @@ mysqld_get_one_option(int optid,
case OPT_LOWER_CASE_TABLE_NAMES:
lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
+ break;
+ case OPT_TEST_SYNCHRONIZE:
+ /*
+ Test Synchronization Facility. See mysql_test_sync.cc.
+ Default value is zero (facility disabled).
+ If option is given without an argument, supply a non-zero value.
+ Default timeout for WAIT_FOR action.
+ */
+ if (!argument)
+ opt_test_synchronize= 300; /* purecov: tested */
break;
}
return 0;
diff -Nrup a/sql/sql_base.cc b/sql/sql_base.cc
--- a/sql/sql_base.cc 2008-02-02 13:19:47 +01:00
+++ b/sql/sql_base.cc 2008-02-13 23:37:42 +01:00
@@ -1021,6 +1021,8 @@ bool close_cached_tables(THD *thd, TABLE
close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd);
+ TEST_SYNCHRONIZE(thd, after_flush_unlock);
+
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT("info",
@@ -2898,6 +2900,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *
*/
if (table->in_use != thd)
{
+ TEST_SYNCHRONIZE(thd, before_open_table_wait_refresh);
+
/* wait_for_conditionwill unlock LOCK_open for us */
wait_for_condition(thd, &LOCK_open, &COND_refresh);
}
@@ -5170,6 +5174,8 @@ int lock_tables(THD *thd, TABLE_LIST *ta
thd->set_current_stmt_binlog_row_based_if_mixed();
}
}
+
+ TEST_SYNCHRONIZE(thd, before_lock_tables_takes_lock);
if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
lock_flag, need_reopen)))
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc 2008-02-11 22:22:12 +01:00
+++ b/sql/sql_class.cc 2008-02-13 23:37:42 +01:00
@@ -507,7 +507,8 @@ THD::THD()
This is needed to ensure the restore (which uses DDL) is not blocked
when the DDL blocker is engaged.
*/
- DDL_exception(FALSE)
+ DDL_exception(FALSE),
+ test_sync_action(0)
{
ulong tmp;
@@ -734,6 +735,9 @@ void THD::init(void)
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
+
+ /* Initialize the test synchronization facility. See mysql_test_sync.cc */
+ test_sync_init_thread(this);
}
@@ -809,6 +813,10 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
+
+ /* End the test synchronization facility. See mysql_test_sync.cc */
+ test_sync_end_thread(this);
+
mysql_ha_cleanup(this);
delete_dynamic(&user_var_events);
hash_free(&user_vars);
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h 2008-02-08 21:22:30 +01:00
+++ b/sql/sql_class.h 2008-02-13 23:37:42 +01:00
@@ -242,6 +242,7 @@ struct Query_cache_tls
Query_cache_tls() :first_query_block(NULL) {}
};
+#include "mysql_test_sync.h"
#include "sql_lex.h" /* Must be here */
class Delayed_insert;
@@ -1748,6 +1749,12 @@ public:
#ifdef WITH_PARTITION_STORAGE_ENGINE
partition_info *work_part_info;
#endif
+
+ /*
+ Pointer to array of TEST SYNCHRONIZE actions.
+ There is one array slot per synchronization point.
+ */
+ struct st_test_sync_action *test_sync_action;
THD();
~THD();
diff -Nrup a/sql/sql_lex.h b/sql/sql_lex.h
--- a/sql/sql_lex.h 2008-02-12 01:17:50 +01:00
+++ b/sql/sql_lex.h 2008-02-13 23:37:42 +01:00
@@ -123,10 +123,11 @@ enum enum_sql_command {
SQLCOM_BACKUP_TEST,
#endif
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
+ SQLCOM_TEST_SYNC,
/*
When a command is added here, be sure it's also added in mysqld.cc
- in "struct show_var_st status_vars[]= {" ...
+ in "struct show_var_st com_status_vars[]= {" ...
*/
/* This should be the last !!! */
SQLCOM_END
@@ -1733,6 +1734,8 @@ typedef struct st_lex : public Query_tab
bool escape_used;
bool is_lex_started; /* If lex_start() did run. For debugging. */
+
+ struct st_test_sync_request test_sync_req;
st_lex();
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc 2008-02-11 22:22:13 +01:00
+++ b/sql/sql_parse.cc 2008-02-13 23:37:42 +01:00
@@ -2875,6 +2875,7 @@ end_with_restore_list:
thd->first_successful_insert_id_in_cur_stmt=
thd->first_successful_insert_id_in_prev_stmt;
+ TEST_SYNCHRONIZE(thd, after_insert);
break;
}
case SQLCOM_REPLACE_SELECT:
@@ -4637,6 +4638,20 @@ create_sp_error:
break;
}
send_ok(thd, 1);
+ break;
+ }
+ case SQLCOM_TEST_SYNC:
+ {
+ LEX *lex= thd->lex;
+ DBUG_PRINT("info", ("case SQLCOM_TEST_SYNC"));
+
+ if (check_global_access(thd, SUPER_ACL))
+ break;
+
+ if (lex->test_sync_req.command == action )
+ VOID(test_sync_set_action(thd, &lex->test_sync_req));
+ else
+ VOID(test_sync_do_command(thd, &lex->test_sync_req));
break;
}
default:
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc 2008-02-02 13:19:48 +01:00
+++ b/sql/sql_table.cc 2008-02-13 23:37:42 +01:00
@@ -4170,6 +4170,7 @@ static bool mysql_admin_table(THD* thd,
RTFC_WAIT_OTHER_THREAD_FLAG |
RTFC_CHECK_KILLED_FLAG);
thd->exit_cond(old_message);
+ TEST_SYNCHRONIZE(thd, after_admin_flush);
DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
if (thd->killed)
goto err;
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy 2008-02-08 21:22:33 +01:00
+++ b/sql/sql_yacc.yy 2008-02-13 23:37:42 +01:00
@@ -593,6 +593,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token CHECKSUM_SYM
%token CHECK_SYM /* SQL-2003-R */
%token CIPHER_SYM
+%token CLEAR_SYM
%token CLIENT_SYM
%token CLOSE_SYM /* SQL-2003-R */
%token COALESCE /* SQL-2003-N */
@@ -728,6 +729,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token HELP_SYM
%token HEX_NUM
%token HIGH_PRIORITY
+%token HIT_LIMIT_SYM
%token HOST_SYM
%token HOSTS_SYM
%token HOUR_MICROSECOND_SYM
@@ -982,6 +984,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token SHIFT_RIGHT /* OPERATOR */
%token SHOW
%token SHUTDOWN
+%token SIGNAL_SYM
%token SIGNED_SYM
%token SIMPLE_SYM /* SQL-2003-N */
%token SLAVE
@@ -1025,6 +1028,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token SUSPEND_SYM
%token SWAPS_SYM
%token SWITCHES_SYM
+%token SYNCHRONIZE_SYM
%token SYSDATE
%token TABLES
%token TABLESPACE
@@ -1033,10 +1037,12 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token TEMPORARY /* SQL-2003-N */
%token TEMPTABLE_SYM
%token TERMINATED
+%token TEST_SYM
%token TEXT_STRING
%token TEXT_SYM
%token THAN_SYM
%token THEN_SYM /* SQL-2003-R */
+%token TIMEOUT_SYM
%token TIMESTAMP /* SQL-2003-R */
%token TIMESTAMP_ADD
%token TIMESTAMP_DIFF
@@ -1090,6 +1096,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
%token VARYING /* SQL-2003-R */
%token VAR_SAMP_SYM
%token VIEW_SYM /* SQL-2003-N */
+%token WAIT_FOR_SYM
%token WAIT_SYM
%token WARNINGS
%token WEEK_SYM
@@ -1316,6 +1323,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
init_key_options key_options key_opts key_opt key_using_alg
server_def server_options_list server_option
definer_opt no_definer definer
+ test_stmt TEST_SYM test_statement SYNCHRONIZE_SYM
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1434,6 +1442,7 @@ statement:
| show
| slave
| start
+ | test_stmt
| truncate
| uninstall
| unlock
@@ -10588,6 +10597,7 @@ keyword:
| SONAME_SYM {}
| START_SYM {}
| STOP_SYM {}
+ | TEST_SYM {}
| TRUNCATE_SYM {}
| UNICODE_SYM {}
| UNINSTALL_SYM {}
@@ -10626,6 +10636,7 @@ keyword_sp:
| CHAIN_SYM {}
| CHANGED {}
| CIPHER_SYM {}
+ | CLEAR_SYM {}
| CLIENT_SYM {}
| COALESCE {}
| CODE_SYM {}
@@ -10686,6 +10697,7 @@ keyword_sp:
| GRANTS {}
| GLOBAL_SYM {}
| HASH_SYM {}
+ | HIT_LIMIT_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
@@ -10814,6 +10826,7 @@ keyword_sp:
| SIMPLE_SYM {}
| SHARE_SYM {}
| SHUTDOWN {}
+ | SIGNAL_SYM {}
| SNAPSHOT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
@@ -10833,6 +10846,7 @@ keyword_sp:
| SUSPEND_SYM {}
| SWAPS_SYM {}
| SWITCHES_SYM {}
+ | SYNCHRONIZE_SYM {}
| TABLES {}
| TABLESPACE {}
| TEMPORARY {}
@@ -10842,6 +10856,7 @@ keyword_sp:
| TRANSACTION_SYM {}
| TRANSACTIONAL_SYM {}
| TRIGGERS_SYM {}
+ | TIMEOUT_SYM {}
| TIMESTAMP {}
| TIMESTAMP_ADD {}
| TIMESTAMP_DIFF {}
@@ -10862,6 +10877,7 @@ keyword_sp:
| VIEW_SYM {}
| VALUE_SYM {}
| WARNINGS {}
+ | WAIT_FOR_SYM {}
| WAIT_SYM {}
| WEEK_SYM {}
| WEIGHT_STRING_SYM {}
@@ -12779,6 +12795,97 @@ uninstall:
LEX *lex= Lex;
lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
lex->comment= $3;
+ }
+ ;
+
+test_stmt:
+ TEST_SYM test_statement
+ ;
+
+test_statement:
+ SYNCHRONIZE_SYM
+ {
+ Lex->sql_command= SQLCOM_TEST_SYNC;
+ Lex->test_sync_req.command= action;
+ Lex->test_sync_req.hit_limit= 0;
+ Lex->test_sync_req.execute= 0;
+ Lex->test_sync_req.timeout= opt_test_synchronize;
+ Lex->test_sync_req.signal.length= 0;
+ Lex->test_sync_req.wait_for.length= 0;
+ Lex->test_sync_req.sync_point.length= 0;
+ }
+ test_sync_stmt
+ ;
+
+test_sync_stmt:
+ ident_or_text test_sync_action
+ {
+ Lex->test_sync_req.sync_point= $1;
+ }
+ | RESET_SYM
+ {
+ Lex->test_sync_req.command= reset;
+ }
+ | SHOW STATUS_SYM
+ {
+ Lex->test_sync_req.command= show_status;
+ }
+ | SHOW ACTION
+ {
+ Lex->test_sync_req.command= show_action;
+ }
+ ;
+
+test_sync_action:
+ test_sync_signal_wait test_sync_execute
+ | test_sync_signal_wait test_sync_execute test_sync_limit
+ | test_sync_limit
+ | CLEAR_SYM /* hit_limit= 0 and execute= 0 */
+ | TEST_SYM
+ {
+ Lex->test_sync_req.command= test;
+ }
+ ;
+
+test_sync_signal_wait:
+ SIGNAL_SYM ident_or_text
+ {
+ Lex->test_sync_req.signal= $2;
+ }
+ | SIGNAL_SYM ident_or_text WAIT_FOR_SYM ident_or_text test_sync_timeout
+ {
+ Lex->test_sync_req.signal= $2;
+ Lex->test_sync_req.wait_for= $4;
+ }
+ | WAIT_FOR_SYM ident_or_text test_sync_timeout
+ {
+ Lex->test_sync_req.wait_for= $2;
+ }
+ ;
+
+test_sync_timeout:
+ /* empty */
+ | TIMEOUT_SYM opt_equal real_ulong_num
+ {
+ Lex->test_sync_req.timeout= $3;
+ }
+ ;
+
+test_sync_execute:
+ /* empty */
+ {
+ Lex->test_sync_req.execute= 1;
+ }
+ | EXECUTE_SYM opt_equal real_ulong_num
+ {
+ Lex->test_sync_req.execute= $3;
+ }
+ ;
+
+test_sync_limit:
+ HIT_LIMIT_SYM opt_equal real_ulong_num
+ {
+ Lex->test_sync_req.hit_limit= $3;
}
;
diff -Nrup a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
--- a/storage/myisammrg/ha_myisammrg.cc 2007-12-21 20:27:49 +01:00
+++ b/storage/myisammrg/ha_myisammrg.cc 2008-02-13 23:37:42 +01:00
@@ -456,6 +456,8 @@ int ha_myisammrg::attach_children(void)
DBUG_PRINT("myrg", ("test_if_locked: %u", this->test_if_locked));
DBUG_ASSERT(!this->file->children_attached);
+ TEST_SYNCHRONIZE(current_thd, before_myisammrg_attach);
+
/*
Initialize variables that are used, modified, and/or set by
myisammrg_attach_children_callback().
@@ -925,6 +927,8 @@ THR_LOCK_DATA **ha_myisammrg::store_lock
enum thr_lock_type lock_type)
{
MYRG_TABLE *open_table;
+
+ TEST_SYNCHRONIZE(thd, before_myisammrg_store_lock);
/*
This method can be called while another thread is attaching the
| Thread |
|---|
| • bk commit into 6.0 tree (istruewing:1.2553) | Ingo Struewing | 13 Feb |