List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:June 22 2009 12:31pm
Subject:bzr commit into mysql-pe branch (joro:3387)
View as plain text  
#At file:///Users/kgeorge/mysql/work/merge-pe/ based on revid:joro@strippedwfqojcuqe8

 3387 Georgi Kodinov	2009-06-22 [merge]
      automerge

    added:
      mysql-test/include/have_semisync_plugin.inc
      mysql-test/suite/rpl/r/rpl_semi_sync.result
      mysql-test/suite/rpl/t/rpl_semi_sync-master.opt
      mysql-test/suite/rpl/t/rpl_semi_sync-slave.opt
      mysql-test/suite/rpl/t/rpl_semi_sync.test
      plugin/semisync/
      plugin/semisync/Makefile.am
      plugin/semisync/configure.in
      plugin/semisync/plug.in
      plugin/semisync/semisync.cc
      plugin/semisync/semisync.h
      plugin/semisync/semisync_master.cc
      plugin/semisync/semisync_master.h
      plugin/semisync/semisync_master_plugin.cc
      plugin/semisync/semisync_slave.cc
      plugin/semisync/semisync_slave.h
      plugin/semisync/semisync_slave_plugin.cc
    renamed:
      mysql-test/include/have_community_features.inc => mysql-test/include/have_profiling.inc
      mysql-test/r/have_community_features.require => mysql-test/r/have_profiling.require
    modified:
      configure.in
      include/config-win.h
      mysql-test/extra/rpl_tests/rpl_row_sp006.test
      mysql-test/mysql-test-run.pl
      mysql-test/r/create.result
      mysql-test/r/events_bugs.result
      mysql-test/r/grant.result
      mysql-test/r/information_schema_routines.result
      mysql-test/r/innodb.result
      mysql-test/r/innodb_mrr.result
      mysql-test/r/mysqldump.result
      mysql-test/r/show_check.result
      mysql-test/r/sp.result
      mysql-test/r/sql_mode.result
      mysql-test/r/strict.result
      mysql-test/r/subselect_sj2_jcl6.result
      mysql-test/r/system_mysql_db.result
      mysql-test/r/trigger.result
      mysql-test/suite/backup/r/backup_check_i_s.result
      mysql-test/suite/backup/r/backup_functions.result
      mysql-test/suite/binlog/r/binlog_tmp_table.result
      mysql-test/suite/binlog/t/binlog_tmp_table.test
      mysql-test/suite/funcs_1/r/innodb_storedproc_07.result
      mysql-test/suite/funcs_1/r/is_columns_is.result
      mysql-test/suite/funcs_1/r/is_columns_mysql.result
      mysql-test/suite/funcs_1/r/is_routines.result
      mysql-test/suite/funcs_1/r/memory_storedproc_07.result
      mysql-test/suite/funcs_1/r/myisam_storedproc_07.result
      mysql-test/suite/funcs_1/r/ndb_storedproc_07.result
      mysql-test/suite/funcs_1/r/storedproc.result
      mysql-test/suite/rpl/r/rpl_heartbeat.result
      mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
      mysql-test/suite/rpl/t/rpl000017.test
      mysql-test/suite/rpl/t/rpl_heartbeat.test
      mysql-test/t/create.test
      mysql-test/t/ctype_utf8.test
      mysql-test/t/grant.test
      mysql-test/t/profiling.test
      mysql-test/t/sp.test
      mysql-test/t/sql_mode.test
      mysql-test/t/trigger.test
      mysql-test/t/variables+c.test
      scripts/mysql_system_tables.sql
      scripts/mysql_system_tables_fix.sql
      sql/log.cc
      sql/log.h
      sql/mysql_priv.h
      sql/mysqld.cc
      sql/rpl_handler.cc
      sql/set_var.cc
      sql/slave.cc
      sql/sql_base.cc
      sql/sql_insert.cc
      sql/sql_parse.cc
      sql/sql_repl.cc
      sql/sql_show.cc
      storage/innobase/handler/ha_innodb.cc
      storage/innobase/handler/ha_innodb.h
      mysql-test/include/have_profiling.inc
      mysql-test/r/have_profiling.require
=== modified file 'configure.in'
--- a/configure.in	2009-06-22 12:04:15 +0000
+++ b/configure.in	2009-06-22 12:30:28 +0000
@@ -639,24 +639,6 @@ then
   fi
 fi
 
-AC_MSG_CHECKING(whether features provided by the user community should be included.)
-AC_ARG_ENABLE(community-features,
-    AS_HELP_STRING(
-        [--enable-community-features], 
-        [Enable additional features provided by the user community.]),
-    [ ENABLE_COMMUNITY_FEATURES=$enableval ],
-    [ ENABLE_COMMUNITY_FEATURES=no ]
-    )
-
-if test "$ENABLE_COMMUNITY_FEATURES" = "yes"
-then
-  AC_DEFINE([COMMUNITY_SERVER], [1],
-            [Whether features provided by the user community should be included])
-  AC_MSG_RESULT([yes, community server])
-else
-  AC_MSG_RESULT([no, enterprise server])
-fi
-
 AC_ARG_WITH(server-suffix,
     [  --with-server-suffix    Append value to the version string.],
     [ MYSQL_SERVER_SUFFIX=`echo "$withval" | sed -e  's/^\(...................................\)..*$/\1/'` ],

=== modified file 'include/config-win.h'
--- a/include/config-win.h	2009-06-08 14:58:33 +0000
+++ b/include/config-win.h	2009-06-17 07:30:19 +0000
@@ -386,7 +386,6 @@ inline ulonglong double2ulonglong(double
 #define HAVE_OPENSSL 1
 #define HAVE_YASSL 1
 
-#define COMMUNITY_SERVER 1
 #define ENABLED_PROFILING 1
 
 /*

=== modified file 'mysql-test/extra/rpl_tests/rpl_row_sp006.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_sp006.test	2007-06-18 13:36:10 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp006.test	2009-06-18 04:03:12 +0000
@@ -11,12 +11,14 @@
 # Begin clean up test section
 connection master;
 --disable_warnings
-create database if not exists mysqltest1;
+drop database if exists mysqltest1;
+create database mysqltest1;
 DROP PROCEDURE IF EXISTS mysqltest1.p1;
 DROP PROCEDURE IF EXISTS mysqltest1.p2;
 DROP TABLE IF EXISTS mysqltest1.t2;
 DROP TABLE IF EXISTS mysqltest1.t1;
 --enable_warnings
+
 # End of cleanup
 
 # Begin test section 1

=== renamed file 'mysql-test/include/have_community_features.inc' => 'mysql-test/include/have_profiling.inc'
--- a/mysql-test/include/have_community_features.inc	2008-07-04 18:48:25 +0000
+++ b/mysql-test/include/have_profiling.inc	2009-06-10 07:55:29 +0000
@@ -1,4 +1,4 @@
---require r/have_community_features.require
+--require r/have_profiling.require
 --disable_query_log
-show variables like 'have_community_features';
+show variables like 'have_profiling';
 --enable_query_log

=== added file 'mysql-test/include/have_semisync_plugin.inc'
--- a/mysql-test/include/have_semisync_plugin.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/have_semisync_plugin.inc	2009-06-17 10:37:04 +0000
@@ -0,0 +1,15 @@
+#
+# Check if dynamic loading is supported
+#
+--require r/have_dynamic_loading.require
+disable_query_log;
+show variables like 'have_dynamic_loading';
+enable_query_log;
+
+#
+# Check if the variable SEMISYNC_MASTER_PLUGIN is set
+#
+if (`select LENGTH('$SEMISYNC_MASTER_PLUGIN') = 0`)
+{
+  skip Need semisync plugins;
+}

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2009-06-09 14:36:52 +0000
+++ b/mysql-test/mysql-test-run.pl	2009-06-18 08:23:14 +0000
@@ -1816,6 +1816,26 @@ sub environment_setup {
     $ENV{'EXAMPLE_PLUGIN_LOAD'}="";
   }
 
+  # --------------------------------------------------------------------------
+  # Add the path where mysqld will find semisync plugins
+  # --------------------------------------------------------------------------
+  my $lib_semisync_master_plugin=
+      mtr_file_exists("$basedir/plugin/semisync/.libs/libsemisync_master.so");
+  my $lib_semisync_slave_plugin=
+      mtr_file_exists("$basedir/plugin/semisync/.libs/libsemisync_slave.so");
+  if ($lib_semisync_master_plugin && $lib_semisync_slave_plugin)
+  {
+    $ENV{'SEMISYNC_MASTER_PLUGIN'}= basename($lib_semisync_master_plugin);
+    $ENV{'SEMISYNC_SLAVE_PLUGIN'}= basename($lib_semisync_slave_plugin);
+    $ENV{'SEMISYNC_PLUGIN_OPT'}= "--plugin-dir=".dirname($lib_semisync_master_plugin);
+  }
+  else
+  {
+    $ENV{'SEMISYNC_MASTER_PLUGIN'}= "";
+    $ENV{'SEMISYNC_SLAVE_PLUGIN'}= "";
+    $ENV{'SEMISYNC_PLUGIN_OPT'}="";
+  }
+
   # ----------------------------------------------------
   # Add the path where mysqld will find mypluglib.so
   # ----------------------------------------------------

=== modified file 'mysql-test/r/create.result'
--- a/mysql-test/r/create.result	2009-03-17 15:50:17 +0000
+++ b/mysql-test/r/create.result	2009-05-28 21:29:31 +0000
@@ -1900,3 +1900,37 @@ create table `me:i`(id int);
 drop table `me:i`;
 
 End of 5.1 tests
+
+# --
+# -- Bug #43054 	Assertion `!table->auto_increment_field_not_null' 
+# --       failed when redefining trigger
+
+CREATE TABLE B (
+pk INTEGER AUTO_INCREMENT,
+int_key INTEGER NOT NULL,
+PRIMARY KEY (pk),
+KEY (int_key)
+);
+INSERT IGNORE INTO B VALUES ('9', '9');
+CREATE TABLE IF NOT EXISTS t1 ( 
+`pk` INTEGER NOT NULL AUTO_INCREMENT , 
+`int` INTEGER ,
+PRIMARY KEY ( `pk` ) 
+) SELECT `pk` , `int_key` FROM B ;
+CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW 
+BEGIN 
+INSERT INTO t1 ( `int` ) VALUES (4 ),( 8 ),( 2 ) ; 
+END ; |
+CREATE TABLE IF NOT EXISTS t1 ( 
+`pk` INTEGER NOT NULL AUTO_INCREMENT , 
+`int` INTEGER ,
+PRIMARY KEY ( `pk` ) 
+) SELECT `pk` , `int_key` FROM B ;
+ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
+CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW 
+BEGIN 
+UPDATE A SET `pk`=1 WHERE `pk`=0 ; 
+END ;|
+ERROR 42000: This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'
+DROP TABLE t1;
+DROP TABLE B;

=== modified file 'mysql-test/r/events_bugs.result'
--- a/mysql-test/r/events_bugs.result	2009-06-12 02:01:08 +0000
+++ b/mysql-test/r/events_bugs.result	2009-06-17 07:30:19 +0000
@@ -77,7 +77,7 @@ set sql_mode='traditional';
 alter event e_16407 do select 1;
 select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
 event_schema	event_name	sql_mode
-events_test	e_16407	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+events_test	e_16407	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 drop event e_16407;
 set sql_mode="ansi";
 select get_lock('ee_16407_2', 60);
@@ -114,8 +114,8 @@ insert into events_test.events_smode_tes
 end|
 select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
 event_schema	event_name	sql_mode
-events_test	ee_16407_2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
-events_test	ee_16407_3	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+events_test	ee_16407_2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+events_test	ee_16407_3	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 events_test	ee_16407_4	
 select /*2*/ user, host, db, info from information_schema.processlist
 where state = 'User lock' and info = 'select get_lock(\'ee_16407_2\', 60)';
@@ -138,8 +138,8 @@ ee_16407_4	0000-00-00
 "OK, last check before we drop them"
 select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
 event_schema	event_name	sql_mode
-events_test	ee_16407_2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
-events_test	ee_16407_3	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+events_test	ee_16407_2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+events_test	ee_16407_3	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 events_test	ee_16407_4	
 drop event ee_16407_2;
 drop event ee_16407_3;
@@ -185,8 +185,8 @@ ee_16407_6	2004-02-29
 "And here we check one more time before we drop the events"
 select event_schema, event_name, sql_mode from information_schema.events order by event_schema, event_name;
 event_schema	event_name	sql_mode
-events_test	ee_16407_5	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
-events_test	ee_16407_6	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+events_test	ee_16407_5	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+events_test	ee_16407_6	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 drop event ee_16407_5;
 drop event ee_16407_6;
 drop procedure ee_16407_5_pendant;

=== modified file 'mysql-test/r/grant.result'
--- a/mysql-test/r/grant.result	2009-06-15 16:18:14 +0000
+++ b/mysql-test/r/grant.result	2009-06-22 12:30:28 +0000
@@ -2101,3 +2101,26 @@ DROP USER mysqltest_u1@localhost;
 
 # End of Bug#38347.
 
+#
+# Bug #25863 No database selected error, but documentation 
+#            says * for global allowed
+#
+GRANT ALL ON * TO mysqltest_1;
+ERROR 3D000: No database selected
+GRANT ALL ON *.* TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+Grants for mysqltest_1@%
+GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'%'
+DROP USER mysqltest_1;
+USE test;
+GRANT ALL ON * TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+Grants for mysqltest_1@%
+GRANT USAGE ON *.* TO 'mysqltest_1'@'%'
+GRANT ALL PRIVILEGES ON `test`.* TO 'mysqltest_1'@'%'
+DROP USER mysqltest_1;
+GRANT ALL ON *.* TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+Grants for mysqltest_1@%
+GRANT ALL PRIVILEGES ON *.* TO 'mysqltest_1'@'%'
+DROP USER mysqltest_1;

=== renamed file 'mysql-test/r/have_community_features.require' => 'mysql-test/r/have_profiling.require'
--- a/mysql-test/r/have_community_features.require	2007-05-02 18:13:33 +0000
+++ b/mysql-test/r/have_profiling.require	2009-06-10 07:55:29 +0000
@@ -1,2 +1,2 @@
 Variable_name	Value
-have_community_features	YES
+have_profiling  YES

=== modified file 'mysql-test/r/information_schema_routines.result'
--- a/mysql-test/r/information_schema_routines.result	2009-06-02 13:04:43 +0000
+++ b/mysql-test/r/information_schema_routines.result	2009-06-16 07:41:38 +0000
@@ -28,7 +28,7 @@ ROUTINES	CREATE TEMPORARY TABLE `ROUTINE
   `CREATED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `LAST_ALTERED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `SQL_MODE` varchar(8192) NOT NULL DEFAULT '',
-  `ROUTINE_COMMENT` varchar(64) NOT NULL DEFAULT '',
+  `ROUTINE_COMMENT` longtext NOT NULL,
   `DEFINER` varchar(77) NOT NULL DEFAULT '',
   `CHARACTER_SET_CLIENT` varchar(32) NOT NULL DEFAULT '',
   `COLLATION_CONNECTION` varchar(32) NOT NULL DEFAULT '',
@@ -568,16 +568,16 @@ TABLE_SCHEMA	information_schema
 TABLE_NAME	routines
 COLUMN_NAME	ROUTINE_COMMENT
 ORDINAL_POSITION	26
-COLUMN_DEFAULT	
+COLUMN_DEFAULT	NULL
 IS_NULLABLE	NO
-DATA_TYPE	varchar
-CHARACTER_MAXIMUM_LENGTH	64
-CHARACTER_OCTET_LENGTH	192
+DATA_TYPE	longtext
+CHARACTER_MAXIMUM_LENGTH	4294967295
+CHARACTER_OCTET_LENGTH	4294967295
 NUMERIC_PRECISION	NULL
 NUMERIC_SCALE	NULL
 CHARACTER_SET_NAME	utf8
 COLLATION_NAME	utf8_general_ci
-COLUMN_TYPE	varchar(64)
+COLUMN_TYPE	longtext
 COLUMN_KEY	
 EXTRA	
 PRIVILEGES	#
@@ -695,7 +695,7 @@ SECURITY_TYPE	varchar(7)	NO			
 CREATED	datetime	NO		0000-00-00 00:00:00	
 LAST_ALTERED	datetime	NO		0000-00-00 00:00:00	
 SQL_MODE	varchar(8192)	NO			
-ROUTINE_COMMENT	varchar(64)	NO			
+ROUTINE_COMMENT	longtext	NO		NULL	
 DEFINER	varchar(77)	NO			
 CHARACTER_SET_CLIENT	varchar(32)	NO			
 COLLATION_CONNECTION	varchar(32)	NO			

=== modified file 'mysql-test/r/innodb.result'
--- a/mysql-test/r/innodb.result	2009-06-02 13:04:43 +0000
+++ b/mysql-test/r/innodb.result	2009-06-19 09:12:06 +0000
@@ -1280,7 +1280,7 @@ count(*)
 623
 explain select * from t1 where c between 1 and 2500;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	range	c	c	5	NULL	#	Using index condition; Using MRR
+1	SIMPLE	t1	range	c	c	5	NULL	#	Using where
 update t1 set c=a;
 explain select * from t1 where c between 1 and 2500;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
@@ -1973,7 +1973,7 @@ qq
 *a         *a*a         *
 explain select * from t1 where v='a';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ref	v,v_2	#	13	const	#	Using index condition
+1	SIMPLE	t1	ref	v,v_2	#	13	const	#	Using where
 select v,count(*) from t1 group by v limit 10;
 v	count(*)
 a	1
@@ -2149,7 +2149,7 @@ id	select_type	table	type	possible_keys	
 1	SIMPLE	t1	ref	v	v	303	const	#	Using where; Using index
 explain select * from t1 where v='a';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t1	ref	v	v	303	const	#	Using index condition
+1	SIMPLE	t1	ref	v	v	303	const	#	Using where
 select v,count(*) from t1 group by v limit 10;
 v	count(*)
 a	1

=== modified file 'mysql-test/r/innodb_mrr.result'
--- a/mysql-test/r/innodb_mrr.result	2009-01-25 16:59:07 +0000
+++ b/mysql-test/r/innodb_mrr.result	2009-06-19 09:12:06 +0000
@@ -24,37 +24,37 @@ a	filler
 select a,filler from t3 where a >= 'c-1011=w' and a <= 'c-1015=w';
 a	filler
 c-1011=w	filler
-c-1012=w	filler
-c-1013=w	filler
-c-1014=w	filler
-c-1015=w	filler
 c-1011=w	filler-1
-c-1012=w	filler-1
-c-1013=w	filler-1
-c-1014=w	filler-1
-c-1015=w	filler-1
 c-1011=w	filler-2
+c-1012=w	filler
+c-1012=w	filler-1
 c-1012=w	filler-2
+c-1013=w	filler
+c-1013=w	filler-1
 c-1013=w	filler-2
+c-1014=w	filler
+c-1014=w	filler-1
 c-1014=w	filler-2
+c-1015=w	filler
+c-1015=w	filler-1
 c-1015=w	filler-2
 select a,filler from t3 where (a>='c-1011=w' and a <= 'c-1013=w') or
 (a>='c-1014=w' and a <= 'c-1015=w');
 a	filler
 c-1011=w	filler
-c-1012=w	filler
-c-1013=w	filler
-c-1014=w	filler
-c-1015=w	filler
 c-1011=w	filler-1
-c-1012=w	filler-1
-c-1013=w	filler-1
-c-1014=w	filler-1
-c-1015=w	filler-1
 c-1011=w	filler-2
+c-1012=w	filler
+c-1012=w	filler-1
 c-1012=w	filler-2
+c-1013=w	filler
+c-1013=w	filler-1
 c-1013=w	filler-2
+c-1014=w	filler
+c-1014=w	filler-1
 c-1014=w	filler-2
+c-1015=w	filler
+c-1015=w	filler-1
 c-1015=w	filler-2
 insert into t3 values ('c-1013=z', 'c-1013=z', 'err');
 insert into t3 values ('a-1014=w', 'a-1014=w', 'err');
@@ -62,59 +62,59 @@ select a,filler from t3 where (a>='c-101
 (a>='c-1014=w' and a <= 'c-1015=w');
 a	filler
 c-1011=w	filler
-c-1012=w	filler
-c-1013=w	filler
-c-1014=w	filler
-c-1015=w	filler
 c-1011=w	filler-1
-c-1012=w	filler-1
-c-1013=w	filler-1
-c-1014=w	filler-1
-c-1015=w	filler-1
 c-1011=w	filler-2
+c-1012=w	filler
+c-1012=w	filler-1
 c-1012=w	filler-2
+c-1013=w	filler
+c-1013=w	filler-1
 c-1013=w	filler-2
+c-1014=w	filler
+c-1014=w	filler-1
 c-1014=w	filler-2
+c-1015=w	filler
+c-1015=w	filler-1
 c-1015=w	filler-2
 delete from t3 where b in ('c-1013=z', 'a-1014=w');
 select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
 a='c-1014=w' or a='c-1015=w';
 a	filler
 c-1011=w	filler
-c-1012=w	filler
-c-1013=w	filler
-c-1014=w	filler
-c-1015=w	filler
 c-1011=w	filler-1
-c-1012=w	filler-1
-c-1013=w	filler-1
-c-1014=w	filler-1
-c-1015=w	filler-1
 c-1011=w	filler-2
+c-1012=w	filler
+c-1012=w	filler-1
 c-1012=w	filler-2
+c-1013=w	filler
+c-1013=w	filler-1
 c-1013=w	filler-2
+c-1014=w	filler
+c-1014=w	filler-1
 c-1014=w	filler-2
+c-1015=w	filler
+c-1015=w	filler-1
 c-1015=w	filler-2
 insert into t3 values ('c-1013=w', 'del-me', 'inserted');
 select a,filler from t3 where a='c-1011=w' or a='c-1012=w' or a='c-1013=w' or
 a='c-1014=w' or a='c-1015=w';
 a	filler
 c-1011=w	filler
-c-1012=w	filler
-c-1013=w	filler
-c-1014=w	filler
-c-1015=w	filler
 c-1011=w	filler-1
-c-1012=w	filler-1
-c-1013=w	filler-1
-c-1014=w	filler-1
-c-1015=w	filler-1
 c-1011=w	filler-2
+c-1012=w	filler
+c-1012=w	filler-1
 c-1012=w	filler-2
+c-1013=w	filler
+c-1013=w	filler-1
 c-1013=w	filler-2
+c-1013=w	inserted
+c-1014=w	filler
+c-1014=w	filler-1
 c-1014=w	filler-2
+c-1015=w	filler
+c-1015=w	filler-1
 c-1015=w	filler-2
-c-1013=w	inserted
 delete from t3 where b='del-me';
 alter table t3 add primary key(b);
 select b,filler from t3 where (b>='c-1011=w' and b<= 'c-1018=w') or 
@@ -183,7 +183,7 @@ explain 
 select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
                                                       or c='no-such-row2');
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	idx1	idx1	29	NULL	16	Using index condition; Using MRR
+1	SIMPLE	t4	range	idx1	idx1	29	NULL	16	Using where
 select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
                                                     or c='no-such-row2');
 a	b	c	filler
@@ -205,7 +205,7 @@ NULL	NULL	NULL	NULL-1
 explain 
 select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t4	range	idx1	idx1	29	NULL	32	Using index condition; Using MRR
+1	SIMPLE	t4	range	idx1	idx1	29	NULL	32	Using where
 select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
 a	b	c	filler
 b-1	NULL	c-1	NULL-15
@@ -306,7 +306,7 @@ from t1 A, t1 B, t1 C;
 explain
 select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	a	a	9	NULL	99	Using index condition; Using MRR
+1	SIMPLE	t2	range	a	a	9	NULL	99	Using where
 select count(length(a) + length(filler)) from t2 where a>='a-1000-a' and a <'a-1001-a';
 count(length(a) + length(filler))
 100
@@ -316,7 +316,7 @@ filler char(10), key(d), primary key (a,
 insert into t2 select A.a, B.a, B.a, A.a, 'filler' from t1 A, t1 B;
 explain select * from t2 force index (d) where d < 10;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	range	d	d	5	NULL	47	Using index condition; Using MRR
+1	SIMPLE	t2	range	d	d	5	NULL	47	Using where
 drop table t2;
 drop table t1;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;

=== modified file 'mysql-test/r/mysqldump.result'
--- a/mysql-test/r/mysqldump.result	2009-06-12 02:01:08 +0000
+++ b/mysql-test/r/mysqldump.result	2009-06-17 07:30:19 +0000
@@ -2392,7 +2392,7 @@ trg3	UPDATE	t1	begin
 if new.a = -1 then
 set @fired:= "Yes";
 end if;
-end	AFTER	0000-00-00 00:00:00	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+end	AFTER	0000-00-00 00:00:00	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
 INSERT INTO t1 (a) VALUES (1),(2),(3),(22);
 update t1 set a = 4 where a=3;
 
@@ -2469,7 +2469,7 @@ DELIMITER ;
 /*!50003 SET character_set_results = latin1 */ ;
 /*!50003 SET collation_connection  = latin1_swedish_ci */ ;
 /*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER' */ ;
+/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
 DELIMITER ;;
 /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg3 after update on t1 for each row
 begin
@@ -2501,7 +2501,7 @@ UNLOCK TABLES;
 /*!50003 SET character_set_results = latin1 */ ;
 /*!50003 SET collation_connection  = latin1_swedish_ci */ ;
 /*!50003 SET @saved_sql_mode       = @@sql_mode */ ;
-/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER' */ ;
+/*!50003 SET sql_mode              = 'STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ;
 DELIMITER ;;
 /*!50003 CREATE*/ /*!50017 DEFINER=`root`@`localhost`*/ /*!50003 trigger trg4 before insert on t2 for each row
 begin
@@ -2595,12 +2595,12 @@ trg3	UPDATE	t1	begin
 if new.a = -1 then
 set @fired:= "Yes";
 end if;
-end	AFTER	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+end	AFTER	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
 trg4	INSERT	t2	begin
 if new.a > 10 then
 set @fired:= "No";
 end if;
-end	BEFORE	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
+end	BEFORE	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	root@localhost	latin1	latin1_swedish_ci	latin1_swedish_ci
 DROP TABLE t1, t2;
 #
 # Bug#9136  my_print_defaults changed behaviour between 4.1.7 and 4.1.10a

=== modified file 'mysql-test/r/show_check.result'
--- a/mysql-test/r/show_check.result	2009-06-02 13:04:43 +0000
+++ b/mysql-test/r/show_check.result	2009-06-16 07:41:38 +0000
@@ -1119,7 +1119,7 @@ def	information_schema	ROUTINES	ROUTINES
 def	information_schema	ROUTINES	ROUTINES	SQL_PATH	SQL_PATH	253	192	0	Y	0	0	33
 def	information_schema	ROUTINES	ROUTINES	SECURITY_TYPE	SECURITY_TYPE	253	21	7	N	1	0	33
 def	information_schema	ROUTINES	ROUTINES	SQL_MODE	SQL_MODE	253	24576	0	N	1	0	33
-def	information_schema	ROUTINES	ROUTINES	ROUTINE_COMMENT	ROUTINE_COMMENT	253	192	0	N	1	0	33
+def	information_schema	ROUTINES	ROUTINES	ROUTINE_COMMENT	ROUTINE_COMMENT	252	589815	0	N	17	0	33
 def	information_schema	ROUTINES	ROUTINES	DEFINER	DEFINER	253	231	14	N	1	0	33
 SPECIFIC_NAME	ROUTINE_CATALOG	ROUTINE_SCHEMA	ROUTINE_NAME	ROUTINE_TYPE	DTD_IDENTIFIER	ROUTINE_BODY	ROUTINE_DEFINITION	EXTERNAL_NAME	EXTERNAL_LANGUAGE	PARAMETER_STYLE	IS_DETERMINISTIC	SQL_DATA_ACCESS	SQL_PATH	SECURITY_TYPE	SQL_MODE	ROUTINE_COMMENT	DEFINER
 p1	def	test	p1	PROCEDURE	NULL	SQL	SELECT 1	NULL	NULL	SQL	NO	CONTAINS SQL	NULL	DEFINER			root@localhost
@@ -1174,7 +1174,7 @@ def	information_schema	ROUTINES	ROUTINES
 def	information_schema	ROUTINES	ROUTINES	SQL_PATH	SQL_PATH	253	192	0	Y	0	0	33
 def	information_schema	ROUTINES	ROUTINES	SECURITY_TYPE	SECURITY_TYPE	253	21	7	N	1	0	33
 def	information_schema	ROUTINES	ROUTINES	SQL_MODE	SQL_MODE	253	24576	0	N	1	0	33
-def	information_schema	ROUTINES	ROUTINES	ROUTINE_COMMENT	ROUTINE_COMMENT	253	192	0	N	1	0	33
+def	information_schema	ROUTINES	ROUTINES	ROUTINE_COMMENT	ROUTINE_COMMENT	252	589815	0	N	17	0	33
 def	information_schema	ROUTINES	ROUTINES	DEFINER	DEFINER	253	231	14	N	1	0	33
 SPECIFIC_NAME	ROUTINE_CATALOG	ROUTINE_SCHEMA	ROUTINE_NAME	ROUTINE_TYPE	DTD_IDENTIFIER	ROUTINE_BODY	ROUTINE_DEFINITION	EXTERNAL_NAME	EXTERNAL_LANGUAGE	PARAMETER_STYLE	IS_DETERMINISTIC	SQL_DATA_ACCESS	SQL_PATH	SECURITY_TYPE	SQL_MODE	ROUTINE_COMMENT	DEFINER
 f1	def	test	f1	FUNCTION	int(11)	SQL	RETURN 1	NULL	NULL	SQL	NO	CONTAINS SQL	NULL	DEFINER			root@localhost

=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result	2009-06-04 13:50:05 +0000
+++ b/mysql-test/r/sp.result	2009-06-17 07:30:19 +0000
@@ -7009,6 +7009,19 @@ DROP FUNCTION f2;
 DROP FUNCTION f3;
 DROP FUNCTION f4;
 DROP TABLE t1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE PROCEDURE p1 ()
+COMMENT
+'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
+BEGIN
+END;
+SELECT comment FROM mysql.proc WHERE name = "p1";
+comment
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+SELECT routine_comment FROM information_schema.routines WHERE routine_name = "p1";
+routine_comment
+12345678901234567890123456789012345678901234567890123456789012345678901234567890
+DROP PROCEDURE p1;
 # ------------------------------------------------------------------
 # -- End of 6.0 tests
 # ------------------------------------------------------------------

=== modified file 'mysql-test/r/sql_mode.result'
--- a/mysql-test/r/sql_mode.result	2009-06-12 21:11:19 +0000
+++ b/mysql-test/r/sql_mode.result	2009-06-22 12:30:28 +0000
@@ -527,3 +527,9 @@ SELECT * FROM mysql.columns_priv WHERE H
 Host	Db	User	Table_name	Column_name	Timestamp	Column_priv
 DROP TABLE t1;
 DROP TABLE t2;
+SET @org_mode=@@sql_mode;
+SET @@sql_mode='traditional';
+SELECT @@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%';
+@@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%'
+1
+SET sql_mode=@org_mode;

=== modified file 'mysql-test/r/strict.result'
--- a/mysql-test/r/strict.result	2009-06-15 16:18:14 +0000
+++ b/mysql-test/r/strict.result	2009-06-22 12:30:28 +0000
@@ -2,7 +2,7 @@ set @org_mode=@@sql_mode;
 set @@sql_mode='ansi,traditional';
 select @@sql_mode;
 @@sql_mode
-REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP TABLE IF EXISTS t1, t2;
 CREATE TABLE t1 (col1 date);
 INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');

=== modified file 'mysql-test/r/subselect_sj2_jcl6.result'
--- a/mysql-test/r/subselect_sj2_jcl6.result	2009-04-02 21:57:08 +0000
+++ b/mysql-test/r/subselect_sj2_jcl6.result	2009-06-19 09:12:06 +0000
@@ -78,7 +78,7 @@ from t0 A, t0 B where B.a <5;
 explain select * from t3 where b in (select a from t0);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t0	ALL	NULL	NULL	NULL	NULL	10	Materialize; Scan
-1	PRIMARY	t3	ref	b	b	5	test.t0.a	1	Using join buffer
+1	PRIMARY	t3	ref	b	b	5	test.t0.a	1	
 set @save_ecp= @@engine_condition_pushdown;
 set engine_condition_pushdown=0;
 select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);

=== modified file 'mysql-test/r/system_mysql_db.result'
--- a/mysql-test/r/system_mysql_db.result	2009-03-11 21:22:33 +0000
+++ b/mysql-test/r/system_mysql_db.result	2009-06-02 11:59:00 +0000
@@ -204,7 +204,7 @@ proc	CREATE TABLE `proc` (
   `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
   `modified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
   `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH') NOT NULL DEFAULT '',
-  `comment` char(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
+  `comment` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
   `character_set_client` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
   `collation_connection` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
   `db_collation` char(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,

=== modified file 'mysql-test/r/trigger.result'
--- a/mysql-test/r/trigger.result	2009-03-27 13:03:00 +0000
+++ b/mysql-test/r/trigger.result	2009-06-16 12:27:49 +0000
@@ -2121,4 +2121,31 @@ Warning	1265	Data truncated for column '
 DROP TRIGGER trg1;
 DROP TRIGGER trg2;
 DROP TABLE t1;
+#
+# Bug#34453 Can't change size of file (Errcode: 1224)
+#
+DROP TRIGGER IF EXISTS t1_bi;
+DROP TRIGGER IF EXISTS t1_bd;
+DROP TABLE IF EXISTS t1;
+DROP TEMPORARY TABLE IF EXISTS t2;
+CREATE TABLE t1 (s1 INT);
+CREATE TEMPORARY TABLE t2 (s1 INT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (0);
+CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t2;
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t1;
+s1
+0
+0
+SELECT * FROM t2;
+s1
+0
+0
+# Reported to give ERROR 14 (HY000): 
+# Can't change size of file (Errcode: 1224)
+# on Windows 
+DELETE FROM t1;
+DROP TABLE t1;
+DROP TEMPORARY TABLE t2;
 End of 6.0 tests.

=== modified file 'mysql-test/suite/backup/r/backup_check_i_s.result'
--- a/mysql-test/suite/backup/r/backup_check_i_s.result	2009-05-04 05:27:25 +0000
+++ b/mysql-test/suite/backup/r/backup_check_i_s.result	2009-06-16 07:41:38 +0000
@@ -99,7 +99,7 @@ SECURITY_TYPE	varchar(7)	NO			
 CREATED	datetime	NO		0000-00-00 00:00:00	
 LAST_ALTERED	datetime	NO		0000-00-00 00:00:00	
 SQL_MODE	varchar(8192)	NO			
-ROUTINE_COMMENT	varchar(64)	NO			
+ROUTINE_COMMENT	longtext	NO		NULL	
 DEFINER	varchar(77)	NO			
 CHARACTER_SET_CLIENT	varchar(32)	NO			
 COLLATION_CONNECTION	varchar(32)	NO			

=== modified file 'mysql-test/suite/backup/r/backup_functions.result'
--- a/mysql-test/suite/backup/r/backup_functions.result	2009-03-05 20:05:02 +0000
+++ b/mysql-test/suite/backup/r/backup_functions.result	2009-06-05 07:56:52 +0000
@@ -99,7 +99,7 @@ square_area(11)
 showing objects and create statements.
 SHOW CREATE FUNCTION number_of_players;;
 Function	number_of_players
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 Create Function	CREATE DEFINER=`root`@`localhost` FUNCTION `number_of_players`() RETURNS int(11)
 BEGIN
 RETURN (SELECT COUNT(*) FROM players);
@@ -191,14 +191,14 @@ backup_id
 #
 SELECT @@SQL_MODE;
 @@SQL_MODE
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 showing objects and create statements
 SHOW CREATE DATABASE bup_sfs;;
 Database	bup_sfs
 Create Database	CREATE DATABASE `bup_sfs` /*!40100 DEFAULT CHARACTER SET latin1 */
 SHOW CREATE FUNCTION number_of_players;;
 Function	number_of_players
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 Create Function	CREATE DEFINER=`root`@`localhost` FUNCTION `number_of_players`() RETURNS int(11)
 BEGIN
 RETURN (SELECT COUNT(*) FROM players);
@@ -310,7 +310,7 @@ Database	bup_sfs
 Create Database	CREATE DATABASE "bup_sfs" /*!40100 DEFAULT CHARACTER SET latin1 */
 SHOW CREATE FUNCTION number_of_players;;
 Function	number_of_players
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 Create Function	CREATE DEFINER=`root`@`localhost` FUNCTION `number_of_players`() RETURNS int(11)
 BEGIN
 RETURN (SELECT COUNT(*) FROM players);
@@ -398,7 +398,7 @@ Database	bup_sfs
 Create Database	CREATE DATABASE "bup_sfs" /*!40100 DEFAULT CHARACTER SET latin1 */
 SHOW CREATE FUNCTION number_of_players;;
 Function	number_of_players
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 Create Function	CREATE DEFINER=`root`@`localhost` FUNCTION `number_of_players`() RETURNS int(11)
 BEGIN
 RETURN (SELECT COUNT(*) FROM players);
@@ -493,7 +493,7 @@ Database	bup_sfs
 Create Database	CREATE DATABASE `bup_sfs` /*!40100 DEFAULT CHARACTER SET latin1 */
 SHOW CREATE FUNCTION number_of_players;;
 Function	number_of_players
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 Create Function	CREATE DEFINER=`root`@`localhost` FUNCTION `number_of_players`() RETURNS int(11)
 BEGIN
 RETURN (SELECT COUNT(*) FROM players);

=== modified file 'mysql-test/suite/binlog/r/binlog_tmp_table.result'
--- a/mysql-test/suite/binlog/r/binlog_tmp_table.result	2009-01-28 14:35:12 +0000
+++ b/mysql-test/suite/binlog/r/binlog_tmp_table.result	2009-06-18 04:03:12 +0000
@@ -1,3 +1,4 @@
+reset master;
 create table foo (a int);
 flush logs;
 create temporary table tmp1_foo like foo;

=== modified file 'mysql-test/suite/binlog/t/binlog_tmp_table.test'
--- a/mysql-test/suite/binlog/t/binlog_tmp_table.test	2009-01-31 21:47:50 +0000
+++ b/mysql-test/suite/binlog/t/binlog_tmp_table.test	2009-06-18 04:03:12 +0000
@@ -31,6 +31,8 @@ source include/have_binlog_format_mixed_
 connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
 connect (master1,127.0.0.1,root,,test,$MASTER_MYPORT,);
 
+reset master;
+
 create table foo (a int);
 
 flush logs;

=== modified file 'mysql-test/suite/funcs_1/r/innodb_storedproc_07.result'
--- a/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_07.result	2009-06-12 09:37:59 +0000
@@ -80,7 +80,7 @@ CREATE TABLE result (f1 text(200), f2 ch
 set @@sql_mode='traditional';
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp1()
 BEGIN
 declare a tinyint;
@@ -97,7 +97,7 @@ END if;
 END//
 SHOW CREATE PROCEDURE sp1;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
+sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
 BEGIN
 declare a tinyint;
 declare count_ int default 1;
@@ -117,10 +117,10 @@ Variable_name	Value
 sql_mode	
 CALL sp1();
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 SELECT * from result;
 f1	f2
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	value restored
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	value restored
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
 sql_mode	
@@ -142,7 +142,7 @@ DROP PROCEDURE IF EXISTS sp2;
 ... show initial value
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp2()
 BEGIN
 SET @@sql_mode='MAXDB';
@@ -150,7 +150,7 @@ SHOW VARIABLES LIKE 'sql_mode';
 END//
 SHOW CREATE PROCEDURE sp2;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
+sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
 BEGIN
 SET @@sql_mode='MAXDB';
 SHOW VARIABLES LIKE 'sql_mode';
@@ -158,7 +158,7 @@ END	latin1	latin1_swedish_ci	latin1_swed
 ... show value prior calling procedure
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 ... call procedure that changes sql_mode
 CALL sp2();
 Variable_name	Value
@@ -166,7 +166,7 @@ sql_mode	PIPES_AS_CONCAT,ANSI_QUOTES,IGN
 ... check whether old value is re-set
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP PROCEDURE sp2;
 
 --source suite/funcs_1/storedproc/cleanup_sp_tb.inc

=== modified file 'mysql-test/suite/funcs_1/r/is_columns_is.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result	2009-06-05 13:21:53 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result	2009-06-16 07:41:38 +0000
@@ -216,7 +216,7 @@ def	information_schema	ROUTINES	NUMERIC_
 def	information_schema	ROUTINES	PARAMETER_STYLE	18		NO	varchar	8	24	NULL	NULL	utf8	utf8_general_ci	varchar(8)			select		Default	Default
 def	information_schema	ROUTINES	ROUTINE_BODY	14		NO	varchar	8	24	NULL	NULL	utf8	utf8_general_ci	varchar(8)			select		Default	Default
 def	information_schema	ROUTINES	ROUTINE_CATALOG	2		NO	varchar	512	1536	NULL	NULL	utf8	utf8_general_ci	varchar(512)			select		Default	Default
-def	information_schema	ROUTINES	ROUTINE_COMMENT	26		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select		Default	Default
+def	information_schema	ROUTINES	ROUTINE_COMMENT	26	NULL	NO	longtext	4294967295	4294967295	NULL	NULL	utf8	utf8_general_ci	longtext			select		Default	Default
 def	information_schema	ROUTINES	ROUTINE_DEFINITION	15	NULL	YES	longtext	4294967295	4294967295	NULL	NULL	utf8	utf8_general_ci	longtext			select		Default	Default
 def	information_schema	ROUTINES	ROUTINE_NAME	4		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select		Default	Default
 def	information_schema	ROUTINES	ROUTINE_SCHEMA	3		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select		Default	Default
@@ -611,7 +611,7 @@ NULL	information_schema	ROUTINES	NUMERIC
 NULL	information_schema	ROUTINES	CREATED	datetime	NULL	NULL	NULL	NULL	datetime
 NULL	information_schema	ROUTINES	LAST_ALTERED	datetime	NULL	NULL	NULL	NULL	datetime
 3.0000	information_schema	ROUTINES	SQL_MODE	varchar	8192	24576	utf8	utf8_general_ci	varchar(8192)
-3.0000	information_schema	ROUTINES	ROUTINE_COMMENT	varchar	64	192	utf8	utf8_general_ci	varchar(64)
+1.0000	information_schema	ROUTINES	ROUTINE_COMMENT	longtext	4294967295	4294967295	utf8	utf8_general_ci	longtext
 3.0000	information_schema	ROUTINES	DEFINER	varchar	77	231	utf8	utf8_general_ci	varchar(77)
 3.0000	information_schema	ROUTINES	CHARACTER_SET_CLIENT	varchar	32	96	utf8	utf8_general_ci	varchar(32)
 3.0000	information_schema	ROUTINES	COLLATION_CONNECTION	varchar	32	96	utf8	utf8_general_ci	varchar(32)

=== modified file 'mysql-test/suite/funcs_1/r/is_columns_mysql.result'
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2009-06-05 13:21:53 +0000
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result	2009-06-12 09:37:59 +0000
@@ -136,7 +136,7 @@ def	mysql	proc	body	11	NULL	NO	longblob	
 def	mysql	proc	body_utf8	20	NULL	YES	longblob	4294967295	4294967295	NULL	NULL	NULL	NULL	longblob			select,insert,update,references		Default	Default
 def	mysql	proc	character_set_client	17	NULL	YES	char	32	96	NULL	NULL	utf8	utf8_bin	char(32)			select,insert,update,references		Default	Default
 def	mysql	proc	collation_connection	18	NULL	YES	char	32	96	NULL	NULL	utf8	utf8_bin	char(32)			select,insert,update,references		Default	Default
-def	mysql	proc	comment	16		NO	char	64	192	NULL	NULL	utf8	utf8_bin	char(64)			select,insert,update,references		Default	Default
+def	mysql	proc	comment	16	NULL	NO	text	65535	65535	NULL	NULL	utf8	utf8_bin	text			select,insert,update,references		Default	Default
 def	mysql	proc	created	13	CURRENT_TIMESTAMP	NO	timestamp	NULL	NULL	NULL	NULL	NULL	NULL	timestamp		on update CURRENT_TIMESTAMP	select,insert,update,references		Default	Default
 def	mysql	proc	db	1		NO	char	64	192	NULL	NULL	utf8	utf8_bin	char(64)	PRI		select,insert,update,references		Default	Default
 def	mysql	proc	db_collation	19	NULL	YES	char	32	96	NULL	NULL	utf8	utf8_bin	char(32)			select,insert,update,references		Default	Default
@@ -260,6 +260,7 @@ COL_CML	DATA_TYPE	CHARACTER_SET_NAME	COL
 1.0000	char	latin1	latin1_bin
 1.0000	char	latin1	latin1_swedish_ci
 1.0000	varchar	latin1	latin1_swedish_ci
+1.0000	text	utf8	utf8_bin
 1.0000	mediumtext	utf8	utf8_general_ci
 1.0000	text	utf8	utf8_general_ci
 SELECT DISTINCT
@@ -456,7 +457,7 @@ NULL	mysql	ndb_binlog_index	gci	int	NULL
 NULL	mysql	proc	created	timestamp	NULL	NULL	NULL	NULL	timestamp
 NULL	mysql	proc	modified	timestamp	NULL	NULL	NULL	NULL	timestamp
 3.0000	mysql	proc	sql_mode	set	478	1434	utf8	utf8_general_ci	set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
-3.0000	mysql	proc	comment	char	64	192	utf8	utf8_bin	char(64)
+1.0000	mysql	proc	comment	text	65535	65535	utf8	utf8_bin	text
 3.0000	mysql	proc	character_set_client	char	32	96	utf8	utf8_bin	char(32)
 3.0000	mysql	proc	collation_connection	char	32	96	utf8	utf8_bin	char(32)
 3.0000	mysql	proc	db_collation	char	32	96	utf8	utf8_bin	char(32)

=== modified file 'mysql-test/suite/funcs_1/r/is_routines.result'
--- a/mysql-test/suite/funcs_1/r/is_routines.result	2009-04-01 09:37:16 +0000
+++ b/mysql-test/suite/funcs_1/r/is_routines.result	2009-06-16 07:41:38 +0000
@@ -53,7 +53,7 @@ SECURITY_TYPE	varchar(7)	NO			
 CREATED	datetime	NO		0000-00-00 00:00:00	
 LAST_ALTERED	datetime	NO		0000-00-00 00:00:00	
 SQL_MODE	varchar(8192)	NO			
-ROUTINE_COMMENT	varchar(64)	NO			
+ROUTINE_COMMENT	longtext	NO		NULL	
 DEFINER	varchar(77)	NO			
 CHARACTER_SET_CLIENT	varchar(32)	NO			
 COLLATION_CONNECTION	varchar(32)	NO			
@@ -86,7 +86,7 @@ ROUTINES	CREATE TEMPORARY TABLE `ROUTINE
   `CREATED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `LAST_ALTERED` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
   `SQL_MODE` varchar(8192) NOT NULL DEFAULT '',
-  `ROUTINE_COMMENT` varchar(64) NOT NULL DEFAULT '',
+  `ROUTINE_COMMENT` longtext NOT NULL,
   `DEFINER` varchar(77) NOT NULL DEFAULT '',
   `CHARACTER_SET_CLIENT` varchar(32) NOT NULL DEFAULT '',
   `COLLATION_CONNECTION` varchar(32) NOT NULL DEFAULT '',
@@ -119,7 +119,7 @@ SECURITY_TYPE	varchar(7)	NO			
 CREATED	datetime	NO		0000-00-00 00:00:00	
 LAST_ALTERED	datetime	NO		0000-00-00 00:00:00	
 SQL_MODE	varchar(8192)	NO			
-ROUTINE_COMMENT	varchar(64)	NO			
+ROUTINE_COMMENT	longtext	NO		NULL	
 DEFINER	varchar(77)	NO			
 CHARACTER_SET_CLIENT	varchar(32)	NO			
 COLLATION_CONNECTION	varchar(32)	NO			

=== modified file 'mysql-test/suite/funcs_1/r/memory_storedproc_07.result'
--- a/mysql-test/suite/funcs_1/r/memory_storedproc_07.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/memory_storedproc_07.result	2009-06-12 09:37:59 +0000
@@ -81,7 +81,7 @@ CREATE TABLE result (f1 text(200), f2 ch
 set @@sql_mode='traditional';
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp1()
 BEGIN
 declare a tinyint;
@@ -98,7 +98,7 @@ END if;
 END//
 SHOW CREATE PROCEDURE sp1;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
+sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
 BEGIN
 declare a tinyint;
 declare count_ int default 1;
@@ -118,10 +118,10 @@ Variable_name	Value
 sql_mode	
 CALL sp1();
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 SELECT * from result;
 f1	f2
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	value restored
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	value restored
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
 sql_mode	
@@ -143,7 +143,7 @@ DROP PROCEDURE IF EXISTS sp2;
 ... show initial value
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp2()
 BEGIN
 SET @@sql_mode='MAXDB';
@@ -151,7 +151,7 @@ SHOW VARIABLES LIKE 'sql_mode';
 END//
 SHOW CREATE PROCEDURE sp2;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
+sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
 BEGIN
 SET @@sql_mode='MAXDB';
 SHOW VARIABLES LIKE 'sql_mode';
@@ -159,7 +159,7 @@ END	latin1	latin1_swedish_ci	latin1_swed
 ... show value prior calling procedure
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 ... call procedure that changes sql_mode
 CALL sp2();
 Variable_name	Value
@@ -167,7 +167,7 @@ sql_mode	PIPES_AS_CONCAT,ANSI_QUOTES,IGN
 ... check whether old value is re-set
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP PROCEDURE sp2;
 
 --source suite/funcs_1/storedproc/cleanup_sp_tb.inc

=== modified file 'mysql-test/suite/funcs_1/r/myisam_storedproc_07.result'
--- a/mysql-test/suite/funcs_1/r/myisam_storedproc_07.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_07.result	2009-06-12 09:37:59 +0000
@@ -81,7 +81,7 @@ CREATE TABLE result (f1 text(200), f2 ch
 set @@sql_mode='traditional';
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp1()
 BEGIN
 declare a tinyint;
@@ -98,7 +98,7 @@ END if;
 END//
 SHOW CREATE PROCEDURE sp1;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
+sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
 BEGIN
 declare a tinyint;
 declare count_ int default 1;
@@ -118,10 +118,10 @@ Variable_name	Value
 sql_mode	
 CALL sp1();
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 SELECT * from result;
 f1	f2
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	value restored
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	value restored
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
 sql_mode	
@@ -143,7 +143,7 @@ DROP PROCEDURE IF EXISTS sp2;
 ... show initial value
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp2()
 BEGIN
 SET @@sql_mode='MAXDB';
@@ -151,7 +151,7 @@ SHOW VARIABLES LIKE 'sql_mode';
 END//
 SHOW CREATE PROCEDURE sp2;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
+sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
 BEGIN
 SET @@sql_mode='MAXDB';
 SHOW VARIABLES LIKE 'sql_mode';
@@ -159,7 +159,7 @@ END	latin1	latin1_swedish_ci	latin1_swed
 ... show value prior calling procedure
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 ... call procedure that changes sql_mode
 CALL sp2();
 Variable_name	Value
@@ -167,7 +167,7 @@ sql_mode	PIPES_AS_CONCAT,ANSI_QUOTES,IGN
 ... check whether old value is re-set
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP PROCEDURE sp2;
 
 --source suite/funcs_1/storedproc/cleanup_sp_tb.inc

=== modified file 'mysql-test/suite/funcs_1/r/ndb_storedproc_07.result'
--- a/mysql-test/suite/funcs_1/r/ndb_storedproc_07.result	2009-02-02 15:58:48 +0000
+++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_07.result	2009-06-12 09:37:59 +0000
@@ -80,7 +80,7 @@ CREATE TABLE result (f1 text(200), f2 ch
 set @@sql_mode='traditional';
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp1()
 BEGIN
 declare a tinyint;
@@ -97,7 +97,7 @@ END if;
 END//
 SHOW CREATE PROCEDURE sp1;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
+sp1	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp1`()
 BEGIN
 declare a tinyint;
 declare count_ int default 1;
@@ -117,10 +117,10 @@ Variable_name	Value
 sql_mode	
 CALL sp1();
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 SELECT * from result;
 f1	f2
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	value restored
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	value restored
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
 sql_mode	
@@ -142,7 +142,7 @@ DROP PROCEDURE IF EXISTS sp2;
 ... show initial value
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 CREATE PROCEDURE sp2()
 BEGIN
 SET @@sql_mode='MAXDB';
@@ -150,7 +150,7 @@ SHOW VARIABLES LIKE 'sql_mode';
 END//
 SHOW CREATE PROCEDURE sp2;
 Procedure	sql_mode	Create Procedure	character_set_client	collation_connection	Database Collation
-sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
+sp2	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION	CREATE DEFINER=`root`@`localhost` PROCEDURE `sp2`()
 BEGIN
 SET @@sql_mode='MAXDB';
 SHOW VARIABLES LIKE 'sql_mode';
@@ -158,7 +158,7 @@ END	latin1	latin1_swedish_ci	latin1_swed
 ... show value prior calling procedure
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 ... call procedure that changes sql_mode
 CALL sp2();
 Variable_name	Value
@@ -166,7 +166,7 @@ sql_mode	PIPES_AS_CONCAT,ANSI_QUOTES,IGN
 ... check whether old value is re-set
 SHOW VARIABLES LIKE 'sql_mode';
 Variable_name	Value
-sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+sql_mode	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP PROCEDURE sp2;
 
 --source suite/funcs_1/storedproc/cleanup_sp_tb.inc

=== modified file 'mysql-test/suite/funcs_1/r/storedproc.result'
--- a/mysql-test/suite/funcs_1/r/storedproc.result	2009-02-23 16:45:39 +0000
+++ b/mysql-test/suite/funcs_1/r/storedproc.result	2009-06-12 09:37:59 +0000
@@ -22113,7 +22113,7 @@ f1
 2005-03-14 01:01:02
 SELECT @@sql_mode;
 @@sql_mode
-STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
+STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
 DROP PROCEDURE sp2;
 drop table temp_table;
 

=== modified file 'mysql-test/suite/rpl/r/rpl_heartbeat.result'
--- a/mysql-test/suite/rpl/r/rpl_heartbeat.result	2009-04-03 16:24:50 +0000
+++ b/mysql-test/suite/rpl/r/rpl_heartbeat.result	2009-06-15 14:00:15 +0000
@@ -45,7 +45,7 @@ Warnings:
 Warning	1624	The currect value for master_heartbeat_period exceeds the new value of `slave_net_timeout' sec. A sensible value for the period should be less than the timeout.
 reset slave;
 drop table if exists t1;
-set @@global.slave_net_timeout= 20;
+set @@global.slave_net_timeout= 10;
 change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root', master_heartbeat_period= 0.5;
 show status like 'Slave_heartbeat_period';;
 Variable_name	Slave_heartbeat_period
@@ -139,7 +139,5 @@ Variable_name	Slave_heartbeat_period
 Value	0.500
 A heartbeat has been received by the slave
 drop table t1;
-*** debug: 356 ***
-#connection slave
 set @@global.slave_net_timeout=@restore_slave_net_timeout;
 End of tests

=== modified file 'mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result'
--- a/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result	2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result	2009-06-18 04:03:12 +0000
@@ -4,7 +4,8 @@ reset master;
 reset slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 start slave;
-create database if not exists mysqltest1;
+drop database if exists mysqltest1;
+create database mysqltest1;
 DROP PROCEDURE IF EXISTS mysqltest1.p1;
 DROP PROCEDURE IF EXISTS mysqltest1.p2;
 DROP TABLE IF EXISTS mysqltest1.t2;

=== added file 'mysql-test/suite/rpl/r/rpl_semi_sync.result'
--- a/mysql-test/suite/rpl/r/rpl_semi_sync.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result	2009-06-17 10:37:04 +0000
@@ -0,0 +1,331 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+#
+# Uninstall semi-sync plugins on master and slave
+#
+include/stop_slave.inc
+reset slave;
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+reset master;
+set sql_log_bin=0;
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+set sql_log_bin=1;
+#
+# Main test of semi-sync replication start here
+#
+[ on master ]
+[ default state of semi-sync on master should be OFF ]
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+rpl_semi_sync_master_enabled	OFF
+[ enable semi-sync on master ]
+set global rpl_semi_sync_master_enabled = 1;
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+rpl_semi_sync_master_enabled	ON
+[ on slave ]
+[ default state of semi-sync on slave should be OFF ]
+show variables like 'rpl_semi_sync_slave_enabled';
+Variable_name	Value
+rpl_semi_sync_slave_enabled	OFF
+[ enable semi-sync on slave ]
+set global rpl_semi_sync_slave_enabled = 1;
+show variables like 'rpl_semi_sync_slave_enabled';
+Variable_name	Value
+rpl_semi_sync_slave_enabled	ON
+include/start_slave.inc
+[ on master ]
+[ initial master state after the semi-sync slave connected ]
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name	Value
+Rpl_semi_sync_master_clients	1
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	0
+create table t1(n int) engine = ENGINE_TYPE;
+[ master state after CREATE TABLE statement ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	1
+[ insert records to table ]
+[ master status after inserts ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	301
+[ on slave ]
+[ slave status after replicated inserts ]
+show status like 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	ON
+select count(distinct n) from t1;
+count(distinct n)
+300
+select min(n) from t1;
+min(n)
+1
+select max(n) from t1;
+max(n)
+300
+include/stop_slave.inc
+[ on master ]
+[ master status should be ON ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	301
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name	Value
+Rpl_semi_sync_master_clients	1
+[ semi-sync replication of these transactions will fail ]
+insert into t1 values (500);
+delete from t1 where n < 500;
+insert into t1 values (100);
+[ master status should be OFF ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	OFF
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	3
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	301
+[ on slave ]
+[ slave status should be OFF ]
+show status like 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+include/start_slave.inc
+[ slave status should be ON ]
+show status like 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	ON
+select count(distinct n) from t1;
+count(distinct n)
+2
+select min(n) from t1;
+min(n)
+100
+select max(n) from t1;
+max(n)
+500
+[ on master ]
+[ do something to activate semi-sync ]
+drop table t1;
+[ master status should be ON again ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';

+Variable_name	Value
+Rpl_semi_sync_master_no_tx	3
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	302
+show status like 'Rpl_semi_sync_master_clients';
+Variable_name	Value
+Rpl_semi_sync_master_clients	1
+[ on slave ]
+include/stop_slave.inc
+[ on master ]
+show master logs;
+Log_name	master-bin.000001
+File_size	#
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+rpl_semi_sync_master_enabled	ON
+[ disable semi-sync on the fly ]
+set global rpl_semi_sync_master_enabled=0;
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+rpl_semi_sync_master_enabled	OFF
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	OFF
+[ enable semi-sync on the fly ]
+set global rpl_semi_sync_master_enabled=1;
+show variables like 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+rpl_semi_sync_master_enabled	ON
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+[ on slave ]
+include/start_slave.inc
+[ on master ]
+create table t1 (a int) engine = ENGINE_TYPE;
+drop table t1;
+show status like 'Rpl_relay%';
+Variable_name	Value
+[ test reset master ]
+[ on master]
+reset master;
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	0
+[ on slave ]
+include/stop_slave.inc
+reset slave;
+include/start_slave.inc
+[ on master ]
+create table t1 (a int) engine = ENGINE_TYPE;
+insert into t1 values (1);
+insert into t1 values (2), (3);
+[ on slave ]
+select * from t1;
+a
+1
+2
+3
+[ on master ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	3
+#
+# Start semi-sync replication without SUPER privilege
+#
+reset master;
+include/stop_slave.inc
+reset slave;
+[ on master ]
+set sql_log_bin=0;
+grant replication slave on *.* to rpl@stripped identified by 'rpl';
+flush privileges;
+set sql_log_bin=1;
+[ on slave ]
+grant replication slave on *.* to rpl@stripped.0.1 identified by 'rpl';
+flush privileges;
+change master to master_user='rpl',master_password='rpl';
+include/start_slave.inc
+[ on master ]
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	0
+insert into t1 values (4);
+insert into t1 values (5);
+show status like 'Rpl_semi_sync_master_status';
+Variable_name	Value
+Rpl_semi_sync_master_status	ON
+show status like 'Rpl_semi_sync_master_no_tx';
+Variable_name	Value
+Rpl_semi_sync_master_no_tx	0
+show status like 'Rpl_semi_sync_master_yes_tx';
+Variable_name	Value
+Rpl_semi_sync_master_yes_tx	2
+#
+# Test semi-sync slave connect to non-semi-sync master
+#
+[ on slave ]
+include/stop_slave.inc
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+[ on master ]
+set sql_log_bin=0;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+set sql_log_bin=1;
+SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled';
+Variable_name	Value
+[ on slave ]
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+Variable_name	Value
+rpl_semi_sync_slave_enabled	ON
+include/start_slave.inc
+[ on master ]
+insert into t1 values (10);
+[ on slave ]
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+#
+# Test non-semi-sync slave connect to semi-sync master
+#
+set sql_log_bin=0;
+INSTALL PLUGIN rpl_semi_sync_master SONAME 'libsemisync_master.so';
+set global rpl_semi_sync_master_timeout= 5000;
+/* 5s */
+set sql_log_bin=1;
+set global rpl_semi_sync_master_enabled= 1;
+[ on slave ]
+include/stop_slave.inc
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+[ uninstall semi-sync slave plugin ]
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+Variable_name	Value
+include/start_slave.inc
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+include/stop_slave.inc
+[ reinstall semi-sync slave plugin and disable semi-sync ]
+INSTALL PLUGIN rpl_semi_sync_slave SONAME 'libsemisync_slave.so';
+set global rpl_semi_sync_slave_enabled= 0;
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+Variable_name	Value
+rpl_semi_sync_slave_enabled	OFF
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+include/start_slave.inc
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+Variable_name	Value
+Rpl_semi_sync_slave_status	OFF
+#
+# Clean up
+#
+include/stop_slave.inc
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+include/start_slave.inc
+drop table t1;
+drop user rpl@stripped;
+flush privileges;

=== modified file 'mysql-test/suite/rpl/t/rpl000017.test'
--- a/mysql-test/suite/rpl/t/rpl000017.test	2008-09-09 05:23:11 +0000
+++ b/mysql-test/suite/rpl/t/rpl000017.test	2009-06-15 13:30:20 +0000
@@ -16,6 +16,7 @@ grant replication slave on *.* to replic
 grant replication slave on *.* to replicate@stripped identified by 'aaaaaaaaaaaaaaab';
 connection slave;
 start slave;
+source include/wait_for_slave_to_start.inc;
 
 connection master;
 --disable_warnings

=== modified file 'mysql-test/suite/rpl/t/rpl_heartbeat.test'
--- a/mysql-test/suite/rpl/t/rpl_heartbeat.test	2009-04-03 16:24:50 +0000
+++ b/mysql-test/suite/rpl/t/rpl_heartbeat.test	2009-06-15 14:00:15 +0000
@@ -113,7 +113,7 @@ drop table if exists t1;
 #
 
 connection slave;
-set @@global.slave_net_timeout= 20;
+set @@global.slave_net_timeout= 10;
 --replace_result $MASTER_MYPORT MASTER_PORT
 # no error this time but rather a warning
 eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 0.5;
@@ -133,7 +133,7 @@ source include/show_slave_status.inc;

 # That would cause reconnecting and relaylog rotation w/o the fix i.e
 # without a heartbeat received.
 
-real_sleep 30;
+real_sleep 15;
 
 # check (compare with the previous show's results) that no rotation happened
 source include/show_slave_status.inc;
@@ -173,10 +173,6 @@ while (`select $slave_value = 0`)
 connection master;
 drop table t1;
 
-# debug print out, todo: remove after bug#37714 is fixed
-let $last_pos = query_get_value("SHOW MASTER STATUS", Position, 1);
-echo *** debug: $last_pos ***
-
 #connection slave;
 sync_slave_with_master;
 set @@global.slave_net_timeout=@restore_slave_net_timeout;

=== added file 'mysql-test/suite/rpl/t/rpl_semi_sync-master.opt'
--- a/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync-master.opt	2009-06-17 10:37:04 +0000
@@ -0,0 +1 @@
+$SEMISYNC_PLUGIN_OPT

=== added file 'mysql-test/suite/rpl/t/rpl_semi_sync-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_semi_sync-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync-slave.opt	2009-06-17 10:37:04 +0000
@@ -0,0 +1 @@
+$SEMISYNC_PLUGIN_OPT

=== added file 'mysql-test/suite/rpl/t/rpl_semi_sync.test'
--- a/mysql-test/suite/rpl/t/rpl_semi_sync.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test	2009-06-17 10:37:04 +0000
@@ -0,0 +1,373 @@
+source include/have_semisync_plugin.inc;
+source include/not_embedded.inc;
+source include/not_windows.inc;
+source include/have_innodb.inc;
+source include/master-slave.inc;
+
+let $engine_type= InnoDB;
+#let $engine_type= MyISAM;
+
+--echo #
+--echo # Uninstall semi-sync plugins on master and slave
+--echo #
+connection slave;
+disable_query_log;
+source include/stop_slave.inc;
+reset slave;
+disable_warnings;
+error 0,1305;
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+error 0,1305;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+enable_warnings;
+
+connection master;
+reset master;
+set sql_log_bin=0;
+disable_warnings;
+error 0,1305;
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+error 0,1305;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+enable_warnings;
+set sql_log_bin=1;
+enable_query_log;
+
+--echo #
+--echo # Main test of semi-sync replication start here
+--echo #
+
+connection master;
+echo [ on master ];
+
+disable_query_log;
+let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1);
+if (`select '$value' = 'No such row'`)
+{
+    set sql_log_bin=0;
+    INSTALL PLUGIN rpl_semi_sync_master SONAME 'libsemisync_master.so';
+    set global rpl_semi_sync_master_timeout= 5000; /* 5s */
+    set sql_log_bin=1;
+}
+enable_query_log;
+
+echo [ default state of semi-sync on master should be OFF ];
+show variables like 'rpl_semi_sync_master_enabled';
+
+echo [ enable semi-sync on master ];
+set global rpl_semi_sync_master_enabled = 1;
+show variables like 'rpl_semi_sync_master_enabled';
+
+connection slave;
+echo [ on slave ];
+
+disable_query_log;
+let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1);
+if (`select '$value' = 'No such row'`)
+{
+    set sql_log_bin=0;
+    INSTALL PLUGIN rpl_semi_sync_slave SONAME 'libsemisync_slave.so';
+    set sql_log_bin=1;
+}
+enable_query_log;
+
+echo [ default state of semi-sync on slave should be OFF ];
+show variables like 'rpl_semi_sync_slave_enabled';
+
+echo [ enable semi-sync on slave ];
+set global rpl_semi_sync_slave_enabled = 1;
+show variables like 'rpl_semi_sync_slave_enabled';
+source include/start_slave.inc;
+
+connection master;
+echo [ on master ];
+
+# NOTE: Rpl_semi_sync_master_client will only be updated when
+# semi-sync slave has started binlog dump request
+let $status_var= Rpl_semi_sync_master_clients;
+let $status_var_value= 1;
+source include/wait_for_status_var.inc;
+
+echo [ initial master state after the semi-sync slave connected ];
+show status like 'Rpl_semi_sync_master_clients';
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+replace_result $engine_type ENGINE_TYPE;
+eval create table t1(n int) engine = $engine_type;
+
+echo [ master state after CREATE TABLE statement ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+let $i=300;
+echo [ insert records to table ];
+disable_query_log;
+while ($i)
+{
+  eval insert into t1 values ($i);
+  dec $i;
+}
+enable_query_log;
+
+echo [ master status after inserts ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+sync_slave_with_master;
+echo [ on slave ];
+
+echo [ slave status after replicated inserts ];
+show status like 'Rpl_semi_sync_slave_status';
+
+select count(distinct n) from t1;
+select min(n) from t1;
+select max(n) from t1;
+
+source include/stop_slave.inc;
+
+connection master;
+echo [ on master ];
+
+# The first semi-sync check should be on because after slave stop,
+# there are no transactions on the master.
+echo [ master status should be ON ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+show status like 'Rpl_semi_sync_master_clients';
+
+echo [ semi-sync replication of these transactions will fail ];
+insert into t1 values (500);
+delete from t1 where n < 500;
+insert into t1 values (100);
+
+# The second semi-sync check should be off because one transaction
+# times out during waiting.
+echo [ master status should be OFF ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+# Save the master position for later use.
+save_master_pos;
+
+connection slave;
+echo [ on slave ];
+
+echo [ slave status should be OFF ];
+show status like 'Rpl_semi_sync_slave_status';
+source include/start_slave.inc;
+sync_with_master;
+
+echo [ slave status should be ON ];
+show status like 'Rpl_semi_sync_slave_status';
+
+select count(distinct n) from t1;
+select min(n) from t1;
+select max(n) from t1;
+
+connection master;
+echo [ on master ];
+
+echo [ do something to activate semi-sync ];
+drop table t1;
+
+# The third semi-sync check should be on again.
+echo [ master status should be ON again ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+show status like 'Rpl_semi_sync_master_clients';
+
+sync_slave_with_master;
+echo [ on slave ];
+
+source include/stop_slave.inc;
+
+connection master;
+echo [ on master ];
+
+source include/show_master_logs.inc;
+show variables like 'rpl_semi_sync_master_enabled';
+
+echo [ disable semi-sync on the fly ];
+set global rpl_semi_sync_master_enabled=0;
+show variables like 'rpl_semi_sync_master_enabled';
+show status like 'Rpl_semi_sync_master_status';
+
+echo [ enable semi-sync on the fly ];
+set global rpl_semi_sync_master_enabled=1;
+show variables like 'rpl_semi_sync_master_enabled';
+show status like 'Rpl_semi_sync_master_status';
+
+connection slave;
+echo [ on slave ];
+
+source include/start_slave.inc;
+
+connection master;
+echo [ on master ];
+
+replace_result $engine_type ENGINE_TYPE;
+eval create table t1 (a int) engine = $engine_type;
+drop table t1;
+
+##show status like 'Rpl_semi_sync_master_status';
+
+sync_slave_with_master;
+--replace_column 2 #
+show status like 'Rpl_relay%';
+
+echo [ test reset master ];
+connection master;
+echo [ on master];
+
+reset master;
+
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+connection slave;
+echo [ on slave ];
+
+source include/stop_slave.inc;
+reset slave;
+source include/start_slave.inc;
+
+connection master;
+echo [ on master ];
+
+replace_result $engine_type ENGINE_TYPE;
+eval create table t1 (a int) engine = $engine_type;
+insert into t1 values (1);
+insert into t1 values (2), (3);
+
+sync_slave_with_master;
+echo [ on slave ];
+
+select * from t1;
+
+connection master;
+echo [ on master ];
+
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+--echo #
+--echo # Start semi-sync replication without SUPER privilege
+--echo #
+connection master;
+reset master;
+sync_slave_with_master;
+source include/stop_slave.inc;
+reset slave;
+connection master;
+echo [ on master ];
+# Do not binlog the following statement because it will generate
+# different events for ROW and STATEMENT format
+set sql_log_bin=0;
+grant replication slave on *.* to rpl@stripped identified by 'rpl';
+flush privileges;
+set sql_log_bin=1;
+connection slave;
+echo [ on slave ];
+grant replication slave on *.* to rpl@stripped identified by 'rpl';
+flush privileges;
+change master to master_user='rpl',master_password='rpl';
+source include/start_slave.inc;
+connection master;
+echo [ on master ];
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+insert into t1 values (4);
+insert into t1 values (5);
+show status like 'Rpl_semi_sync_master_status';
+show status like 'Rpl_semi_sync_master_no_tx';
+show status like 'Rpl_semi_sync_master_yes_tx';
+
+--echo #
+--echo # Test semi-sync slave connect to non-semi-sync master
+--echo #
+
+connection slave;
+echo [ on slave ];
+source include/stop_slave.inc;
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+
+connection master;
+echo [ on master ];
+set sql_log_bin=0;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+set sql_log_bin=1;
+enable_query_log;
+SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled';
+
+connection slave;
+echo [ on slave ];
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+source include/start_slave.inc;
+
+connection master;
+echo [ on master ];
+insert into t1 values (10);
+sync_slave_with_master;
+echo [ on slave ];
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+
+--echo #
+--echo # Test non-semi-sync slave connect to semi-sync master
+--echo #
+
+connection master;
+set sql_log_bin=0;
+INSTALL PLUGIN rpl_semi_sync_master SONAME 'libsemisync_master.so';
+set global rpl_semi_sync_master_timeout= 5000; /* 5s */
+set sql_log_bin=1;
+set global rpl_semi_sync_master_enabled= 1;
+
+connection slave;
+echo [ on slave ];
+source include/stop_slave.inc;
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+
+echo [ uninstall semi-sync slave plugin ];
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+source include/start_slave.inc;
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+source include/stop_slave.inc;
+
+echo [ reinstall semi-sync slave plugin and disable semi-sync ];
+INSTALL PLUGIN rpl_semi_sync_slave SONAME 'libsemisync_slave.so';
+set global rpl_semi_sync_slave_enabled= 0;
+SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled';
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+source include/start_slave.inc;
+SHOW STATUS LIKE 'Rpl_semi_sync_slave_status';
+
+--echo #
+--echo # Clean up
+--echo #
+
+connection slave;
+source include/stop_slave.inc;
+UNINSTALL PLUGIN rpl_semi_sync_slave;
+
+connection master;
+UNINSTALL PLUGIN rpl_semi_sync_master;
+
+connection slave;
+source include/start_slave.inc;
+
+connection master;
+drop table t1;
+drop user rpl@stripped;
+flush privileges;
+sync_slave_with_master;

=== modified file 'mysql-test/t/create.test'
--- a/mysql-test/t/create.test	2009-02-13 16:30:54 +0000
+++ b/mysql-test/t/create.test	2009-05-28 21:29:31 +0000
@@ -1547,3 +1547,56 @@ drop table `me:i`;
 
 --echo
 --echo End of 5.1 tests
+
+
+###########################################################################
+
+--echo
+--echo # --
+--echo # -- Bug #43054 	Assertion `!table->auto_increment_field_not_null' 
+--echo # --       failed when redefining trigger
+--echo
+
+#--disable_abort_on_error
+
+CREATE TABLE B (
+  pk INTEGER AUTO_INCREMENT,
+  int_key INTEGER NOT NULL,
+  PRIMARY KEY (pk),
+  KEY (int_key)
+);
+
+INSERT IGNORE INTO B VALUES ('9', '9');
+
+CREATE TABLE IF NOT EXISTS t1 ( 
+  `pk` INTEGER NOT NULL AUTO_INCREMENT , 
+  `int` INTEGER ,
+   PRIMARY KEY ( `pk` ) 
+) SELECT `pk` , `int_key` FROM B ;
+
+--delimiter |
+
+CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW 
+BEGIN 
+  INSERT INTO t1 ( `int` ) VALUES (4 ),( 8 ),( 2 ) ; 
+END ; |
+
+--delimiter ;
+--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
+CREATE TABLE IF NOT EXISTS t1 ( 
+  `pk` INTEGER NOT NULL AUTO_INCREMENT , 
+  `int` INTEGER ,
+  PRIMARY KEY ( `pk` ) 
+) SELECT `pk` , `int_key` FROM B ;
+
+--delimiter |
+--error ER_NOT_SUPPORTED_YET
+CREATE TRIGGER f BEFORE INSERT ON t1 FOR EACH ROW 
+BEGIN 
+  UPDATE A SET `pk`=1 WHERE `pk`=0 ; 
+END ;|
+
+--delimiter ;
+
+DROP TABLE t1;
+DROP TABLE B;

=== modified file 'mysql-test/t/ctype_utf8.test'
--- a/mysql-test/t/ctype_utf8.test	2009-06-02 13:04:43 +0000
+++ b/mysql-test/t/ctype_utf8.test	2009-06-11 09:13:52 +0000
@@ -2,6 +2,8 @@
 # Tests with the utf8 character set
 #
 
+--source include/have_innodb.inc
+
 --disable_warnings
 drop table if exists t1,t2;
 --enable_warnings
@@ -256,9 +258,7 @@ drop table t1;
 # Bug 4521: unique key prefix interacts poorly with utf8
 # InnoDB: keys with prefix compression, case insensitive collation.
 #
---disable_warnings
 create table t1 (c varchar(30) character set utf8, unique(c(10))) engine=innodb;
---enable_warnings
 insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z');
 insert into t1 values ('aaaaaaaaaa');
 --error ER_DUP_ENTRY
@@ -306,9 +306,7 @@ drop table t1;
 # Bug 4521: unique key prefix interacts poorly with utf8
 # InnoDB: fixed length keys, case insensitive collation
 #
---disable_warnings
 create table t1 (c char(3) character set utf8, unique (c(2))) engine=innodb;
---enable_warnings
 insert into t1 values ('1'),('2'),('3'),('4'),('x'),('y'),('z');
 insert into t1 values ('a');
 insert into t1 values ('aa');
@@ -383,12 +381,10 @@ drop table t1;
 # Bug 4531: unique key prefix interacts poorly with utf8
 # Check BDB, case insensitive collation
 #
---disable_warnings
 create table t1 (
 c char(10) character set utf8,
 unique key a (c(1))
 ) engine=innodb;
---enable_warnings
 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
 --error ER_DUP_ENTRY
 insert into t1 values ('aa');
@@ -506,12 +502,10 @@ drop table t1;
 # Bug 4531: unique key prefix interacts poorly with utf8
 # Check BDB, binary collation
 #
---disable_warnings
 create table t1 (
 c char(10) character set utf8 collate utf8_bin,
 unique key a (c(1))
 ) engine=innodb;
---enable_warnings
 insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f');
 --error ER_DUP_ENTRY
 insert into t1 values ('aa');
@@ -543,12 +537,10 @@ drop table t1;
 # Bug#4594: column index make = failed for gbk, but like works
 # Check InnoDB
 #
---disable_warnings
 create table t1 (
   str varchar(255) character set utf8 not null,
   key str  (str(2))
 ) engine=innodb;
---enable_warnings
 INSERT INTO t1 VALUES ('str');
 INSERT INTO t1 VALUES ('str2');
 select * from t1 where str='str';
@@ -581,12 +573,10 @@ drop table t1;
 # the same for BDB
 #
 
---disable_warnings
 create table t1 (
   str varchar(255) character set utf8 not null,
   key str (str(2))
 ) engine=innodb;
---enable_warnings
 INSERT INTO t1 VALUES ('str');
 INSERT INTO t1 VALUES ('str2');
 select * from t1 where str='str';
@@ -603,14 +593,11 @@ DROP TABLE t1;
 #
 # Bug #5723: length(<varchar utf8 field>) returns varying results
 #
---disable_warnings
 SET NAMES utf8;
---disable_warnings
 CREATE TABLE t1 (
   subject varchar(255) character set utf8 collate utf8_unicode_ci,
   p varchar(15) character set utf8
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
---enable_warnings
 INSERT INTO t1 VALUES ('谷川俊二と申しますが、t1 VALUES ('aaa','bbb');
 SELECT length(subject) FROM t1;
@@ -661,18 +648,14 @@ DROP TABLE t1;
 # Bug #6019 SELECT tries to use too short prefix index on utf8 data
 #
 set names utf8;
---disable_warnings
 create table t1 (
   a int primary key,
   b varchar(6),
   index b3(b(3))
 ) engine=innodb character set=utf8;
---enable_warnings
 insert into t1 values(1,'foo'),(2,'foobar');
 select * from t1 where b like 'foob%';
---disable_warnings
 alter table t1 engine=innodb;
---enable_warnings
 select * from t1 where b like 'foob%';
 drop table t1;
 
@@ -841,14 +824,12 @@ INSERT INTO t1 VALUES 
 (1,'blah','464','aaa','fkc1c9ilc20x0hgae7lx6j09','ERR','ERR Имри.Афимим.Аеимимримдмримрмрирор имримримримр имридм ирбднримрфмриририм.Дадимфшьмримд им.Адимим01 17:30:43','1234567890'),
 (2,'blah','464','aaa','haxpl2ilc20x00bj4tt2m5ti','11','11 g','G',3,'2005-06-02 22:43:10','1234567890');
 
---disable_warnings
 CREATE TABLE t2 (
   `msisdn` varchar(15) NOT NULL default '',
   `operator_id` int(11) NOT NULL default '0',
   `created` datetime NOT NULL default '0000-00-00 00:00:00',
   UNIQUE KEY `PK_user` (`msisdn`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
---enable_warnings
 
 INSERT INTO t2 VALUES ('1234567890',2,'2005-05-24 13:53:25');
 
@@ -1013,10 +994,8 @@ drop table t1;
 # additional tests from duplicate bug#20744 MySQL return no result
 
 set names utf8;
---disable_warnings
 create table t1 (a varchar(30) not null primary key)
 engine=innodb  default character set utf8 collate utf8_general_ci;
---enable_warnings
 insert into t1 values ('あいうえおかきくけこさしすせi1 from t1 where a like 'さしすせそかき@ select a as gci2 from t1 where a like '�drop table t1;
 
 set names utf8;
---disable_warnings
 create table t1 (a varchar(30) not null primary key)
 engine=innodb default character set utf8 collate utf8_unicode_ci;
---enable_warnings
 insert into t1 values ('あいうえおかきくけこさしすせそ');
 insert into t1 values ('さしすせそかきくけこあいうえお');
 select a as uci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
@@ -1035,10 +1012,8 @@ select a as uci2 from t1 where a like '�drop table t1;
 
 set names utf8;
---disable_warnings
 create table t1 (a varchar(30) not null primary key)
 engine=innodb default character set utf8 collate utf8_bin;
---enable_warnings
 insert into t1 values ('あいうえおかきくけこさしすせそ');
 insert into t1 values ('さしすせそかfrom t1 where a like 'さしすせそかきくselect concat(a, if(b>10, 'x' 'x', 'y' '
 select concat(a, if(b>10, 'x' 'æ', 'y' 'ß')) from t1;
 drop table t1;
 
-
 #
 # Bug#19960: Inconsistent results when joining
 # InnoDB tables using partial UTF8 indexes
 #
---disable_warnings
+
 CREATE TABLE t1 (
   colA int(11) NOT NULL,
   colB varchar(255) character set utf8 NOT NULL,
    PRIMARY KEY  (colA)
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
---enable_warnings
 INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar');
---disable_warnings
 CREATE TABLE t2 (
   colA int(11) NOT NULL,
   colB varchar(255) character set utf8 NOT NULL,
    KEY bad  (colA,colB(3))
 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
---enable_warnings
 INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar');
 SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB
 WHERE t1.colA < 3;

=== modified file 'mysql-test/t/grant.test'
--- a/mysql-test/t/grant.test	2009-06-15 16:18:14 +0000
+++ b/mysql-test/t/grant.test	2009-06-22 12:30:28 +0000
@@ -1850,3 +1850,29 @@ DROP USER mysqltest_u1@localhost;
 --echo
 --echo # End of Bug#38347.
 --echo
+
+--echo #
+--echo # Bug #25863 No database selected error, but documentation 
+--echo #            says * for global allowed
+--echo #
+
+connect(conn1,localhost,root,,*NO-ONE*);
+
+--error ER_NO_DB_ERROR
+GRANT ALL ON * TO mysqltest_1;
+
+GRANT ALL ON *.* TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+DROP USER mysqltest_1;
+
+USE test;
+
+GRANT ALL ON * TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+DROP USER mysqltest_1;
+
+GRANT ALL ON *.* TO mysqltest_1;
+SHOW GRANTS FOR mysqltest_1;
+DROP USER mysqltest_1;
+
+disconnect conn1;

=== modified file 'mysql-test/t/profiling.test'
--- a/mysql-test/t/profiling.test	2009-05-15 12:57:51 +0000
+++ b/mysql-test/t/profiling.test	2009-06-17 07:30:19 +0000
@@ -1,4 +1,4 @@
---source include/have_community_features.inc
+--source include/have_profiling.inc
 
 # Verify that the protocol isn't violated if we ask for profiling info
 # before profiling has recorded anything.

=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test	2009-06-04 13:50:05 +0000
+++ b/mysql-test/t/sp.test	2009-06-17 07:30:19 +0000
@@ -8372,6 +8372,27 @@ DROP FUNCTION f3;
 DROP FUNCTION f4;
 DROP TABLE t1;
 
+#
+# Bug#34197: CREATE PROCEDURE fails when COMMENT truncated in non 
+#            strict SQL mode
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+--enable_warnings
+
+CREATE PROCEDURE p1 ()
+COMMENT
+'12345678901234567890123456789012345678901234567890123456789012345678901234567890'
+BEGIN
+END;
+
+SELECT comment FROM mysql.proc WHERE name = "p1";
+
+SELECT routine_comment FROM information_schema.routines WHERE routine_name = "p1";
+
+DROP PROCEDURE p1;
+
 --echo # ------------------------------------------------------------------
 --echo # -- End of 6.0 tests
 --echo # ------------------------------------------------------------------

=== modified file 'mysql-test/t/sql_mode.test'
--- a/mysql-test/t/sql_mode.test	2009-06-12 21:11:19 +0000
+++ b/mysql-test/t/sql_mode.test	2009-06-22 12:30:28 +0000
@@ -344,3 +344,16 @@ SELECT * FROM mysql.columns_priv WHERE H
 # Cleanup
 DROP TABLE t1;
 DROP TABLE t2;
+
+#
+# Bug#21099 MySQL 5.0.22 silently creates MyISAM tables even though 
+#           InnoDB specified.
+#
+
+SET @org_mode=@@sql_mode;
+SET @@sql_mode='traditional';
+
+# Agreed change was to add NO_ENGINE_SUBSTITUTION to TRADITIONAL sql mode.
+SELECT @@sql_mode LIKE '%NO_ENGINE_SUBSTITUTION%';
+
+SET sql_mode=@org_mode;

=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test	2009-03-27 13:03:00 +0000
+++ b/mysql-test/t/trigger.test	2009-06-16 12:27:49 +0000
@@ -2435,4 +2435,31 @@ DROP TRIGGER trg1;
 DROP TRIGGER trg2;
 DROP TABLE t1;
 
+--echo #
+--echo # Bug#34453 Can't change size of file (Errcode: 1224)
+--echo #
+
+--disable_warnings
+DROP TRIGGER IF EXISTS t1_bi;
+DROP TRIGGER IF EXISTS t1_bd;
+DROP TABLE IF EXISTS t1;
+DROP TEMPORARY TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (s1 INT);
+CREATE TEMPORARY TABLE t2 (s1 INT);
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (0);
+CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t2;
+INSERT INTO t1 VALUES (0);
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t1;
+SELECT * FROM t2;
+-- echo # Reported to give ERROR 14 (HY000): 
+-- echo # Can't change size of file (Errcode: 1224)
+-- echo # on Windows 
+DELETE FROM t1;
+
+DROP TABLE t1;
+DROP TEMPORARY TABLE t2;
+
 --echo End of 6.0 tests.

=== modified file 'mysql-test/t/variables+c.test'
--- a/mysql-test/t/variables+c.test	2007-05-02 18:13:33 +0000
+++ b/mysql-test/t/variables+c.test	2009-06-10 07:55:29 +0000
@@ -1,4 +1,4 @@
---source include/have_community_features.inc
+--source include/have_profiling.inc
 
 #
 # Bug#24822: Patch: uptime_since_flush_status

=== added directory 'plugin/semisync'
=== added file 'plugin/semisync/Makefile.am'
--- a/plugin/semisync/Makefile.am	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/Makefile.am	2009-06-16 05:36:36 +0000
@@ -0,0 +1,35 @@
+# Copyright (C) 2006 MySQL AB
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+## Makefile.am for semi-synchronous replication
+
+pkgplugindir =		$(pkglibdir)/plugin
+INCLUDES =              -I$(top_srcdir)/include \
+			-I$(top_srcdir)/sql \
+			-I$(srcdir)
+
+noinst_HEADERS = semisync.h semisync_master.h semisync_slave.h
+
+pkgplugin_LTLIBRARIES =	libsemisync_master.la libsemisync_slave.la
+
+libsemisync_master_la_LDFLAGS =	-module
+libsemisync_master_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libsemisync_master_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libsemisync_master_la_SOURCES = semisync.cc semisync_master.cc semisync_master_plugin.cc
+
+libsemisync_slave_la_LDFLAGS =	-module
+libsemisync_slave_la_CXXFLAGS=	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libsemisync_slave_la_CFLAGS =	$(AM_CFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+libsemisync_slave_la_SOURCES = semisync.cc semisync_slave.cc semisync_slave_plugin.cc

=== added file 'plugin/semisync/configure.in'
--- a/plugin/semisync/configure.in	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/configure.in	2009-06-17 10:37:04 +0000
@@ -0,0 +1,9 @@
+# configure.in for semi-synchronous replication
+
+AC_INIT(mysql-semi-sync-plugin, 0.2)
+AM_INIT_AUTOMAKE
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
+

=== added file 'plugin/semisync/plug.in'
--- a/plugin/semisync/plug.in	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/plug.in	2009-06-15 13:30:20 +0000
@@ -0,0 +1,3 @@
+MYSQL_PLUGIN(semisync,[Semi-synchronous Replication Plugin],
+        [Semi-synchronous replication plugin.])
+MYSQL_PLUGIN_DYNAMIC(semisync,   [libsemisync_master.la libsemisync_slave.la])

=== added file 'plugin/semisync/semisync.cc'
--- a/plugin/semisync/semisync.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync.cc	2009-06-15 13:30:20 +0000
@@ -0,0 +1,30 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#include "semisync.h"
+
+const unsigned char ReplSemiSyncBase::kPacketMagicNum = 0xef;
+const unsigned char ReplSemiSyncBase::kPacketFlagSync = 0x01;
+
+
+const unsigned long Trace::kTraceGeneral  = 0x0001;
+const unsigned long Trace::kTraceDetail   = 0x0010;
+const unsigned long Trace::kTraceNetWait  = 0x0020;
+const unsigned long Trace::kTraceFunction = 0x0040;
+
+const char  ReplSemiSyncBase::kSyncHeader[2] =
+  {ReplSemiSyncBase::kPacketMagicNum, 0};

=== added file 'plugin/semisync/semisync.h'
--- a/plugin/semisync/semisync.h	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync.h	2009-06-17 10:37:04 +0000
@@ -0,0 +1,95 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#ifndef SEMISYNC_H
+#define SEMISYNC_H
+
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <mysql.h>
+
+typedef uint32_t uint32;
+typedef unsigned long long my_off_t;
+#define FN_REFLEN	512	/* Max length of full path-name */
+void sql_print_error(const char *format, ...);
+void sql_print_warning(const char *format, ...);
+void sql_print_information(const char *format, ...);
+extern unsigned long max_connections;
+
+#define MYSQL_SERVER
+#define HAVE_REPLICATION
+#include <my_global.h>
+#include <my_pthread.h>
+#include <mysql/plugin.h>
+#include <replication.h>
+
+typedef struct st_mysql_show_var SHOW_VAR;
+typedef struct st_mysql_sys_var SYS_VAR;
+
+
+/**
+   This class is used to trace function calls and other process
+   information
+*/
+class Trace {
+public:
+  static const unsigned long kTraceFunction;
+  static const unsigned long kTraceGeneral;
+  static const unsigned long kTraceDetail;
+  static const unsigned long kTraceNetWait;
+
+  unsigned long           trace_level_;                      /* the level for tracing */
+
+  inline void function_enter(const char *func_name)
+  {
+    if (trace_level_ & kTraceFunction)
+      sql_print_information("---> %s enter", func_name);
+  }
+  inline int  function_exit(const char *func_name, int exit_code)
+  {
+    if (trace_level_ & kTraceFunction)
+      sql_print_information("<--- %s exit (%d)", func_name, exit_code);
+    return exit_code;
+  }
+
+  Trace()
+    :trace_level_(0L)
+  {}
+  Trace(unsigned long trace_level)
+    :trace_level_(trace_level)
+  {}
+};
+
+/**
+   Base class for semi-sync master and slave classes
+*/
+class ReplSemiSyncBase
+  :public Trace {
+public:
+  static const char  kSyncHeader[2];              /* three byte packet header */
+
+  /* Constants in network packet header. */
+  static const unsigned char kPacketMagicNum;
+  static const unsigned char kPacketFlagSync;
+};
+
+#endif /* SEMISYNC_H */

=== added file 'plugin/semisync/semisync_master.cc'
--- a/plugin/semisync/semisync_master.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_master.cc	2009-06-17 10:37:04 +0000
@@ -0,0 +1,1184 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#include "semisync_master.h"
+
+#define TIME_THOUSAND 1000
+#define TIME_MILLION  1000000
+#define TIME_BILLION  1000000000
+
+/* This indicates whether semi-synchronous replication is enabled. */
+char rpl_semi_sync_master_enabled;
+unsigned long rpl_semi_sync_master_timeout;
+unsigned long rpl_semi_sync_master_trace_level;
+unsigned long rpl_semi_sync_master_status           = 0;
+unsigned long rpl_semi_sync_master_yes_transactions = 0;
+unsigned long rpl_semi_sync_master_no_transactions  = 0;
+unsigned long rpl_semi_sync_master_off_times        = 0;
+unsigned long rpl_semi_sync_master_timefunc_fails   = 0;
+unsigned long rpl_semi_sync_master_num_timeouts     = 0;
+unsigned long rpl_semi_sync_master_wait_sessions    = 0;
+unsigned long rpl_semi_sync_master_back_wait_pos    = 0;
+unsigned long rpl_semi_sync_master_trx_wait_time    = 0;
+unsigned long long rpl_semi_sync_master_trx_wait_num = 0;
+unsigned long rpl_semi_sync_master_net_wait_time    = 0;
+unsigned long long rpl_semi_sync_master_net_wait_num = 0;
+unsigned long rpl_semi_sync_master_clients          = 0;
+unsigned long long rpl_semi_sync_master_net_wait_total_time = 0;
+unsigned long long rpl_semi_sync_master_trx_wait_total_time = 0;
+
+
+static int getWaitTime(const struct timeval& start_tv);
+
+/*******************************************************************************
+ *
+ * <ActiveTranx> class : manage all active transaction nodes
+ *
+ ******************************************************************************/
+
+ActiveTranx::ActiveTranx(int max_connections,
+			 pthread_mutex_t *lock,
+			 unsigned long trace_level)
+  : Trace(trace_level), num_transactions_(max_connections),
+    num_entries_(max_connections << 1),
+    lock_(lock)
+{
+  /* Allocate the memory for the array */
+  node_array_ = new TranxNode[num_transactions_];
+  for (int idx = 0; idx < num_transactions_; ++idx)
+  {
+    node_array_[idx].log_pos_     = 0;
+    node_array_[idx].hash_next_   = NULL;
+    node_array_[idx].next_        = node_array_ + idx + 1;
+
+    node_array_[idx].log_name_    = new char[FN_REFLEN];
+    node_array_[idx].log_name_[0] = '\x0';
+  }
+  node_array_[num_transactions_-1].next_ = NULL;
+
+  /* All nodes in the array go to the pool initially. */
+  free_pool_ = node_array_;
+
+  /* No transactions are in the list initially. */
+  trx_front_ = NULL;
+  trx_rear_  = NULL;
+
+  /* Create the hash table to find a transaction's ending event. */
+  trx_htb_ = new TranxNode *[num_entries_];
+  for (int idx = 0; idx < num_entries_; ++idx)
+    trx_htb_[idx] = NULL;
+
+  sql_print_information("Semi-sync replication initialized for %d "
+                        "transactions.", num_transactions_);
+}
+
+ActiveTranx::~ActiveTranx()
+{
+  for (int idx = 0; idx < num_transactions_; ++idx)
+  {
+    delete node_array_[idx].log_name_;
+    node_array_[idx].log_name_ = NULL;
+  }
+
+  delete [] node_array_;
+  delete [] trx_htb_;
+
+  node_array_       = NULL;
+  trx_htb_          = NULL;
+  num_transactions_ = 0;
+  num_entries_      = 0;
+}
+
+unsigned int ActiveTranx::calc_hash(const unsigned char *key,
+                                    unsigned int length)
+{
+  unsigned int nr = 1, nr2 = 4;
+
+  /* The hash implementation comes from calc_hashnr() in mysys/hash.c. */
+  while (length--)
+  {
+    nr  ^= (((nr & 63)+nr2)*((unsigned int) (unsigned char) *key++))+ (nr << 8);
+    nr2 += 3;
+  }
+  return((unsigned int) nr);
+}
+
+unsigned int ActiveTranx::get_hash_value(const char *log_file_name,
+				 my_off_t    log_file_pos)
+{
+  unsigned int hash1 = calc_hash((const unsigned char *)log_file_name,
+                                 strlen(log_file_name));
+  unsigned int hash2 = calc_hash((const unsigned char *)(&log_file_pos),
+                                 sizeof(log_file_pos));
+
+  return (hash1 + hash2) % num_entries_;
+}
+
+ActiveTranx::TranxNode* ActiveTranx::alloc_tranx_node()
+{
+  TranxNode *ptr = free_pool_;
+
+  if (free_pool_)
+  {
+    free_pool_ = free_pool_->next_;
+    ptr->next_ = NULL;
+    ptr->hash_next_ = NULL;
+  }
+
+  return ptr;
+}
+
+int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1,
+			 const char *log_file_name2, my_off_t log_file_pos2)
+{
+  int cmp = strcmp(log_file_name1, log_file_name2);
+
+  if (cmp != 0)
+    return cmp;
+
+  if (log_file_pos1 > log_file_pos2)
+    return 1;
+  else if (log_file_pos1 < log_file_pos2)
+    return -1;
+  return 0;
+}
+
+int ActiveTranx::insert_tranx_node(const char *log_file_name,
+				   my_off_t log_file_pos)
+{
+  const char *kWho = "ActiveTranx:insert_tranx_node";
+  TranxNode  *ins_node;
+  int         result = 0;
+  unsigned int        hash_val;
+
+  function_enter(kWho);
+
+  ins_node = alloc_tranx_node();
+  if (!ins_node)
+  {
+    sql_print_error("%s: transaction node allocation failed for: (%s, %lu)",
+                    kWho, log_file_name, (unsigned long)log_file_pos);
+    result = -1;
+    goto l_end;
+  }
+
+  /* insert the binlog position in the active transaction list. */
+  strcpy(ins_node->log_name_, log_file_name);
+  ins_node->log_pos_ = log_file_pos;
+
+  if (!trx_front_)
+  {
+    /* The list is empty. */
+    trx_front_ = trx_rear_ = ins_node;
+  }
+  else
+  {
+    int cmp = compare(ins_node, trx_rear_);
+    if (cmp > 0)
+    {
+      /* Compare with the tail first.  If the transaction happens later in
+       * binlog, then make it the new tail.
+       */
+      trx_rear_->next_ = ins_node;
+      trx_rear_        = ins_node;
+    }
+    else
+    {
+      /* Otherwise, it is an error because the transaction should hold the
+       * mysql_bin_log.LOCK_log when appending events.
+       */
+      sql_print_error("%s: binlog write out-of-order, tail (%s, %lu), "
+                      "new node (%s, %lu)", kWho,
+                      trx_rear_->log_name_, (unsigned long)trx_rear_->log_pos_,

+                      ins_node->log_name_, (unsigned long)ins_node->log_pos_);
+      result = -1;
+      goto l_end;
+    }
+  }
+
+  hash_val = get_hash_value(ins_node->log_name_, ins_node->log_pos_);
+  ins_node->hash_next_ = trx_htb_[hash_val];
+  trx_htb_[hash_val]   = ins_node;
+
+  if (trace_level_ & kTraceDetail)
+    sql_print_information("%s: insert (%s, %lu) in entry(%u)", kWho,
+                          ins_node->log_name_, (unsigned long)ins_node->log_pos_,
+                          hash_val);
+
+ l_end:
+  return function_exit(kWho, result);
+}
+
+bool ActiveTranx::is_tranx_end_pos(const char *log_file_name,
+				   my_off_t    log_file_pos)
+{
+  const char *kWho = "ActiveTranx::is_tranx_end_pos";
+  function_enter(kWho);
+
+  unsigned int hash_val = get_hash_value(log_file_name, log_file_pos);
+  TranxNode *entry = trx_htb_[hash_val];
+
+  while (entry != NULL)
+  {
+    if (compare(entry, log_file_name, log_file_pos) == 0)
+      break;
+
+    entry = entry->hash_next_;
+  }
+
+  if (trace_level_ & kTraceDetail)
+    sql_print_information("%s: probe (%s, %lu) in entry(%u)", kWho,
+                          log_file_name, (unsigned long)log_file_pos, hash_val);
+
+  function_exit(kWho, (entry != NULL));
+  return (entry != NULL);
+}
+
+int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name,
+					  my_off_t log_file_pos)
+{
+  const char *kWho = "ActiveTranx::::clear_active_tranx_nodes";
+  TranxNode *new_front;
+
+  function_enter(kWho);
+
+  if (log_file_name != NULL)
+  {
+    new_front = trx_front_;
+
+    while (new_front)
+    {
+      if (compare(new_front, log_file_name, log_file_pos) > 0)
+        break;
+      new_front = new_front->next_;
+    }
+  }
+  else
+  {
+    /* If log_file_name is NULL, clear everything. */
+    new_front = NULL;
+  }
+
+  if (new_front == NULL)
+  {
+    /* No active transaction nodes after the call. */
+
+    /* Clear the hash table. */
+    memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *));
+
+    /* Clear the active transaction list. */
+    if (trx_front_ != NULL)
+    {
+      trx_rear_->next_ = free_pool_;
+      free_pool_ = trx_front_;
+      trx_front_ = NULL;
+      trx_rear_  = NULL;
+    }
+
+    if (trace_level_ & kTraceDetail)
+      sql_print_information("%s: free all nodes back to free list", kWho);
+  }
+  else if (new_front != trx_front_)
+  {
+    TranxNode *curr_node, *next_node;
+
+    /* Delete all transaction nodes before the confirmation point. */
+    int n_frees = 0;
+    curr_node = trx_front_;
+    while (curr_node != new_front)
+    {
+      next_node = curr_node->next_;
+
+      /* Put the node in the memory pool. */
+      curr_node->next_ = free_pool_;
+      free_pool_       = curr_node;
+      n_frees++;
+
+      /* Remove the node from the hash table. */
+      unsigned int hash_val = get_hash_value(curr_node->log_name_, curr_node->log_pos_);
+      TranxNode **hash_ptr = &(trx_htb_[hash_val]);
+      while ((*hash_ptr) != NULL)
+      {
+        if ((*hash_ptr) == curr_node)
+	{
+          (*hash_ptr) = curr_node->hash_next_;
+          break;
+        }
+        hash_ptr = &((*hash_ptr)->hash_next_);
+      }
+
+      curr_node = next_node;
+    }
+
+    trx_front_ = new_front;
+
+    if (trace_level_ & kTraceDetail)
+      sql_print_information("%s: free %d nodes back until pos (%s, %lu)",
+                            kWho, n_frees,
+                            trx_front_->log_name_, (unsigned long)trx_front_->log_pos_);
+  }
+
+  return function_exit(kWho, 0);
+}
+
+
+/*******************************************************************************
+ *
+ * <ReplSemiSyncMaster> class: the basic code layer for sync-replication master.
+ * <ReplSemiSyncSlave>  class: the basic code layer for sync-replication slave.
+ *
+ * The most important functions during semi-syn replication listed:
+ *
+ * Master:
+ *  . reportReplyBinlog(): called by the binlog dump thread when it receives
+ *                         the slave's status information.
+ *  . updateSyncHeader():  based on transaction waiting information, decide
+ *                         whether to request the slave to reply.
+ *  . writeTraxInBinlog(): called by the transaction thread when it finishes
+ *                         writing all transaction events in binlog.
+ *  . commitTrx():         transaction thread wait for the slave reply.
+ *
+ * Slave:
+ *  . slaveReadSyncHeader(): read the semi-sync header from the master, get the
+ *                         sync status and get the payload for events.
+ *  . slaveReply():        reply to the master about the replication progress.
+ *
+ ******************************************************************************/
+
+ReplSemiSyncMaster::ReplSemiSyncMaster()
+  : active_tranxs_(NULL),
+    init_done_(false),
+    reply_file_name_inited_(false),
+    reply_file_pos_(0L),
+    wait_file_name_inited_(false),
+    wait_file_pos_(0),
+    master_enabled_(false),
+    wait_timeout_(0L),
+    state_(0),
+    enabled_transactions_(0),
+    disabled_transactions_(0),
+    switched_off_times_(0),
+    timefunc_fails_(0),
+    wait_sessions_(0),
+    wait_backtraverse_(0),
+    total_trx_wait_num_(0),
+    total_trx_wait_time_(0),
+    total_net_wait_num_(0),
+    total_net_wait_time_(0),
+    max_transactions_(0L)
+{
+  strcpy(reply_file_name_, "");
+  strcpy(wait_file_name_, "");
+}
+
+int ReplSemiSyncMaster::initObject()
+{
+  int result;
+  const char *kWho = "ReplSemiSyncMaster::initObject";
+
+  if (init_done_)
+  {
+    fprintf(stderr, "%s called twice\n", kWho);
+    return 1;
+  }
+  init_done_ = true;
+
+  /* References to the parameter works after set_options(). */
+  setWaitTimeout(rpl_semi_sync_master_timeout);
+  setTraceLevel(rpl_semi_sync_master_trace_level);
+  max_transactions_ = (int)max_connections;
+
+  /* Mutex initialization can only be done after MY_INIT(). */
+  pthread_mutex_init(&LOCK_binlog_, MY_MUTEX_INIT_FAST);
+  pthread_cond_init(&COND_binlog_send_, NULL);
+
+  if (rpl_semi_sync_master_enabled)
+    result = enableMaster();
+  else
+    result = disableMaster();
+
+  return result;
+}
+
+int ReplSemiSyncMaster::enableMaster()
+{
+  int result = 0;
+
+  /* Must have the lock when we do enable of disable. */
+  lock();
+
+  if (!getMasterEnabled())
+  {
+    active_tranxs_ = new ActiveTranx(max_connections,
+				     &LOCK_binlog_,
+				     trace_level_);
+    if (active_tranxs_ != NULL)
+    {
+      commit_file_name_inited_ = false;
+      reply_file_name_inited_  = false;
+      wait_file_name_inited_   = false;
+
+      set_master_enabled(true);
+      state_ = true;
+      sql_print_information("Semi-sync replication enabled on the master.");
+    }
+    else
+    {
+      sql_print_information("Semi-sync replication not able to allocate memory.");
+      result = -1;
+    }
+  }
+
+  unlock();
+
+  return result;
+}
+
+int ReplSemiSyncMaster::disableMaster()
+{
+  /* Must have the lock when we do enable of disable. */
+  lock();
+
+  if (getMasterEnabled())
+  {
+    /* Switch off the semi-sync first so that waiting transaction will be
+     * waken up.
+     */
+    switch_off();
+
+    assert(active_tranxs_ != NULL);
+    delete active_tranxs_;
+    active_tranxs_ = NULL;
+
+    reply_file_name_inited_ = false;
+    wait_file_name_inited_  = false;
+    commit_file_name_inited_ = false;
+
+    set_master_enabled(false);
+    sql_print_information("Semi-sync replication disabled on the master.");
+  }
+
+  unlock();
+
+  return 0;
+}
+
+ReplSemiSyncMaster::~ReplSemiSyncMaster()
+{
+  if (init_done_)
+  {
+    pthread_mutex_destroy(&LOCK_binlog_);
+    pthread_cond_destroy(&COND_binlog_send_);
+  }
+
+  delete active_tranxs_;
+}
+
+void ReplSemiSyncMaster::lock()
+{
+  pthread_mutex_lock(&LOCK_binlog_);
+}
+
+void ReplSemiSyncMaster::unlock()
+{
+  pthread_mutex_unlock(&LOCK_binlog_);
+}
+
+void ReplSemiSyncMaster::cond_broadcast()
+{
+  pthread_cond_broadcast(&COND_binlog_send_);
+}
+
+int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time)
+{
+  const char *kWho = "ReplSemiSyncMaster::cond_timewait()";
+  int wait_res;
+
+  function_enter(kWho);
+  wait_res = pthread_cond_timedwait(&COND_binlog_send_,
+                                    &LOCK_binlog_, wait_time);
+  return function_exit(kWho, wait_res);
+}
+
+void ReplSemiSyncMaster::add_slave()
+{
+  lock();
+  rpl_semi_sync_master_clients++;
+  unlock();
+}
+
+void ReplSemiSyncMaster::remove_slave()
+{
+  lock();
+  rpl_semi_sync_master_clients--;
+  unlock();
+}
+
+bool ReplSemiSyncMaster::is_semi_sync_slave()
+{
+  int null_value;
+  long long val= 0;
+  get_user_var_int("rpl_semi_sync_slave", &val, &null_value);
+  return val;
+}
+
+int ReplSemiSyncMaster::reportReplyBinlog(const char *log_file_pos)
+{
+  char log_name[FN_REFLEN];
+  char *endptr;
+  my_off_t log_pos= strtoull(log_file_pos, &endptr, 10);
+  if (!log_pos || !endptr || *endptr != ':' )
+    return 1;
+  endptr++;                                     // skip the ':' seperator
+  strncpy(log_name, endptr, FN_REFLEN);
+  uint32 server_id= 0;
+  return reportReplyBinlog(server_id, log_name, log_pos);
+}
+
+int ReplSemiSyncMaster::reportReplyBinlog(uint32 server_id,
+					  const char *log_file_name,
+					  my_off_t log_file_pos)
+{
+  const char *kWho = "ReplSemiSyncMaster::reportReplyBinlog";
+  int   cmp;
+  bool  can_release_threads = false;
+  bool  need_copy_send_pos = true;
+
+  if (!(getMasterEnabled()))
+    return 0;
+
+  function_enter(kWho);
+
+  lock();
+
+  /* This is the real check inside the mutex. */
+  if (!getMasterEnabled())
+    goto l_end;
+
+  if (!is_on())
+    /* We check to see whether we can switch semi-sync ON. */
+    try_switch_on(server_id, log_file_name, log_file_pos);
+
+  /* The position should increase monotonically, if there is only one
+   * thread sending the binlog to the slave.
+   * In reality, to improve the transaction availability, we allow multiple
+   * sync replication slaves.  So, if any one of them get the transaction,
+   * the transaction session in the primary can move forward.
+   */
+  if (reply_file_name_inited_)
+  {
+    cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                               reply_file_name_, reply_file_pos_);
+
+    /* If the requested position is behind the sending binlog position,
+     * would not adjust sending binlog position.
+     * We based on the assumption that there are multiple semi-sync slave,
+     * and at least one of them shou/ld be up to date.
+     * If all semi-sync slaves are behind, at least initially, the primary
+     * can find the situation after the waiting timeout.  After that, some
+     * slaves should catch up quickly.
+     */
+    if (cmp < 0)
+    {
+      /* If the position is behind, do not copy it. */
+      need_copy_send_pos = false;
+    }
+  }
+
+  if (need_copy_send_pos)
+  {
+    strcpy(reply_file_name_, log_file_name);
+    reply_file_pos_ = log_file_pos;
+    reply_file_name_inited_ = true;
+
+    /* Remove all active transaction nodes before this point. */
+    assert(active_tranxs_ != NULL);
+    active_tranxs_->clear_active_tranx_nodes(log_file_name, log_file_pos);
+
+    if (trace_level_ & kTraceDetail)
+      sql_print_information("%s: Got reply at (%s, %lu)", kWho,
+                            log_file_name, (unsigned long)log_file_pos);
+  }
+
+  if (wait_sessions_ > 0)
+  {
+    /* Let us check if some of the waiting threads doing a trx
+     * commit can now proceed.
+     */
+    cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_,
+                               wait_file_name_, wait_file_pos_);
+    if (cmp >= 0)
+    {
+      /* Yes, at least one waiting thread can now proceed:
+       * let us release all waiting threads with a broadcast
+       */
+      can_release_threads = true;
+      wait_file_name_inited_ = false;
+    }
+  }
+
+ l_end:
+  unlock();
+
+  if (can_release_threads)
+  {
+    if (trace_level_ & kTraceDetail)
+      sql_print_information("%s: signal all waiting threads.", kWho);
+
+    cond_broadcast();
+  }
+
+  return function_exit(kWho, 0);
+}
+
+int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
+				  my_off_t trx_wait_binlog_pos)
+{
+  const char *kWho = "ReplSemiSyncMaster::commitTrx";
+
+  function_enter(kWho);
+
+  if (getMasterEnabled() && trx_wait_binlog_name)
+  {
+    struct timeval start_tv;
+    struct timespec abstime;
+    int wait_result, start_time_err;
+    const char *old_msg= 0;
+
+    start_time_err = gettimeofday(&start_tv, 0);
+
+    /* Acquire the mutex. */
+    lock();
+
+    /* This must be called after acquired the lock */
+    old_msg= thd_enter_cond(NULL, &COND_binlog_send_, &LOCK_binlog_,
+                            "Waiting for semi-sync ACK from slave");
+
+    /* This is the real check inside the mutex. */
+    if (!getMasterEnabled() || !is_on() || !rpl_semi_sync_master_clients)
+      goto l_end;
+
+    if (trace_level_ & kTraceDetail)
+    {
+      sql_print_information("%s: wait pos (%s, %lu), repl(%d)\n", kWho,
+                            trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos,
+                            (int)is_on());
+    }
+
+    while (is_on())
+    {
+      int cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_,
+                                     trx_wait_binlog_name, trx_wait_binlog_pos);
+      if (cmp >= 0)
+      {
+        /* We have already sent the relevant binlog to the slave: no need to
+         * wait here.
+         */
+        if (trace_level_ & kTraceDetail)
+          sql_print_information("%s: Binlog reply is ahead (%s, %lu),",
+                                kWho, reply_file_name_, (unsigned long)reply_file_pos_);
+        break;
+      }
+
+      /* Let us update the info about the minimum binlog position of waiting
+       * threads.
+       */
+      if (wait_file_name_inited_)
+      {
+        cmp = ActiveTranx::compare(trx_wait_binlog_name, trx_wait_binlog_pos,
+                                   wait_file_name_, wait_file_pos_);
+        if (cmp <= 0)
+	{
+          /* This thd has a lower position, let's update the minimum info. */
+          strcpy(wait_file_name_, trx_wait_binlog_name);
+          wait_file_pos_ = trx_wait_binlog_pos;
+
+          wait_backtraverse_++;
+          if (trace_level_ & kTraceDetail)
+            sql_print_information("%s: move back wait position (%s, %lu),",
+                                  kWho, wait_file_name_, (unsigned long)wait_file_pos_);
+        }
+      }
+      else
+      {
+        strcpy(wait_file_name_, trx_wait_binlog_name);
+        wait_file_pos_ = trx_wait_binlog_pos;
+        wait_file_name_inited_ = true;
+
+        if (trace_level_ & kTraceDetail)
+          sql_print_information("%s: init wait position (%s, %lu),",
+                                kWho, wait_file_name_, (unsigned long)wait_file_pos_);
+      }
+
+      if (start_time_err == 0)
+      {
+        int diff_usecs = start_tv.tv_usec + wait_timeout_ * TIME_THOUSAND;
+
+        /* Calcuate the waiting period. */
+        abstime.tv_sec = start_tv.tv_sec;
+        if (diff_usecs < TIME_MILLION)
+	{
+          abstime.tv_nsec = diff_usecs * TIME_THOUSAND;
+        }
+	else
+	{
+          while (diff_usecs >= TIME_MILLION)
+	  {
+            abstime.tv_sec++;
+            diff_usecs -= TIME_MILLION;
+          }
+          abstime.tv_nsec = diff_usecs * TIME_THOUSAND;
+        }
+
+        /* In semi-synchronous replication, we wait until the binlog-dump
+         * thread has received the reply on the relevant binlog segment from the
+         * replication slave.
+         *
+         * Let us suspend this thread to wait on the condition;
+         * when replication has progressed far enough, we will release
+         * these waiting threads.
+         */
+        wait_sessions_++;
+
+        if (trace_level_ & kTraceDetail)
+          sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)",
+                                kWho, wait_timeout_,
+                                wait_file_name_, (unsigned long)wait_file_pos_);
+
+        wait_result = cond_timewait(&abstime);
+        wait_sessions_--;
+
+        if (wait_result != 0)
+	{
+          if (trace_level_ & kTraceGeneral)
+	  {
+            /* This is a real wait timeout. */
+            sql_print_warning("Replication semi-sync not sent binlog to "
+                            "slave within the timeout %lu ms - OFF.",
+                            wait_timeout_);
+            sql_print_warning("          semi-sync up to file %s, position %lu",
+                            reply_file_name_, (unsigned long)reply_file_pos_);
+            sql_print_warning("          transaction needs file %s, position %lu",
+                            trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
+          }
+          total_wait_timeouts_++;
+
+          /* switch semi-sync off */
+          switch_off();
+        }
+	else
+	{
+          int wait_time;
+
+          wait_time = getWaitTime(start_tv);
+          if (wait_time < 0)
+	  {
+            if (trace_level_ & kTraceGeneral)
+	    {
+              /* This is a time/gettimeofday function call error. */
+              sql_print_error("Replication semi-sync gettimeofday fail1 at "
+                              "wait position (%s, %lu)",
+                              trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
+            }
+            timefunc_fails_++;
+          }
+	  else
+	  {
+            total_trx_wait_num_++;
+            total_trx_wait_time_ += wait_time;
+          }
+        }
+      }
+      else
+      {
+        if (trace_level_ & kTraceGeneral)
+	{
+          /* This is a gettimeofday function call error. */
+          sql_print_error("Replication semi-sync gettimeofday fail2 at "
+                          "wait position (%s, %lu)",
+                          trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos);
+        }
+        timefunc_fails_++;
+
+        /* switch semi-sync off */
+        switch_off();
+      }
+    }
+
+  l_end:
+    /* Update the status counter. */
+    if (is_on())
+      enabled_transactions_++;
+    else
+      disabled_transactions_++;
+
+    /* The lock held will be released by thd_exit_cond, so no need to
+       call unlock() here */
+    thd_exit_cond(NULL, old_msg);
+  }
+
+  return function_exit(kWho, 0);
+}
+
+/* Indicate that semi-sync replication is OFF now.
+ * 
+ * What should we do when it is disabled?  The problem is that we want
+ * the semi-sync replication enabled again when the slave catches up
+ * later.  But, it is not that easy to detect that the slave has caught
+ * up.  This is caused by the fact that MySQL's replication protocol is
+ * asynchronous, meaning that if the master does not use the semi-sync
+ * protocol, the slave would not send anything to the master.
+ * Still, if the master is sending (N+1)-th event, we assume that it is
+ * an indicator that the slave has received N-th event and earlier ones.
+ *
+ * If semi-sync is disabled, all transactions still update the wait
+ * position with the last position in binlog.  But no transactions will
+ * wait for confirmations and the active transaction list would not be
+ * maintained.  In binlog dump thread, updateSyncHeader() checks whether
+ * the current sending event catches up with last wait position.  If it
+ * does match, semi-sync will be switched on again.
+ */
+int ReplSemiSyncMaster::switch_off()
+{
+  const char *kWho = "ReplSemiSyncMaster::switch_off";
+  int result;
+
+  function_enter(kWho);
+  state_ = false;
+
+  /* Clear the active transaction list. */
+  assert(active_tranxs_ != NULL);
+  result = active_tranxs_->clear_active_tranx_nodes(NULL, 0);
+
+  switched_off_times_++;
+  wait_file_name_inited_   = false;
+  reply_file_name_inited_  = false;
+  commit_file_name_inited_ = false;
+  cond_broadcast();                            /* wake up all waiting threads */
+
+  return function_exit(kWho, result);
+}
+
+int ReplSemiSyncMaster::try_switch_on(int server_id,
+				      const char *log_file_name,
+				      my_off_t log_file_pos)
+{
+  const char *kWho = "ReplSemiSyncMaster::try_switch_on";
+  bool semi_sync_on = false;
+
+  function_enter(kWho);
+
+  /* If the current sending event's position is larger than or equal to the
+   * 'largest' commit transaction binlog position, the slave is already
+   * catching up now and we can switch semi-sync on here.
+   * If commit_file_name_inited_ indicates there are no recent transactions,
+   * we can enable semi-sync immediately.
+   */
+  if (commit_file_name_inited_)
+  {
+    int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                                   commit_file_name_, commit_file_pos_);
+    semi_sync_on = (cmp >= 0);
+  }
+  else
+  {
+    semi_sync_on = true;
+  }
+
+  if (semi_sync_on)
+  {
+    /* Switch semi-sync replication on. */
+    state_ = true;
+
+    if (trace_level_ & kTraceGeneral)
+      sql_print_information("%s switch semi-sync ON with server(%d) "
+                            "at (%s, %lu), repl(%d)",
+                            kWho, server_id, log_file_name,
+                            (unsigned long)log_file_pos, (int)is_on());
+  }
+
+  return function_exit(kWho, 0);
+}
+
+int ReplSemiSyncMaster::reserveSyncHeader(unsigned char *header,
+					  unsigned long size)
+{
+  const char *kWho = "ReplSemiSyncMaster::reserveSyncHeader";
+  function_enter(kWho);
+
+  int hlen=0;
+  if (!is_semi_sync_slave())
+  {
+    hlen= 0;
+  }
+  else
+  {
+    /* No enough space for the extra header, disable semi-sync master */
+    if (sizeof(kSyncHeader) > size)
+    {
+      disableMaster();
+      return 0;
+    }
+    
+    /* Set the magic number and the sync status.  By default, no sync
+     * is required.
+     */
+    memcpy(header, kSyncHeader, sizeof(kSyncHeader));
+    hlen= sizeof(kSyncHeader);
+  }
+  return function_exit(kWho, hlen);
+}
+
+int ReplSemiSyncMaster::updateSyncHeader(unsigned char *packet,
+					 const char *log_file_name,
+					 my_off_t log_file_pos,
+					 uint32 server_id)
+{
+  const char *kWho = "ReplSemiSyncMaster::updateSyncHeader";
+  int  cmp = 0;
+  bool sync = false;
+
+  /* If the semi-sync master is not enabled, or the slave is not a semi-sync
+   * target, do not request replies from the slave.
+   */
+  if (!getMasterEnabled() || !is_semi_sync_slave())
+  {
+    sync = false;
+    return 0;
+  }
+
+  function_enter(kWho);
+
+  lock();
+
+  /* This is the real check inside the mutex. */
+  if (!getMasterEnabled())
+  {
+    sync = false;
+    goto l_end;
+  }
+
+  if (is_on())
+  {
+    /* semi-sync is ON */
+    sync = false;     /* No sync unless a transaction is involved. */
+
+    if (reply_file_name_inited_)
+    {
+      cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                                 reply_file_name_, reply_file_pos_);
+      if (cmp <= 0)
+      {
+        /* If we have already got the reply for the event, then we do
+         * not need to sync the transaction again.
+         */
+        goto l_end;
+      }
+    }
+
+    if (wait_file_name_inited_)
+    {
+      cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                                 wait_file_name_, wait_file_pos_);
+    }
+    else
+    {
+      cmp = 1;
+    }
+    
+    /* If we are already waiting for some transaction replies which
+     * are later in binlog, do not wait for this one event.
+     */
+    if (cmp >= 0)
+    {
+      /* 
+       * We only wait if the event is a transaction's ending event.
+       */
+      assert(active_tranxs_ != NULL);
+      sync = active_tranxs_->is_tranx_end_pos(log_file_name,
+                                               log_file_pos);
+    }
+  }
+  else
+  {
+    if (commit_file_name_inited_)
+    {
+      int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                                     commit_file_name_, commit_file_pos_);
+      sync = (cmp >= 0);
+    }
+    else
+    {
+      sync = true;
+    }
+  }
+
+  if (trace_level_ & kTraceDetail)
+    sql_print_information("%s: server(%d), (%s, %lu) sync(%d), repl(%d)",
+                          kWho, server_id, log_file_name,
+                          (unsigned long)log_file_pos, sync, (int)is_on());
+
+ l_end:
+  unlock();
+
+  /* We do not need to clear sync flag because we set it to 0 when we
+   * reserve the packet header.
+   */
+  if (sync)
+    (packet)[2] = kPacketFlagSync;
+
+  return function_exit(kWho, 0);
+}
+
+int ReplSemiSyncMaster::writeTranxInBinlog(const char* log_file_name,
+					   my_off_t log_file_pos)
+{
+  const char *kWho = "ReplSemiSyncMaster::writeTranxInBinlog";
+  int result = 0;
+
+  function_enter(kWho);
+
+  lock();
+
+  /* This is the real check inside the mutex. */
+  if (!getMasterEnabled())
+    goto l_end;
+
+  /* Update the 'largest' transaction commit position seen so far even
+   * though semi-sync is switched off.
+   * It is much better that we update commit_file_* here, instead of
+   * inside commitTrx().  This is mostly because updateSyncHeader()
+   * will watch for commit_file_* to decide whether to switch semi-sync
+   * on. The detailed reason is explained in function updateSyncHeader().
+   */
+  if (commit_file_name_inited_)
+  {
+    int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
+                                   commit_file_name_, commit_file_pos_);
+    if (cmp > 0)
+    {
+      /* This is a larger position, let's update the maximum info. */
+      strcpy(commit_file_name_, log_file_name);
+      commit_file_pos_ = log_file_pos;
+    }
+  }
+  else
+  {
+    strcpy(commit_file_name_, log_file_name);
+    commit_file_pos_ = log_file_pos;
+    commit_file_name_inited_ = true;
+  }
+
+  if (is_on())
+  {
+    assert(active_tranxs_ != NULL);
+    result = active_tranxs_->insert_tranx_node(log_file_name, log_file_pos);
+  }
+
+ l_end:
+  unlock();
+
+  return function_exit(kWho, result);
+}
+
+int ReplSemiSyncMaster::resetMaster()
+{
+  const char *kWho = "ReplSemiSyncMaster::resetMaster";
+  int result = 0;
+
+  function_enter(kWho);
+
+
+  lock();
+
+  state_ = getMasterEnabled()? 1 : 0;
+
+  wait_file_name_inited_   = false;
+  reply_file_name_inited_  = false;
+  commit_file_name_inited_ = false;
+
+  enabled_transactions_ = 0;
+  disabled_transactions_ = 0;
+  switched_off_times_ = 0;
+  timefunc_fails_ = 0;
+  wait_sessions_ = 0;
+  wait_backtraverse_ = 0;
+  total_trx_wait_num_ = 0;
+  total_trx_wait_time_ = 0;
+  total_net_wait_num_ = 0;
+  total_net_wait_time_ = 0;
+
+  unlock();
+
+  return function_exit(kWho, result);
+}
+
+void ReplSemiSyncMaster::setExportStats()
+{
+  lock();
+
+  rpl_semi_sync_master_status           = state_ ? 1 : 0;
+  rpl_semi_sync_master_yes_transactions = enabled_transactions_;
+  rpl_semi_sync_master_no_transactions  = disabled_transactions_;
+  rpl_semi_sync_master_off_times        = switched_off_times_;
+  rpl_semi_sync_master_timefunc_fails   = timefunc_fails_;
+  rpl_semi_sync_master_num_timeouts     = total_wait_timeouts_;
+  rpl_semi_sync_master_wait_sessions    = wait_sessions_;
+  rpl_semi_sync_master_back_wait_pos    = wait_backtraverse_;
+  rpl_semi_sync_master_trx_wait_num     = total_trx_wait_num_;
+  rpl_semi_sync_master_trx_wait_time    =
+    ((total_trx_wait_num_) ?
+     (unsigned long)((double)total_trx_wait_time_ /
+             ((double)total_trx_wait_num_)) : 0);
+  rpl_semi_sync_master_net_wait_num     = total_net_wait_num_;
+  rpl_semi_sync_master_net_wait_time    =
+    ((total_net_wait_num_) ?
+     (unsigned long)((double)total_net_wait_time_ /
+             ((double)total_net_wait_num_)) : 0);
+
+  rpl_semi_sync_master_net_wait_total_time = total_net_wait_time_;
+  rpl_semi_sync_master_trx_wait_total_time = total_trx_wait_time_;
+
+  unlock();
+}
+
+/* Get the waiting time given the wait's staring time.
+ * 
+ * Return:
+ *  >= 0: the waiting time in microsecons(us)
+ *   < 0: error in gettimeofday or time back traverse
+ */
+static int getWaitTime(const struct timeval& start_tv)
+{
+  unsigned long long start_usecs, end_usecs;
+  struct timeval end_tv;
+  int end_time_err;
+
+  /* Starting time in microseconds(us). */
+  start_usecs = start_tv.tv_sec * TIME_MILLION + start_tv.tv_usec;
+
+  /* Get the wait time interval. */
+  end_time_err = gettimeofday(&end_tv, 0);
+
+  /* Ending time in microseconds(us). */
+  end_usecs = end_tv.tv_sec * TIME_MILLION + end_tv.tv_usec;
+
+  if (end_time_err != 0 || end_usecs < start_usecs)
+    return -1;
+
+  return (int)(end_usecs - start_usecs);
+}

=== added file 'plugin/semisync/semisync_master.h'
--- a/plugin/semisync/semisync_master.h	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_master.h	2009-06-15 13:30:20 +0000
@@ -0,0 +1,366 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#ifndef SEMISYNC_MASTER_H
+#define SEMISYNC_MASTER_H
+
+#include "semisync.h"
+
+/**
+   This class manages memory for active transaction list.
+
+   We record each active transaction with a TranxNode.  Because each
+   session can only have only one open transaction, the total active
+   transaction nodes can not exceed the maximum sessions.  Currently
+   in MySQL, sessions are the same as connections.
+*/
+class ActiveTranx
+  :public Trace {
+private:
+  struct TranxNode {
+    char             *log_name_;
+    my_off_t          log_pos_;
+    struct TranxNode *next_;            /* the next node in the sorted list */
+    struct TranxNode *hash_next_;    /* the next node during hash collision */
+  };
+
+  /* The following data structure maintains an active transaction list. */
+  TranxNode       *node_array_;
+  TranxNode       *free_pool_;
+
+  /* These two record the active transaction list in sort order. */
+  TranxNode       *trx_front_, *trx_rear_;
+
+  TranxNode      **trx_htb_;        /* A hash table on active transactions. */
+
+  int              num_transactions_;               /* maximum transactions */
+  int              num_entries_;              /* maximum hash table entries */
+  pthread_mutex_t *lock_;                                     /* mutex lock */
+
+  inline void assert_lock_owner();
+
+  inline TranxNode* alloc_tranx_node();
+
+  inline unsigned int calc_hash(const unsigned char *key,unsigned int length);
+  unsigned int get_hash_value(const char *log_file_name, my_off_t log_file_pos);
+
+  int compare(const char *log_file_name1, my_off_t log_file_pos1,
+	      const TranxNode *node2) {
+    return compare(log_file_name1, log_file_pos1,
+		   node2->log_name_, node2->log_pos_);
+  }
+  int compare(const TranxNode *node1,
+	      const char *log_file_name2, my_off_t log_file_pos2) {
+    return compare(node1->log_name_, node1->log_pos_,
+		   log_file_name2, log_file_pos2);
+  }
+  int compare(const TranxNode *node1, const TranxNode *node2) {
+    return compare(node1->log_name_, node1->log_pos_,
+		   node2->log_name_, node2->log_pos_);
+  }
+
+public:
+  ActiveTranx(int max_connections, pthread_mutex_t *lock,
+	      unsigned long trace_level);
+  ~ActiveTranx();
+
+  /* Insert an active transaction node with the specified position.
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int insert_tranx_node(const char *log_file_name, my_off_t log_file_pos);
+
+  /* Clear the active transaction nodes until(inclusive) the specified
+   * position.
+   * If log_file_name is NULL, everything will be cleared: the sorted
+   * list and the hash table will be reset to empty.
+   * 
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int clear_active_tranx_nodes(const char *log_file_name,
+			       my_off_t    log_file_pos);
+
+  /* Given a position, check to see whether the position is an active
+   * transaction's ending position by probing the hash table.
+   */
+  bool is_tranx_end_pos(const char *log_file_name, my_off_t log_file_pos);
+
+  /* Given two binlog positions, compare which one is bigger based on
+   * (file_name, file_position).
+   */
+  static int compare(const char *log_file_name1, my_off_t log_file_pos1,
+		     const char *log_file_name2, my_off_t log_file_pos2);
+
+};
+
+/**
+   The extension class for the master of semi-synchronous replication
+*/
+class ReplSemiSyncMaster
+  :public ReplSemiSyncBase {
+ private:
+  ActiveTranx    *active_tranxs_;  /* active transaction list: the list will
+                                      be cleared when semi-sync switches off. */
+
+  /* True when initObject has been called */
+  bool init_done_;
+
+  /* This cond variable is signaled when enough binlog has been sent to slave,
+   * so that a waiting trx can return the 'ok' to the client for a commit.
+   */
+  pthread_cond_t  COND_binlog_send_;
+
+  /* Mutex that protects the following state variables and the active
+   * transaction list.
+   * Under no cirumstances we can acquire mysql_bin_log.LOCK_log if we are
+   * already holding LOCK_binlog_ because it can cause deadlocks.
+   */
+  pthread_mutex_t LOCK_binlog_;
+
+  /* This is set to true when reply_file_name_ contains meaningful data. */
+  bool            reply_file_name_inited_;
+
+  /* The binlog name up to which we have received replies from any slaves. */
+  char            reply_file_name_[FN_REFLEN];
+
+  /* The position in that file up to which we have the reply from any slaves. */
+  my_off_t        reply_file_pos_;
+
+  /* This is set to true when we know the 'smallest' wait position. */
+  bool            wait_file_name_inited_;
+
+  /* NULL, or the 'smallest' filename that a transaction is waiting for
+   * slave replies.
+   */
+  char            wait_file_name_[FN_REFLEN];
+
+  /* The smallest position in that file that a trx is waiting for: the trx
+   * can proceed and send an 'ok' to the client when the master has got the
+   * reply from the slave indicating that it already got the binlog events.
+   */
+  my_off_t        wait_file_pos_;
+
+  /* This is set to true when we know the 'largest' transaction commit
+   * position in the binlog file.
+   * We always maintain the position no matter whether semi-sync is switched
+   * on switched off.  When a transaction wait timeout occurs, semi-sync will
+   * switch off.  Binlog-dump thread can use the three fields to detect when
+   * slaves catch up on replication so that semi-sync can switch on again.
+   */
+  bool            commit_file_name_inited_;
+
+  /* The 'largest' binlog filename that a commit transaction is seeing.       */
+  char            commit_file_name_[FN_REFLEN];
+
+  /* The 'largest' position in that file that a commit transaction is seeing. */
+  my_off_t        commit_file_pos_;
+
+  /* All global variables which can be set by parameters. */
+  volatile bool            master_enabled_;      /* semi-sync is enabled on the master */
+  unsigned long           wait_timeout_;      /* timeout period(ms) during tranx wait */
+
+  /* All status variables. */
+  bool            state_;                    /* whether semi-sync is switched */
+  unsigned long           enabled_transactions_;          /* semi-sync'ed tansactions */
+  unsigned long           disabled_transactions_;     /* non-semi-sync'ed tansactions */
+  unsigned long           switched_off_times_;    /* how many times are switched off? */
+  unsigned long           timefunc_fails_;           /* how many time function fails? */
+  unsigned long           total_wait_timeouts_;      /* total number of wait timeouts */
+  unsigned long           wait_sessions_;      /* how many sessions wait for replies? */
+  unsigned long           wait_backtraverse_;         /* wait position back traverses */
+  unsigned long long       total_trx_wait_num_;   /* total trx waits: non-timeout ones */
+  unsigned long long       total_trx_wait_time_;         /* total trx wait time: in us */
+  unsigned long long       total_net_wait_num_;                 /* total network waits */
+  unsigned long long       total_net_wait_time_;            /* total network wait time */
+
+  /* The number of maximum active transactions.  This should be the same as
+   * maximum connections because MySQL does not do connection sharing now.
+   */
+  int             max_transactions_;
+
+  void lock();
+  void unlock();
+  void cond_broadcast();
+  int  cond_timewait(struct timespec *wait_time);
+
+  /* Is semi-sync replication on? */
+  bool is_on() {
+    return (state_);
+  }
+
+  void set_master_enabled(bool enabled) {
+    master_enabled_ = enabled;
+  }
+
+  /* Switch semi-sync off because of timeout in transaction waiting. */
+  int switch_off();
+
+  /* Switch semi-sync on when slaves catch up. */
+  int try_switch_on(int server_id,
+                    const char *log_file_name, my_off_t log_file_pos);
+
+ public:
+  ReplSemiSyncMaster();
+  ~ReplSemiSyncMaster();
+
+  bool getMasterEnabled() {
+    return master_enabled_;
+  }
+  void setTraceLevel(unsigned long trace_level) {
+    trace_level_ = trace_level;
+    if (active_tranxs_)
+      active_tranxs_->trace_level_ = trace_level;
+  }
+
+  /* Set the transaction wait timeout period, in milliseconds. */
+  void setWaitTimeout(unsigned long wait_timeout) {
+    wait_timeout_ = wait_timeout;
+  }
+
+  /* Initialize this class after MySQL parameters are initialized. this
+   * function should be called once at bootstrap time.
+   */
+  int initObject();
+
+  /* Enable the object to enable semi-sync replication inside the master. */
+  int enableMaster();
+
+  /* Enable the object to enable semi-sync replication inside the master. */
+  int disableMaster();
+
+  /* Add a semi-sync replication slave */
+  void add_slave();
+    
+  /* Remove a semi-sync replication slave */
+  void remove_slave();
+
+  /* Is the slave servered by the thread requested semi-sync */
+  bool is_semi_sync_slave();
+
+  int reportReplyBinlog(const char *log_file_pos);
+  
+  /* In semi-sync replication, reports up to which binlog position we have
+   * received replies from the slave indicating that it already get the events.
+   *
+   * Input:
+   *  server_id     - (IN)  master server id number
+   *  log_file_name - (IN)  binlog file name
+   *  end_offset    - (IN)  the offset in the binlog file up to which we have
+   *                        the replies from the slave
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int reportReplyBinlog(uint32 server_id,
+                        const char* log_file_name,
+                        my_off_t end_offset);
+
+  /* Commit a transaction in the final step.  This function is called from
+   * InnoDB before returning from the low commit.  If semi-sync is switch on,
+   * the function will wait to see whether binlog-dump thread get the reply for
+   * the events of the transaction.  Remember that this is not a direct wait,
+   * instead, it waits to see whether the binlog-dump thread has reached the
+   * point.  If the wait times out, semi-sync status will be switched off and
+   * all other transaction would not wait either.
+   *
+   * Input:  (the transaction events' ending binlog position)
+   *  trx_wait_binlog_name - (IN)  ending position's file name
+   *  trx_wait_binlog_pos  - (IN)  ending position's file offset
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int commitTrx(const char* trx_wait_binlog_name,
+                my_off_t trx_wait_binlog_pos);
+
+  /* Reserve space in the replication event packet header:
+   *  . slave semi-sync off: 1 byte - (0)
+   *  . slave semi-sync on:  3 byte - (0, 0xef, 0/1}
+   * 
+   * Input:
+   *  header   - (IN)  the header buffer
+   *  size     - (IN)  size of the header buffer
+   *
+   * Return:
+   *  size of the bytes reserved for header
+   */
+  int reserveSyncHeader(unsigned char *header, unsigned long size);
+
+  /* Update the sync bit in the packet header to indicate to the slave whether
+   * the master will wait for the reply of the event.  If semi-sync is switched
+   * off and we detect that the slave is catching up, we switch semi-sync on.
+   * 
+   * Input:
+   *  packet        - (IN)  the packet containing the replication event
+   *  log_file_name - (IN)  the event ending position's file name
+   *  log_file_pos  - (IN)  the event ending position's file offset
+   *  server_id     - (IN)  master server id number
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int updateSyncHeader(unsigned char *packet,
+                       const char *log_file_name,
+		       my_off_t log_file_pos,
+		       uint32 server_id);
+
+  /* Called when a transaction finished writing binlog events.
+   *  . update the 'largest' transactions' binlog event position
+   *  . insert the ending position in the active transaction list if
+   *    semi-sync is on
+   * 
+   * Input:  (the transaction events' ending binlog position)
+   *  log_file_name - (IN)  transaction ending position's file name
+   *  log_file_pos  - (IN)  transaction ending position's file offset
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int writeTranxInBinlog(const char* log_file_name, my_off_t log_file_pos);
+
+  /* Export internal statistics for semi-sync replication. */
+  void setExportStats();
+
+  /* 'reset master' command is issued from the user and semi-sync need to
+   * go off for that.
+   */
+  int resetMaster();
+};
+
+/* System and status variables for the master component */
+extern char rpl_semi_sync_master_enabled;
+extern unsigned long rpl_semi_sync_master_timeout;
+extern unsigned long rpl_semi_sync_master_trace_level;
+extern unsigned long rpl_semi_sync_master_status;
+extern unsigned long rpl_semi_sync_master_yes_transactions;
+extern unsigned long rpl_semi_sync_master_no_transactions;
+extern unsigned long rpl_semi_sync_master_off_times;
+extern unsigned long rpl_semi_sync_master_timefunc_fails;
+extern unsigned long rpl_semi_sync_master_num_timeouts;
+extern unsigned long rpl_semi_sync_master_wait_sessions;
+extern unsigned long rpl_semi_sync_master_back_wait_pos;
+extern unsigned long rpl_semi_sync_master_trx_wait_time;
+extern unsigned long rpl_semi_sync_master_net_wait_time;
+extern unsigned long long rpl_semi_sync_master_net_wait_num;
+extern unsigned long long rpl_semi_sync_master_trx_wait_num;
+extern unsigned long long rpl_semi_sync_master_net_wait_total_time;
+extern unsigned long long rpl_semi_sync_master_trx_wait_total_time;
+extern unsigned long rpl_semi_sync_master_clients;
+
+#endif /* SEMISYNC_MASTER_H */

=== added file 'plugin/semisync/semisync_master_plugin.cc'
--- a/plugin/semisync/semisync_master_plugin.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_master_plugin.cc	2009-06-17 10:37:04 +0000
@@ -0,0 +1,380 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#include "semisync_master.h"
+
+ReplSemiSyncMaster repl_semisync;
+
+int repl_semi_report_binlog_update(Binlog_storage_param *param,
+				   const char *log_file,
+				   my_off_t log_pos, uint32 flags)
+{
+  int  error= 0;
+
+  if (repl_semisync.getMasterEnabled())
+  {
+    /*
+      Let us store the binlog file name and the position, so that
+      we know how long to wait for the binlog to the replicated to
+      the slave in synchronous replication.
+    */
+    error= repl_semisync.writeTranxInBinlog(log_file,
+                                            log_pos);
+  }
+
+  return error;
+}
+
+int repl_semi_request_commit(Trans_param *param)
+{
+  return 0;
+}
+
+int repl_semi_report_commit(Trans_param *param)
+{
+
+  bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS;
+
+  if (is_real_trans && param->log_pos)
+  {
+    const char *binlog_name= param->log_file;
+    return repl_semisync.commitTrx(binlog_name, param->log_pos);
+  }
+  return 0;
+}
+
+int repl_semi_report_rollback(Trans_param *param)
+{
+  return repl_semi_report_commit(param);
+}
+
+int repl_semi_binlog_dump_start(Binlog_transmit_param *param,
+				 const char *log_file,
+				 my_off_t log_pos)
+{
+  bool semi_sync_slave= repl_semisync.is_semi_sync_slave();
+  
+  if (semi_sync_slave)
+    /* One more semi-sync slave */
+    repl_semisync.add_slave();
+  sql_print_information("Start %s binlog_dump to slave (server_id: %d), pos(%s, %lu)",
+			semi_sync_slave ? "semi-sync" : "asynchronous",
+			param->server_id, log_file, (unsigned long)log_pos);
+  
+  return 0;
+}
+
+int repl_semi_binlog_dump_end(Binlog_transmit_param *param)
+{
+  bool semi_sync_slave= repl_semisync.is_semi_sync_slave();
+  
+  sql_print_information("Stop %s binlog_dump to slave (server_id: %d)",
+                        semi_sync_slave ? "semi-sync" : "asynchronous",
+                        param->server_id);
+  if (semi_sync_slave)
+  {
+    /* One less semi-sync slave */
+    repl_semisync.remove_slave();
+  }
+  return 0;
+}
+
+int repl_semi_reserve_header(Binlog_transmit_param *param,
+			     unsigned char *header,
+			     unsigned long size, unsigned long *len)
+{
+  *len +=  repl_semisync.reserveSyncHeader(header, size);
+  return 0;
+}
+
+int repl_semi_before_send_event(Binlog_transmit_param *param,
+                                unsigned char *packet, unsigned long len,
+                                const char *log_file, my_off_t log_pos)
+{
+  return repl_semisync.updateSyncHeader(packet,
+					log_file,
+					log_pos,
+					param->server_id);
+}
+
+int repl_semi_after_send_event(Binlog_transmit_param *param,
+                               const char *event_buf, unsigned long len)
+{
+  return 0;
+}
+
+int repl_semi_reset_master(Binlog_transmit_param *param)
+{
+  if (repl_semisync.resetMaster())
+    return 1;
+  return 0;
+}
+
+/*
+  semisync system variables
+ */
+static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
+				      SYS_VAR *var,
+				      void *ptr,
+				      const void *val);
+
+static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
+					  SYS_VAR *var,
+					  void *ptr,
+					  const void *val);
+
+static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
+				      SYS_VAR *var,
+				      void *ptr,
+				      const void *val);
+
+static void fix_rpl_semi_sync_master_reply_log_file_pos(MYSQL_THD thd,
+                                                 SYS_VAR *var,
+                                                 void *ptr,
+                                                 const void *val);
+
+static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_master_enabled,
+  PLUGIN_VAR_OPCMDARG,
+ "Enable semi-synchronous replication master (disabled by default). ",
+  NULL, 			// check
+  &fix_rpl_semi_sync_master_enabled,	// update
+  0);
+
+static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout,
+  PLUGIN_VAR_OPCMDARG,
+ "The timeout value (in ms) for semi-synchronous replication in the master",
+  NULL, 			// check
+  fix_rpl_semi_sync_master_timeout,	// update
+  10, 0, ~0L, 1);
+
+static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level,
+  PLUGIN_VAR_OPCMDARG,
+ "The tracing level for semi-sync replication.",
+  NULL,				  // check
+  &fix_rpl_semi_sync_master_trace_level, // update
+  32, 0, ~0L, 1);
+
+/*
+  Use a SESSION instead of GLOBAL variable for slave to send reply to
+  avoid requiring SUPER privilege.
+*/
+static MYSQL_THDVAR_STR(reply_log_file_pos,
+  PLUGIN_VAR_NOCMDOPT,
+  "The log filename and position slave has queued to relay log.",
+  NULL,             // check
+  &fix_rpl_semi_sync_master_reply_log_file_pos,
+  "");
+
+static SYS_VAR* semi_sync_master_system_vars[]= {
+  MYSQL_SYSVAR(enabled),
+  MYSQL_SYSVAR(timeout),
+  MYSQL_SYSVAR(trace_level),
+  MYSQL_SYSVAR(reply_log_file_pos),
+  NULL,
+};
+
+
+static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd,
+				      SYS_VAR *var,
+				      void *ptr,
+				      const void *val)
+{
+  *(unsigned long *)ptr= *(unsigned long *)val;
+  repl_semisync.setWaitTimeout(rpl_semi_sync_master_timeout);
+  return;
+}
+
+static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd,
+					  SYS_VAR *var,
+					  void *ptr,
+					  const void *val)
+{
+  *(unsigned long *)ptr= *(unsigned long *)val;
+  repl_semisync.setTraceLevel(rpl_semi_sync_master_trace_level);
+  return;
+}
+
+static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd,
+				      SYS_VAR *var,
+				      void *ptr,
+				      const void *val)
+{
+  *(char *)ptr= *(char *)val;
+  if (rpl_semi_sync_master_enabled)
+  {
+    if (repl_semisync.enableMaster() != 0)
+      rpl_semi_sync_master_enabled = false;
+  }
+  else
+  {
+    if (repl_semisync.disableMaster() != 0)
+      rpl_semi_sync_master_enabled = true;
+  }
+
+  return;
+}
+
+static void fix_rpl_semi_sync_master_reply_log_file_pos(MYSQL_THD thd,
+                                                 SYS_VAR *var,
+                                                 void *ptr,
+                                                 const void *val)
+{
+  const char *log_file_pos= *(char **)val;
+  
+  if (repl_semisync.reportReplyBinlog(log_file_pos))
+    sql_print_error("report slave binlog reply failed.");
+
+  return;
+}
+
+Trans_observer trans_observer = {
+  sizeof(Trans_observer),		// len
+
+  repl_semi_report_commit,	// after_commit
+  repl_semi_report_rollback,	// after_rollback
+};
+
+Binlog_storage_observer storage_observer = {
+  sizeof(Binlog_storage_observer), // len
+
+  repl_semi_report_binlog_update, // report_update
+};
+
+Binlog_transmit_observer transmit_observer = {
+  sizeof(Binlog_transmit_observer), // len
+
+  repl_semi_binlog_dump_start,	// start
+  repl_semi_binlog_dump_end,	// stop
+  repl_semi_reserve_header,	// reserve_header
+  repl_semi_before_send_event,	// before_send_event
+  repl_semi_after_send_event,	// after_send_event
+  repl_semi_reset_master,	// reset
+};
+
+
+#define SHOW_FNAME(name)			\
+  rpl_semi_sync_master_show_##name
+
+#define DEF_SHOW_FUNC(name, show_type)					\
+  static  int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \
+  {									\
+    repl_semisync.setExportStats();					\
+    var->type= show_type;						\
+    var->value= (char *)&rpl_semi_sync_master_##name;				\
+    return 0;								\
+  }
+
+DEF_SHOW_FUNC(clients, SHOW_LONG)
+DEF_SHOW_FUNC(net_wait_time, SHOW_LONG)
+DEF_SHOW_FUNC(net_wait_total_time, SHOW_LONGLONG)
+DEF_SHOW_FUNC(net_wait_num, SHOW_LONGLONG)
+DEF_SHOW_FUNC(off_times, SHOW_LONG)
+DEF_SHOW_FUNC(no_transactions, SHOW_LONG)
+DEF_SHOW_FUNC(status, SHOW_BOOL)
+DEF_SHOW_FUNC(timefunc_fails, SHOW_LONG)
+DEF_SHOW_FUNC(trx_wait_time, SHOW_LONG)
+DEF_SHOW_FUNC(trx_wait_total_time, SHOW_LONGLONG)
+DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG)
+DEF_SHOW_FUNC(back_wait_pos, SHOW_LONG)
+DEF_SHOW_FUNC(wait_sessions, SHOW_LONG)
+DEF_SHOW_FUNC(yes_transactions, SHOW_LONG)
+
+
+/* plugin status variables */
+static SHOW_VAR semi_sync_master_status_vars[]= {
+  {"Rpl_semi_sync_master_clients",    (char*) &SHOW_FNAME(clients),         SHOW_FUNC},
+  {"Rpl_semi_sync_master_net_avg_wait_time",
+                               (char*) &SHOW_FNAME(net_wait_time),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_net_wait_time",
+                               (char*) &SHOW_FNAME(net_wait_total_time),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_net_waits",  (char*) &SHOW_FNAME(net_wait_num),    SHOW_FUNC},
+  {"Rpl_semi_sync_master_no_times",   (char*) &SHOW_FNAME(off_times),       SHOW_FUNC},
+  {"Rpl_semi_sync_master_no_tx",      (char*) &SHOW_FNAME(no_transactions), SHOW_FUNC},
+  {"Rpl_semi_sync_master_status",     (char*) &SHOW_FNAME(status),          SHOW_FUNC},
+  {"Rpl_semi_sync_master_timefunc_failures",
+                               (char*) &SHOW_FNAME(timefunc_fails),  SHOW_FUNC},
+  {"Rpl_semi_sync_master_tx_avg_wait_time",
+                               (char*) &SHOW_FNAME(trx_wait_time),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_tx_wait_time",
+                               (char*) &SHOW_FNAME(trx_wait_total_time),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_tx_waits",   (char*) &SHOW_FNAME(trx_wait_num),    SHOW_FUNC},
+  {"Rpl_semi_sync_master_wait_pos_backtraverse",
+                               (char*) &SHOW_FNAME(back_wait_pos),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_wait_sessions",
+                               (char*) &SHOW_FNAME(wait_sessions),   SHOW_FUNC},
+  {"Rpl_semi_sync_master_yes_tx",     (char*) &SHOW_FNAME(yes_transactions), SHOW_FUNC},
+  {NULL, NULL, SHOW_LONG},
+};
+
+
+static int semi_sync_master_plugin_init(void *p)
+{
+  if (repl_semisync.initObject())
+    return 1;
+  if (register_trans_observer(&trans_observer, p))
+    return 1;
+  if (register_binlog_storage_observer(&storage_observer, p))
+    return 1;
+  if (register_binlog_transmit_observer(&transmit_observer, p))
+    return 1;
+  return 0;
+}
+
+static int semi_sync_master_plugin_deinit(void *p)
+{
+  if (unregister_trans_observer(&trans_observer, p))
+  {
+    sql_print_error("unregister_trans_observer failed");
+    return 1;
+  }
+  if (unregister_binlog_storage_observer(&storage_observer, p))
+  {
+    sql_print_error("unregister_binlog_storage_observer failed");
+    return 1;
+  }
+  if (unregister_binlog_transmit_observer(&transmit_observer, p))
+  {
+    sql_print_error("unregister_binlog_transmit_observer failed");
+    return 1;
+  }
+  sql_print_information("unregister_replicator OK");
+  return 0;
+}
+
+struct Mysql_replication semi_sync_master_plugin= {
+  MYSQL_REPLICATION_INTERFACE_VERSION
+};
+
+/*
+  Plugin library descriptor
+*/
+mysql_declare_plugin(semi_sync_master)
+{
+  MYSQL_REPLICATION_PLUGIN,
+  &semi_sync_master_plugin,
+  "rpl_semi_sync_master",
+  "He Zhenxing",
+  "Semi-synchronous replication master",
+  PLUGIN_LICENSE_GPL,
+  semi_sync_master_plugin_init, /* Plugin Init */
+  semi_sync_master_plugin_deinit, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+  semi_sync_master_status_vars,	/* status variables */
+  semi_sync_master_system_vars,	/* system variables */
+  NULL                        /* config options                  */
+}
+mysql_declare_plugin_end;

=== added file 'plugin/semisync/semisync_slave.cc'
--- a/plugin/semisync/semisync_slave.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_slave.cc	2009-06-15 13:30:20 +0000
@@ -0,0 +1,122 @@
+/* Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#include "semisync_slave.h"
+
+char rpl_semi_sync_slave_enabled;
+unsigned long rpl_semi_sync_slave_status= 0;
+unsigned long rpl_semi_sync_slave_trace_level;
+
+int ReplSemiSyncSlave::initObject()
+{
+  int result= 0;
+  const char *kWho = "ReplSemiSyncSlave::initObject";
+
+  if (init_done_)
+  {
+    fprintf(stderr, "%s called twice\n", kWho);
+    return 1;
+  }
+  init_done_ = true;
+
+  /* References to the parameter works after set_options(). */
+  setSlaveEnabled(rpl_semi_sync_slave_enabled);
+  setTraceLevel(rpl_semi_sync_slave_trace_level);
+
+  return result;
+}
+
+int ReplSemiSyncSlave::slaveReplyConnect()
+{
+  if (!mysql_reply && !(mysql_reply= rpl_connect_master(NULL)))
+  {
+    sql_print_error("Semisync slave connect to master for reply failed");
+    return 1;
+  }
+  return 0;
+}
+
+int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header,
+                                      unsigned long total_len,
+                                      bool  *need_reply,
+                                      const char **payload,
+                                      unsigned long *payload_len)
+{
+  const char *kWho = "ReplSemiSyncSlave::slaveReadSyncHeader";
+  int read_res = 0;
+  function_enter(kWho);
+
+  if ((unsigned char)(header[0]) == kPacketMagicNum)
+  {
+    *need_reply  = (header[1] & kPacketFlagSync);
+    *payload_len = total_len - 2;
+    *payload     = header + 2;
+
+    if (trace_level_ & kTraceDetail)
+      sql_print_information("%s: reply - %d", kWho, *need_reply);
+  }
+  else
+  {
+    sql_print_error("Missing magic number for semi-sync packet, packet "
+                    "len: %lu", total_len);
+    read_res = -1;
+  }
+
+  return function_exit(kWho, read_res);
+}
+
+int ReplSemiSyncSlave::slaveStart(Binlog_relay_IO_param *param)
+{
+  bool semi_sync= getSlaveEnabled();
+  
+  sql_print_information("Slave I/O thread: Start %s replication to\
+ master '%s@%s:%d' in log '%s' at position %lu",
+			semi_sync ? "semi-sync" : "asynchronous",
+			param->user, param->host, param->port,
+			param->master_log_name[0] ? param->master_log_name : "FIRST",
+			(unsigned long)param->master_log_pos);
+
+  if (semi_sync && !rpl_semi_sync_slave_status)
+    rpl_semi_sync_slave_status= 1;
+  return 0;
+}
+
+int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param)
+{
+  if (rpl_semi_sync_slave_status)
+    rpl_semi_sync_slave_status= 0;
+  if (mysql_reply)
+    mysql_close(mysql_reply);
+  mysql_reply= 0;
+  return 0;
+}
+
+int ReplSemiSyncSlave::slaveReply(const char *log_name, my_off_t log_pos)
+{
+  char query[FN_REFLEN + 100];
+  sprintf(query, "SET SESSION rpl_semi_sync_master_reply_log_file_pos='%llu:%s'",
+          (unsigned long long)log_pos, log_name);
+  if (mysql_real_query(mysql_reply, query, strlen(query)))
+  {
+    sql_print_error("Set 'rpl_semi_sync_master_reply_log_file_pos' on master failed");
+    mysql_free_result(mysql_store_result(mysql_reply));
+    mysql_close(mysql_reply);
+    mysql_reply= 0;
+    return 1;
+  }
+  mysql_free_result(mysql_store_result(mysql_reply));
+  return 0;
+}

=== added file 'plugin/semisync/semisync_slave.h'
--- a/plugin/semisync/semisync_slave.h	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_slave.h	2009-06-15 13:30:20 +0000
@@ -0,0 +1,99 @@
+/* Copyright (C) 2006 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#ifndef SEMISYNC_SLAVE_H
+#define SEMISYNC_SLAVE_H
+
+#include "semisync.h"
+
+/**
+   The extension class for the slave of semi-synchronous replication
+*/
+class ReplSemiSyncSlave
+  :public ReplSemiSyncBase {
+public:
+ ReplSemiSyncSlave()
+   :slave_enabled_(false)
+  {}
+  ~ReplSemiSyncSlave() {}
+
+  void setTraceLevel(unsigned long trace_level) {
+    trace_level_ = trace_level;
+  }
+
+  /* Initialize this class after MySQL parameters are initialized. this
+   * function should be called once at bootstrap time.
+   */
+  int initObject();
+
+  bool getSlaveEnabled() {
+    return slave_enabled_;
+  }
+  void setSlaveEnabled(bool enabled) {
+    slave_enabled_ = enabled;
+  }
+
+  /* A slave reads the semi-sync packet header and separate the metadata
+   * from the payload data.
+   * 
+   * Input:
+   *  header      - (IN)  packet header pointer
+   *  total_len   - (IN)  total packet length: metadata + payload
+   *  need_reply  - (IN)  whether the master is waiting for the reply
+   *  payload     - (IN)  payload: the replication event
+   *  payload_len - (IN)  payload length
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int slaveReadSyncHeader(const char *header, unsigned long total_len, bool *need_reply,
+                          const char **payload, unsigned long *payload_len);
+
+  /* A slave replies to the master indicating its replication process.  It
+   * indicates that the slave has received all events before the specified
+   * binlog position.
+   * 
+   * Input:
+   *  log_name         - (IN)  the reply point's binlog file name
+   *  log_pos   - (IN)  the reply point's binlog file offset
+   *
+   * Return:
+   *  0: success;  -1 or otherwise: error
+   */
+  int slaveReply(const char *log_name, my_off_t log_pos);
+
+  /*
+    Connect to master for sending reply

+   */
+  int slaveReplyConnect();
+  
+  int slaveStart(Binlog_relay_IO_param *param);
+  int slaveStop(Binlog_relay_IO_param *param);
+
+private:
+  /* True when initObject has been called */
+  bool init_done_;
+  bool slave_enabled_;        /* semi-sycn is enabled on the slave */
+  MYSQL *mysql_reply;         /* connection to send reply */
+};
+
+
+/* System and status variables for the slave component */
+extern char rpl_semi_sync_slave_enabled;
+extern unsigned long rpl_semi_sync_slave_trace_level;
+extern unsigned long rpl_semi_sync_slave_status;
+
+#endif /* SEMISYNC_SLAVE_H */

=== added file 'plugin/semisync/semisync_slave_plugin.cc'
--- a/plugin/semisync/semisync_slave_plugin.cc	1970-01-01 00:00:00 +0000
+++ b/plugin/semisync/semisync_slave_plugin.cc	2009-06-17 10:37:04 +0000
@@ -0,0 +1,224 @@
+/* Copyright (C) 2007 Google Inc.
+   Copyright (C) 2008 MySQL AB
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 of the License.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
+
+
+#include "semisync_slave.h"
+
+ReplSemiSyncSlave repl_semisync;
+
+/*
+  indicate whether or not the slave should send a reply to the master.
+
+  This is set to true in repl_semi_slave_read_event if the current
+  event read is the last event of a transaction. And the value is
+  checked in repl_semi_slave_queue_event.
+*/
+bool semi_sync_need_reply= false;
+
+int repl_semi_reset_slave(Binlog_relay_IO_param *param)
+{
+  // TODO: reset semi-sync slave status here
+  return 0;
+}
+
+int repl_semi_slave_request_dump(Binlog_relay_IO_param *param,
+				 uint32 flags)
+{
+  MYSQL *mysql= param->mysql;
+  MYSQL_RES *res= 0;
+  MYSQL_ROW row;
+  const char *query;
+
+  if (!repl_semisync.getSlaveEnabled())
+    return 0;
+
+  /*
+    Create the connection that is used to send slave ACK replies to
+    master
+  */
+  if (repl_semisync.slaveReplyConnect())
+    return 1;
+
+  /* Check if master server has semi-sync plugin installed */
+  query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'";
+  if (mysql_real_query(mysql, query, strlen(query)) ||
+      !(res= mysql_store_result(mysql)))
+  {
+    mysql_free_result(mysql_store_result(mysql));
+    sql_print_error("Execution failed on master: %s", query);
+    return 1;
+  }
+
+  row= mysql_fetch_row(res);
+  if (!row)
+  {
+    /* Master does not support or not configured semi-sync */
+    sql_print_warning("Master server does not support or not configured semi-sync replication, fallback to asynchronous");
+    rpl_semi_sync_slave_status= 0;
+    return 0;
+  }
+
+  /*
+    Tell master dump thread that we want to do semi-sync
+    replication
+  */
+  query= "SET @rpl_semi_sync_slave= 1";
+  if (mysql_real_query(mysql, query, strlen(query)))
+  {
+    sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed");
+    mysql_free_result(mysql_store_result(mysql));
+    return 1;
+  }
+  mysql_free_result(mysql_store_result(mysql));
+  rpl_semi_sync_slave_status= 1;
+  return 0;
+}
+
+int repl_semi_slave_read_event(Binlog_relay_IO_param *param,
+			       const char *packet, unsigned long len,
+			       const char **event_buf, unsigned long *event_len)
+{
+  if (rpl_semi_sync_slave_status)
+    return repl_semisync.slaveReadSyncHeader(packet, len,
+					     &semi_sync_need_reply,
+					     event_buf, event_len);
+  *event_buf= packet;
+  *event_len= len;
+  return 0;
+}
+
+int repl_semi_slave_queue_event(Binlog_relay_IO_param *param,
+				const char *event_buf,
+				unsigned long event_len,
+				uint32 flags)
+{
+  if (rpl_semi_sync_slave_status && semi_sync_need_reply)
+    return repl_semisync.slaveReply(param->master_log_name,
+                                    param->master_log_pos);
+  return 0;
+}
+
+int repl_semi_slave_io_start(Binlog_relay_IO_param *param)
+{
+  return repl_semisync.slaveStart(param);
+}
+
+int repl_semi_slave_io_end(Binlog_relay_IO_param *param)
+{
+  return repl_semisync.slaveStop(param);
+}
+
+
+static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd,
+					    SYS_VAR *var,
+					    void *ptr,
+					    const void *val)
+{
+  *(char *)ptr= *(char *)val;
+  repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0);
+  return;
+}
+
+static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd,
+					  SYS_VAR *var,
+					  void *ptr,
+					  const void *val)
+{
+  *(unsigned long *)ptr= *(unsigned long *)val;
+  repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level);
+  return;
+}
+
+/* plugin system variables */
+static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled,
+  PLUGIN_VAR_OPCMDARG,
+ "Enable semi-synchronous replication slave (disabled by default). ",
+  NULL,				   // check
+  &fix_rpl_semi_sync_slave_enabled, // update
+  0);
+
+static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level,
+  PLUGIN_VAR_OPCMDARG,
+ "The tracing level for semi-sync replication.",
+  NULL,				  // check
+  &fix_rpl_semi_sync_trace_level, // update
+  32, 0, ~0L, 1);
+
+static SYS_VAR* semi_sync_slave_system_vars[]= {
+  MYSQL_SYSVAR(enabled),
+  MYSQL_SYSVAR(trace_level),
+  NULL,
+};
+
+
+/* plugin status variables */
+static SHOW_VAR semi_sync_slave_status_vars[]= {
+  {"Rpl_semi_sync_slave_status",
+   (char*) &rpl_semi_sync_slave_status,    SHOW_BOOL},
+  {NULL, NULL, SHOW_BOOL},
+};
+
+Binlog_relay_IO_observer relay_io_observer = {
+  sizeof(Binlog_relay_IO_observer), // len
+
+  repl_semi_slave_io_start,	// start
+  repl_semi_slave_io_end,	// stop
+  repl_semi_slave_request_dump,	// request_transmit
+  repl_semi_slave_read_event,	// after_read_event
+  repl_semi_slave_queue_event,	// after_queue_event
+  repl_semi_reset_slave,	// reset
+};
+
+static int semi_sync_slave_plugin_init(void *p)
+{
+  if (repl_semisync.initObject())
+    return 1;
+  if (register_binlog_relay_io_observer(&relay_io_observer, p))
+    return 1;
+  return 0;
+}
+
+static int semi_sync_slave_plugin_deinit(void *p)
+{
+  if (unregister_binlog_relay_io_observer(&relay_io_observer, p))
+    return 1;
+  return 0;
+}
+
+
+struct Mysql_replication semi_sync_slave_plugin= {
+  MYSQL_REPLICATION_INTERFACE_VERSION
+};
+
+/*
+  Plugin library descriptor
+*/
+mysql_declare_plugin(semi_sync_slave)
+{
+  MYSQL_REPLICATION_PLUGIN,
+  &semi_sync_slave_plugin,
+  "rpl_semi_sync_slave",
+  "He Zhenxing",
+  "Semi-synchronous replication slave",
+  PLUGIN_LICENSE_GPL,
+  semi_sync_slave_plugin_init, /* Plugin Init */
+  semi_sync_slave_plugin_deinit, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+  semi_sync_slave_status_vars,	/* status variables */
+  semi_sync_slave_system_vars,	/* system variables */
+  NULL                        /* config options                  */
+}
+mysql_declare_plugin_end;

=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql	2009-06-08 14:58:33 +0000
+++ b/scripts/mysql_system_tables.sql	2009-06-17 07:30:19 +0000
@@ -60,7 +60,7 @@ CREATE TABLE IF NOT EXISTS time_zone_tra
 CREATE TABLE IF NOT EXISTS time_zone_leap_second (   Transition_time bigint signed NOT NULL, Correction int signed NOT NULL, PRIMARY KEY TranTime (Transition_time) ) engine=MyISAM CHARACTER SET utf8   comment='Leap seconds information for time zones';
 
 
-CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment char(64) collate utf8_bin DEFAULT '' NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
+CREATE TABLE IF NOT EXISTS proc (db char(64) collate utf8_bin DEFAULT '' NOT NULL, name char(64) DEFAULT '' NOT NULL, type enum('FUNCTION','PROCEDURE') NOT NULL, specific_name char(64) DEFAULT '' NOT NULL, language enum('SQL') DEFAULT 'SQL' NOT NULL, sql_data_access enum( 'CONTAINS_SQL', 'NO_SQL', 'READS_SQL_DATA', 'MODIFIES_SQL_DATA') DEFAULT 'CONTAINS_SQL' NOT NULL, is_deterministic enum('YES','NO') DEFAULT 'NO' NOT NULL, security_type enum('INVOKER','DEFINER') DEFAULT 'DEFINER' NOT NULL, param_list blob NOT NULL, returns longblob DEFAULT '' NOT NULL, body longblob NOT NULL, definer char(77) collate utf8_bin DEFAULT '' NOT NULL, created timestamp, modified timestamp, sql_mode set( 'REAL_AS_FLOAT', 'PIPES_AS_CONCAT', 'ANSI_QUOTES', 'IGNORE_SPACE', 'NOT_USED', 'ONLY_FULL_GROUP_BY', 'NO_UNSIGNED_SUBTRACTION', 'NO_DIR_IN_CREATE', 'POSTGRESQL', 'ORACLE', 'MSSQL', 'DB2', 'MAXDB', 'NO_KEY_OPTIONS', 'NO_TABLE_OPTIONS', 'NO_FIELD_OPTIONS', 'MYSQL323', 'MYSQL40', 'ANSI', 'NO_AUTO_VALUE_ON_ZERO', 'NO_BACKSLASH_ESCAPES', 'STRICT_TRANS_TABLES', 'STRICT_ALL_TABLES', 'NO_ZERO_IN_DATE', 'NO_ZERO_DATE', 'INVALID_DATES', 'ERROR_FOR_DIVISION_BY_ZERO', 'TRADITIONAL', 'NO_AUTO_CREATE_USER', 'HIGH_NOT_PRECEDENCE', 'NO_ENGINE_SUBSTITUTION', 'PAD_CHAR_TO_FULL_LENGTH') DEFAULT '' NOT NULL, comment text collate utf8_bin NOT NULL, character_set_client char(32) collate utf8_bin, collation_connection char(32) collate utf8_bin, db_collation char(32) collate utf8_bin, body_utf8 longblob, PRIMARY KEY (db,name,type)) engine=MyISAM character set utf8 comment='Stored Procedures';
 
 CREATE TABLE IF NOT EXISTS procs_priv ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Routine_name char(64) binary DEFAULT '' NOT NULL, Routine_type enum('FUNCTION','PROCEDURE') NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Proc_priv set('Execute','Alter Routine','Grant') COLLATE utf8_general_ci DEFAULT '' NOT NULL, Timestamp timestamp, PRIMARY KEY (Host,Db,User,Routine_name,Routine_type), KEY Grantor (Grantor) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin   comment='Procedure privileges';
 

=== modified file 'scripts/mysql_system_tables_fix.sql'
--- a/scripts/mysql_system_tables_fix.sql	2009-05-21 13:17:37 +0000
+++ b/scripts/mysql_system_tables_fix.sql	2009-06-11 14:01:26 +0000
@@ -457,6 +457,9 @@ ALTER TABLE proc ADD body_utf8 longblob 
                      AFTER db_collation;
 ALTER TABLE proc MODIFY body_utf8 longblob DEFAULT NULL;
 
+# Change comment from char(64) to text
+ALTER TABLE proc MODIFY comment
+                        text collate utf8_bin NOT NULL;
 
 #
 # EVENT privilege

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-06-19 09:28:44 +0000
+++ b/sql/log.cc	2009-06-22 12:30:28 +0000
@@ -4287,7 +4287,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_
   :bytes_written(0), prepared_xids(0), file_id(1), open_count(1),
    need_start_event(TRUE), m_table_map_version(0),
    sync_period_ptr(sync_period),
-   is_relay_log(0),
+   is_relay_log(0), signal_cnt(0),
    description_event_for_exec(0), description_event_for_queue(0)
 {
   /*
@@ -6787,6 +6787,7 @@ bool flush_error_log()
 void MYSQL_BIN_LOG::signal_update()
 {
   DBUG_ENTER("MYSQL_BIN_LOG::signal_update");
+  signal_cnt++;
   pthread_cond_broadcast(&update_cond);
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/log.h'
--- a/sql/log.h	2009-06-18 17:09:01 +0000
+++ b/sql/log.h	2009-06-22 12:30:28 +0000
@@ -410,7 +410,7 @@ public:
 
   /* This is relay log */
   bool is_relay_log;
-
+  ulong signal_cnt;  // update of the counter is checked by heartbeat
   /*
     These describe the log's format. This is used only for relay logs.
     _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-06-12 02:01:08 +0000
+++ b/sql/mysql_priv.h	2009-06-17 07:30:19 +0000
@@ -2037,6 +2037,7 @@ extern uint server_command_flags[];
 extern TYPELIB log_output_typelib;
 
 /* optional things, have_* variables */
+extern SHOW_COMP_OPTION have_profiling;
 extern SHOW_COMP_OPTION have_community_features;
 extern handlerton *partition_hton;
 extern handlerton *myisam_hton;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-06-19 09:28:44 +0000
+++ b/sql/mysqld.cc	2009-06-22 12:30:28 +0000
@@ -710,7 +710,7 @@ MY_LOCALE *my_default_lc_time_names;
 SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
 SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 SHOW_COMP_OPTION have_crypt, have_compress;
-SHOW_COMP_OPTION have_community_features;
+SHOW_COMP_OPTION have_profiling;
 
 /* Thread specific variables */
 
@@ -6936,7 +6936,7 @@ log and this option does nothing anymore
   {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
    "Can be used to restrict the total size used to cache a multi-transaction query.",
    (uchar**) &max_binlog_cache_size, (uchar**) &max_binlog_cache_size, 0,
-   GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
+   GET_ULL, REQUIRED_ARG, ULONGLONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
   {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
    "Binary log will be rotated automatically when the size exceeds this \
 value. Will also apply to relay logs if max_relay_log_size is 0. \
@@ -7358,7 +7358,7 @@ static int show_starttime(THD *thd, SHOW
   return 0;
 }
 
-#ifdef COMMUNITY_SERVER
+#ifdef ENABLED_PROFILING
 static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
 {
   var->type= SHOW_LONG;
@@ -7856,7 +7856,7 @@ SHOW_VAR status_vars[]= {
   {"Threads_created",	       (char*) &thread_created,		SHOW_LONG_NOFLUSH},
   {"Threads_running",          (char*) &thread_running,         SHOW_INT},
   {"Uptime",                   (char*) &show_starttime,         SHOW_FUNC},
-#ifdef COMMUNITY_SERVER
+#ifdef ENABLED_PROFILING
   {"Uptime_since_flush_status",(char*) &show_flushstatustime,   SHOW_FUNC},
 #endif
   {NullS, NullS, SHOW_LONG}
@@ -8094,10 +8094,10 @@ static int mysql_init_variables(void)
 			     "d:t:i:o,/tmp/mysqld.trace");
 #endif
   opt_error_log= IF_WIN(1,0);
-#ifdef COMMUNITY_SERVER
-    have_community_features = SHOW_OPTION_YES;
+#ifdef ENABLED_PROFILING
+    have_profiling = SHOW_OPTION_YES;
 #else
-    have_community_features = SHOW_OPTION_NO;
+    have_profiling = SHOW_OPTION_NO;
 #endif
   global_system_variables.ndb_index_stat_enable=FALSE;
   max_system_variables.ndb_index_stat_enable=TRUE;

=== modified file 'sql/rpl_handler.cc'
--- a/sql/rpl_handler.cc	2009-03-13 08:14:40 +0000
+++ b/sql/rpl_handler.cc	2009-06-17 10:37:04 +0000
@@ -153,8 +153,10 @@ void delegates_destroy()
         && ((Observer *)info->observer)->f args)                        \
     {                                                                   \
       r= 1;                                                             \
+      plugin_unlock(thd, plugin);                                       \
       break;                                                            \
     }                                                                   \
+    plugin_unlock(thd, plugin);                                         \
   }                                                                     \
   unlock()
 
@@ -304,8 +306,10 @@ int Binlog_transmit_delegate::reserve_he
                                                         &hlen))
     {
       ret= 1;
+      plugin_unlock(thd, plugin);
       break;
     }
+    plugin_unlock(thd, plugin);
     if (hlen == 0)
       continue;
     if (hlen > RESERVE_HEADER_SIZE || packet->append((char *)header, hlen))

=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc	2009-06-19 09:30:43 +0000
+++ b/sql/set_var.cc	2009-06-22 12:30:28 +0000
@@ -910,9 +910,9 @@ static sys_var_have_plugin sys_have_ndbc
 static sys_var_have_variable sys_have_openssl(&vars, "have_openssl", &have_ssl);
 static sys_var_have_variable sys_have_ssl(&vars, "have_ssl", &have_ssl);
 static sys_var_have_plugin sys_have_partition_db(&vars, "have_partitioning", C_STRING_WITH_LEN("partition"), MYSQL_STORAGE_ENGINE_PLUGIN);
+static sys_var_have_variable sys_have_profiling(&vars, "have_profiling", &have_profiling);
 static sys_var_have_variable sys_have_query_cache(&vars, "have_query_cache",
                                            &have_query_cache);
-static sys_var_have_variable sys_have_community_features(&vars, "have_community_features", &have_community_features);
 static sys_var_have_variable sys_have_rtree_keys(&vars, "have_rtree_keys", &have_rtree_keys);
 static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
 /* Global read-only variable describing server license */
@@ -4545,7 +4545,8 @@ ulong fix_sql_mode(ulong sql_mode)
   if (sql_mode & MODE_TRADITIONAL)
     sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
                 MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
-                MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER);
+                MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER | 
+                MODE_NO_ENGINE_SUBSTITUTION);
   return sql_mode;
 }
 

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2009-06-18 18:29:43 +0000
+++ b/sql/slave.cc	2009-06-22 12:30:28 +0000
@@ -2569,7 +2569,11 @@ pthread_handler_t handle_slave_io(void *
   my_pthread_setspecific_ptr(RPL_MASTER_INFO, mi);
 
   if (RUN_HOOK(binlog_relay_io, thread_start, (thd, mi)))
+  {
+    mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+               ER(ER_SLAVE_FATAL_ERROR), "Failed to run 'thread_start' hook");
     goto err;
+  }
 
   if (!(mi->mysql = mysql = mysql_init(NULL)))
   {
@@ -2726,7 +2730,9 @@ Stopping slave I/O thread due to out-of-
                  (thd, mi,(const char*)mysql->net.read_pos + 1,
                   event_len, &event_buf, &event_len)))
     {
-      sql_print_error("Failed to run 'after_read_event' hook");
+      mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+                 ER(ER_SLAVE_FATAL_ERROR),
+                 "Failed to run 'after_read_event' hook");
       goto err;
     }
 
@@ -2740,7 +2746,12 @@ Stopping slave I/O thread due to out-of-
 
     if (RUN_HOOK(binlog_relay_io, after_queue_event,
                  (thd, mi, event_buf, event_len, synced)))
+    {
+      mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
+                 ER(ER_SLAVE_FATAL_ERROR),
+                 "Failed to run 'after_queue_event' hook");
       goto err;
+    }
 
     if (flush_master_info(mi))
     {
@@ -3987,7 +3998,10 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
   if (!mysql)
   {
     if(!(mysql= mysql_init(NULL)))
+    {
+      sql_print_error("rpl_connect_master: failed in mysql_init()");
       return NULL;
+    }
     allocated= true;
   }
 
@@ -4023,6 +4037,10 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
       || !mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
                              mi->port, 0, 0))
   {
+    if (!io_slave_killed(thd, mi))
+      sql_print_error("rpl_connect_master: error connecting to master: %s (server_error: %d)",
+                      mysql_error(mysql), mysql_errno(mysql));
+    
     if (allocated)
       mysql_close(mysql);                       // this will free the object
     return NULL;

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-06-19 09:28:44 +0000
+++ b/sql/sql_base.cc	2009-06-22 12:30:28 +0000
@@ -2799,7 +2799,8 @@ bool open_table(THD *thd, TABLE_LIST *ta
     table exists now we should downgrade our exclusive metadata
     lock on this table to shared metadata lock.
   */
-  if (table_list->lock_strategy == TABLE_LIST::EXCLUSIVE_DOWNGRADABLE_MDL)
+  if (table_list->lock_strategy == TABLE_LIST::EXCLUSIVE_DOWNGRADABLE_MDL &&
+      !(flags & MYSQL_OPEN_HAS_MDL_LOCK))
     mdl_ticket->downgrade_exclusive_lock();
 
   table->mdl_ticket= mdl_ticket;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-06-18 17:09:01 +0000
+++ b/sql/sql_insert.cc	2009-06-22 12:30:28 +0000
@@ -3899,6 +3899,7 @@ void select_create::abort()
   {
     table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
     table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
+    table->auto_increment_field_not_null= FALSE;
     if (!create_info->table_existed)
       drop_open_table(thd, table, create_table->db, create_table->table_name);
     table=0;                                    // Safety

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-06-17 15:26:50 +0000
+++ b/sql/sql_parse.cc	2009-06-22 12:30:28 +0000
@@ -413,7 +413,7 @@ void execute_init_command(THD *thd, sys_
   Vio* save_vio;
   ulong save_client_capabilities;
 
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
   thd->profiling.start_new_query();
   thd->profiling.set_query_source(init_command_var->value,
                                   init_command_var->value_length);
@@ -441,7 +441,7 @@ void execute_init_command(THD *thd, sys_
   thd->client_capabilities= save_client_capabilities;
   thd->net.vio= save_vio;
 
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
   thd->profiling.finish_current_query();
 #endif
 }
@@ -551,7 +551,7 @@ pthread_handler_t handle_bootstrap(void 
     bootstrap_error= thd->is_error();
     thd->protocol->end_statement();
 
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
     thd->profiling.finish_current_query();
 #endif
 

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2009-06-12 02:01:08 +0000
+++ b/sql/sql_repl.cc	2009-06-16 12:47:31 +0000
@@ -817,18 +817,19 @@ impossible position";
 	case LOG_READ_EOF:
         {
           int ret;
+          ulong signal_cnt;
 	  DBUG_PRINT("wait",("waiting for data in binary log"));
 	  if (thd->server_id==0) // for mysqlbinlog (mysqlbinlog.server_id==0)
 	  {
 	    pthread_mutex_unlock(log_lock);
 	    goto end;
 	  }
-
+          signal_cnt= mysql_bin_log.signal_cnt;
+          do
+          {
 #ifndef DBUG_OFF
-          ulong hb_info_counter= 0;
+            ulong hb_info_counter= 0;
 #endif
-          do 
-          {
             if (coord)
             {
               DBUG_ASSERT(heartbeat_ts && heartbeat_period != 0LL);
@@ -860,12 +861,11 @@ impossible position";
             }
             else
             {
-              DBUG_ASSERT(ret == 0);
-              DBUG_PRINT("wait",("binary log received update"));
+              DBUG_PRINT("wait",("binary log received update or a broadcast signal caught"));
             }
-          } while (ret != 0 && coord != NULL && !thd->killed);
+          } while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed);
           pthread_mutex_unlock(log_lock);
-        }    
+        }
         break;
             
         default:

=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc	2009-06-19 09:28:44 +0000
+++ b/sql/sql_show.cc	2009-06-22 12:30:28 +0000
@@ -6767,7 +6767,7 @@ ST_FIELD_INFO proc_fields_info[]=
   {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE},
   {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE},
   {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-  {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment",
+  {"ROUTINE_COMMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Comment",
    SKIP_OPEN_TABLE},
   {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
   {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,

=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc	2009-05-19 08:37:33 +0000
+++ b/storage/innobase/handler/ha_innodb.cc	2009-06-18 08:20:27 +0000
@@ -8540,8 +8540,15 @@ ha_rows ha_innobase::multi_range_read_in
 {
   /* See comments in ha_myisam::multi_range_read_info_const */
   ds_mrr.init(this, table);
-  return ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges, bufsz,
-                                 flags, cost);
+  uint orig_flags= *flags;
+
+  ha_rows res= ds_mrr.dsmrr_info_const(keyno, seq, seq_init_param, n_ranges,
+                                       bufsz, flags, cost);
+
+  /* Disable DS-MRR: enable MS-MRR only after critical bugs are fixed */
+  *bufsz= 0;
+  *flags = orig_flags | HA_MRR_USE_DEFAULT_IMPL;
+  return res;
 }
 
 ha_rows ha_innobase::multi_range_read_info(uint keyno, uint n_ranges, 
@@ -8549,7 +8556,13 @@ ha_rows ha_innobase::multi_range_read_in
                                            uint *flags, COST_VECT *cost)
 {
   ds_mrr.init(this, table);
-  return ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
+  uint orig_flags= *flags;
+
+  ha_rows res= ds_mrr.dsmrr_info(keyno, n_ranges, keys, bufsz, flags, cost);
+  /* Disable DS-MRR: enable MS-MRR only after critical bugs are fixed */
+  *bufsz= 0;
+  *flags = orig_flags | HA_MRR_USE_DEFAULT_IMPL;
+  return res;
 }
 
 

=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h	2009-04-24 11:32:53 +0000
+++ b/storage/innobase/handler/ha_innodb.h	2009-06-18 08:20:27 +0000
@@ -102,8 +102,11 @@ class ha_innobase: public handler
 		  HA_READ_PREV |
 		  HA_READ_ORDER |
 		  HA_READ_RANGE |
-		  HA_KEYREAD_ONLY |
-		  ((idx == primary_key) ? 0 : HA_DO_INDEX_COND_PUSHDOWN));
+		  HA_KEYREAD_ONLY);
+		  /* Turn off engine_condition_pushdown for InnoDB.
+		  It is unstable at this point. */
+		  /* HA_KEYREAD_ONLY |
+		  ((idx == primary_key)? 0 : HA_DO_INDEX_COND_PUSHDOWN)); */
 	}
 	uint max_supported_keys()	   const { return MAX_KEY; }
 				/* An InnoDB page must store >= 2 keys;

Attachment: [text/bzr-bundle] bzr/joro@sun.com-20090622123028-4po6vy45mqgd203y.bundle
Thread
bzr commit into mysql-pe branch (joro:3387)Georgi Kodinov22 Jun