#At file:///export/home/z/mysql-azalea-bugfixing-bug36021/ based on revid:jon.hauglid@stripped5io17p0yy64
2803 Jon Olav Hauglid 2009-06-25 [merge]
manual merge
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
modified:
.bzr-mysql/default.conf
client/mysqltest.cc
mysql-test/extra/rpl_tests/rpl_row_sp006.test
mysql-test/include/gis_generic.inc
mysql-test/mysql-test-run.pl
mysql-test/r/alter_table.result
mysql-test/r/archive_gis.result
mysql-test/r/gis.result
mysql-test/r/innodb_gis.result
mysql-test/suite/backup/t/backup_db_grants.test
mysql-test/suite/backup/t/backup_objects_dependency.test
mysql-test/suite/backup/t/disabled.def
mysql-test/suite/backup_engines/t/backup_partitioning.test
mysql-test/suite/binlog/r/binlog_tmp_table.result
mysql-test/suite/binlog/t/binlog_tmp_table.test
mysql-test/suite/funcs_1/r/storedproc.result
mysql-test/suite/funcs_1/t/storedproc.test
mysql-test/suite/ndb/t/disabled.def
mysql-test/suite/ndb/t/ndb_basic.test
mysql-test/suite/ndb/t/ndb_index.test
mysql-test/suite/ndb/t/ndb_index_ordered.test
mysql-test/suite/ndb_binlog/t/ndb_binlog_basic.test
mysql-test/suite/ndb_team/t/ndb_autodiscover.test
mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc
mysql-test/suite/parts/inc/partition_decimal.inc
mysql-test/suite/parts/inc/partition_double.inc
mysql-test/suite/parts/inc/partition_float.inc
mysql-test/suite/parts/t/disabled.def
mysql-test/suite/rpl/r/rpl_heartbeat.result
mysql-test/suite/rpl/r/rpl_row_sp006_InnoDB.result
mysql-test/suite/rpl/t/disabled.def
mysql-test/suite/rpl/t/rpl000017.test
mysql-test/suite/rpl/t/rpl_backup_multi.test
mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test
mysql-test/suite/rpl/t/rpl_cross_version.test
mysql-test/suite/rpl/t/rpl_extraCol_myisam.test
mysql-test/suite/rpl/t/rpl_heartbeat.test
mysql-test/suite/rpl/t/rpl_killed_ddl.test
mysql-test/suite/rpl/t/rpl_row_colSize.test
mysql-test/suite/rpl/t/rpl_row_create_table.test
mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test
mysql-test/suite/rpl/t/rpl_stm_log.test
mysql-test/suite/rpl/t/rpl_temporary.test
mysql-test/suite/rpl/t/rpl_truncate_3innodb.test
mysql-test/suite/sys_vars/inc/timestamp_basic.inc
mysql-test/suite/sys_vars/t/automatic_sp_privileges_func.test
mysql-test/suite/sys_vars/t/foreign_key_checks_func.test
mysql-test/t/alter_table.test
mysql-test/t/csv_not_null.test
mysql-test/t/ctype_ldml.test
mysql-test/t/ctype_utf8.test
mysql-test/t/gis.test
mysql-test/t/index_merge_innodb.test
mysql-test/t/information_schema.test
mysql-test/t/information_schema_db.test
mysql-test/t/innodb_ctype_ldml.test
mysql-test/t/mysqlbinlog-cp932.test
mysql-test/t/mysqldump.test
mysql-test/t/partition_mgm_err2.test
mysql-test/t/partition_not_windows.test
mysql-test/t/ps.test
mysql-test/t/query_cache.test
mysql-test/t/show_check.test
mysql-test/t/skip_name_resolve.test
mysql-test/t/sp.test
mysql-test/t/symlink.test
mysql-test/t/trigger.test
sql/log.cc
sql/log.h
sql/opt_range.cc
sql/rpl_handler.cc
sql/slave.cc
sql/sql_repl.cc
sql/sql_table.cc
sql/table.cc
=== modified file '.bzr-mysql/default.conf'
--- a/.bzr-mysql/default.conf 2009-06-17 07:30:19 +0000
+++ b/.bzr-mysql/default.conf 2009-06-19 07:44:35 +0000
@@ -1,5 +1,5 @@
[MYSQL]
-tree_location = "bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-azalea-bugfixing"
+tree_location = "bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-azalea"
post_commit_to = "commits@stripped"
post_push_to = "commits@stripped"
-tree_name = "mysql-5.4-bugfixing"
+tree_name = "mysql-5.4"
=== modified file 'client/mysqltest.cc'
--- a/client/mysqltest.cc 2009-06-17 07:30:19 +0000
+++ b/client/mysqltest.cc 2009-06-19 12:41:16 +0000
@@ -114,6 +114,8 @@ static uint my_end_arg= 0;
/* Number of lines of the result to include in failure report */
static uint opt_tail_lines= 0;
+static uint opt_connect_timeout= 0;
+
static char delimiter[MAX_DELIMITER_LENGTH]= ";";
static uint delimiter_length= 1;
@@ -5026,6 +5028,11 @@ void do_connect(struct st_command *comma
#endif
if (!mysql_init(&con_slot->mysql))
die("Failed on mysql_init()");
+
+ if (opt_connect_timeout)
+ mysql_options(&con_slot->mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
+
if (opt_compress || con_compress)
mysql_options(&con_slot->mysql, MYSQL_OPT_COMPRESS, NullS);
mysql_options(&con_slot->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
@@ -5824,6 +5831,11 @@ static struct my_option my_long_options[
{"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select",
(uchar**) &view_protocol, (uchar**) &view_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
+ "Number of seconds before connection timeout.",
+ (uchar**) &opt_connect_timeout,
+ (uchar**) &opt_connect_timeout, 0, GET_UINT, REQUIRED_ARG,
+ 120, 0, 3600 * 12, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -7049,6 +7061,10 @@ int util_query(MYSQL* org_mysql, const c
if (!(mysql= mysql_init(mysql)))
die("Failed in mysql_init()");
+ if (opt_connect_timeout)
+ mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
+
/* enable local infile, in non-binary builds often disabled by default */
mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0);
safe_connect(mysql, "util", org_mysql->host, org_mysql->user,
@@ -7706,6 +7722,9 @@ int main(int argc, char **argv)
st_connection *con= connections;
if (!( mysql_init(&con->mysql)))
die("Failed in mysql_init()");
+ if (opt_connect_timeout)
+ mysql_options(&con->mysql, MYSQL_OPT_CONNECT_TIMEOUT,
+ (void *) &opt_connect_timeout);
if (opt_compress)
mysql_options(&con->mysql,MYSQL_OPT_COMPRESS,NullS);
mysql_options(&con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
=== 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
=== modified file 'mysql-test/include/gis_generic.inc'
--- a/mysql-test/include/gis_generic.inc 2007-03-29 10:00:32 +0000
+++ b/mysql-test/include/gis_generic.inc 2009-06-24 19:39:33 +0000
@@ -108,7 +108,8 @@ explain extended select AsText(Centroid(
SELECT fid, IsClosed(g) FROM gis_multi_line ORDER by fid;
-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
+# -- [DISABLED Bug#38092]
+# SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
SELECT fid, NumGeometries(g) from gis_multi_point ORDER by fid;
=== 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-17 07:30:19 +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/alter_table.result'
--- a/mysql-test/r/alter_table.result 2009-02-13 16:30:54 +0000
+++ b/mysql-test/r/alter_table.result 2009-06-24 09:53:11 +0000
@@ -1277,3 +1277,7 @@ DROP i,
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1;
DROP TABLE t1;
+CREATE TABLE t1 (id int);
+INSERT INTO t1 VALUES (1), (2);
+ALTER TABLE t1 ADD COLUMN (f1 INT), ADD COLUMN (f2 INT), ADD KEY f2k(f2);
+DROP TABLE t1;
=== modified file 'mysql-test/r/archive_gis.result'
--- a/mysql-test/r/archive_gis.result 2009-02-10 14:51:18 +0000
+++ b/mysql-test/r/archive_gis.result 2009-06-24 19:39:33 +0000
@@ -324,11 +324,6 @@ fid IsClosed(g)
114 0
115 0
116 0
-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
-fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
-119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g)
117 1684.5
=== modified file 'mysql-test/r/gis.result'
--- a/mysql-test/r/gis.result 2009-04-29 03:50:14 +0000
+++ b/mysql-test/r/gis.result 2009-06-24 19:39:33 +0000
@@ -316,11 +316,6 @@ fid IsClosed(g)
114 0
115 0
116 0
-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
-fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
-119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon;
fid Area(g)
117 1684.5
=== modified file 'mysql-test/r/innodb_gis.result'
--- a/mysql-test/r/innodb_gis.result 2009-02-10 14:51:18 +0000
+++ b/mysql-test/r/innodb_gis.result 2009-06-24 19:39:33 +0000
@@ -324,11 +324,6 @@ fid IsClosed(g)
114 0
115 0
116 0
-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon ORDER by fid;
-fid AsText(Centroid(g))
-117 POINT(55.58852775304245 17.426536064113982)
-118 POINT(55.58852775304245 17.426536064113982)
-119 POINT(2 2)
SELECT fid, Area(g) FROM gis_multi_polygon ORDER by fid;
fid Area(g)
117 1684.5
=== modified file 'mysql-test/suite/backup/t/backup_db_grants.test'
--- a/mysql-test/suite/backup/t/backup_db_grants.test 2009-03-04 10:20:21 +0000
+++ b/mysql-test/suite/backup/t/backup_db_grants.test 2009-06-24 19:39:33 +0000
@@ -110,7 +110,7 @@ SHOW GRANTS FOR 'bup_user3'@'%';
--error ER_NONEXISTING_GRANT
SHOW GRANTS FOR 'no_user'@'%';
-#
+# -- [DISABLED Bug#39016]
# Section of test disabled due to errors in PB. See BUG#39016
#
#--echo Now demonstrate what happens when grants are altered in backup image.
=== modified file 'mysql-test/suite/backup/t/backup_objects_dependency.test'
--- a/mysql-test/suite/backup/t/backup_objects_dependency.test 2009-03-11 01:14:44 +0000
+++ b/mysql-test/suite/backup/t/backup_objects_dependency.test 2009-06-24 19:39:33 +0000
@@ -432,7 +432,7 @@ SHOW CREATE TABLE ob3.tp;
SHOW CREATE TABLE ob2.t23;
SHOW CREATE TABLE ob3.tp;
-#
+# -- [DISABLED Bug#43549]
# BUG#43549 This portion disabled because the firing of the event is
# non-deterministic.
#
@@ -528,7 +528,7 @@ SHOW CREATE TABLE ob3.tp;
SHOW CREATE TABLE ob2.t23;
SHOW CREATE TABLE ob3.tp;
-#
+# -- [DISABLED Bug#43549]
# BUG#43549 This portion disabled because the firing of the event is
# non-deterministic.
#
@@ -646,7 +646,7 @@ INSERT INTO ob3.t32 VALUES(97);
SELECT * FROM ob3.t32;
SELECT * FROM ob1.t14;
-#
+# -- [DISABLED Bug#43549]
# BUG#43549 This portion disabled because the firing of the event is
# non-deterministic.
#
@@ -739,7 +739,7 @@ Let $db=ob3;
--error ER_NO_SUCH_TABLE
CALL ob3.fire('user3 created');
-#
+# -- [DISABLED Bug#43549]
# BUG#43549 This portion disabled because the firing of the event is
# non-deterministic.
#
=== modified file 'mysql-test/suite/backup/t/disabled.def'
--- a/mysql-test/suite/backup/t/disabled.def 2009-06-18 11:28:01 +0000
+++ b/mysql-test/suite/backup/t/disabled.def 2009-06-25 09:29:53 +0000
@@ -1,4 +1,4 @@
-|##############################################################################
+##############################################################################
#
# List the test cases that are to be disabled temporarily.
#
=== modified file 'mysql-test/suite/backup_engines/t/backup_partitioning.test'
--- a/mysql-test/suite/backup_engines/t/backup_partitioning.test 2009-03-12 19:50:43 +0000
+++ b/mysql-test/suite/backup_engines/t/backup_partitioning.test 2009-06-24 19:39:33 +0000
@@ -193,6 +193,7 @@ ALTER TABLE `ê` PARTITION BY KEY(DOB) P
#Bug#20129
#We can include these operations in the test case once this bug is fixed.
+# -- [DISABLED Bug#45712]
#Bug#38784 Mysql server crash if table is altered with partition changes.
#This happens only in Windows OS. The # can be removed once the bug#38784
#is fixed.
=== 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/storedproc.result'
--- a/mysql-test/suite/funcs_1/r/storedproc.result 2009-06-12 09:37:59 +0000
+++ b/mysql-test/suite/funcs_1/r/storedproc.result 2009-06-24 19:39:33 +0000
@@ -16797,18 +16797,12 @@ BEGIN
set f1 = (f1 / 2); set f1 = (f1 * 2); set f1 = (f1 - 10); set f1 = (f1 + 10);
return f1;
END//
-SELECT fn50(4.29e+09);
-fn50(4.29e+09)
-4290000000
DROP FUNCTION IF EXISTS fn51;
CREATE FUNCTION fn51( f1 int unsigned zerofill) returns int unsigned zerofill
BEGIN
set f1 = (f1 / 2); set f1 = (f1 * 2); set f1 = (f1 - 10); set f1 = (f1 + 10);
return f1;
END//
-SELECT fn51(4.29e+09);
-fn51(4.29e+09)
-4290000000
DROP FUNCTION IF EXISTS fn52;
CREATE FUNCTION fn52( f1 int zerofill) returns int zerofill
BEGIN
@@ -17928,18 +17922,12 @@ BEGIN
set f1 = (f1 / 2); set f1 = (f1 * 2); set f1 = (f1 - 10); set f1 = (f1 + 10);
SELECT f1;
END//
-CALL sp50(4.29e+09);
-f1
-4290000000
DROP PROCEDURE IF EXISTS sp51;
CREATE PROCEDURE sp51( f1 int unsigned zerofill)
BEGIN
set f1 = (f1 / 2); set f1 = (f1 * 2); set f1 = (f1 - 10); set f1 = (f1 + 10);
SELECT f1;
END//
-CALL sp51(4.29e+09);
-f1
-4290000000
DROP PROCEDURE IF EXISTS sp52;
CREATE PROCEDURE sp52( f1 int zerofill)
BEGIN
@@ -21390,11 +21378,6 @@ set var7 = -9.22e+18;
CALL sp81(4.29e+09, var1, var2, -9.22e+18, var3, var4, -9.22e+18, var5, var6, -9.22e+18, var7, var8);
SELECT var1, var2, var3, var4, var5, var6, var7, var8;
END//
-CALL spexecute81();
-f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
-4290000000 4290000000 4290000010 -9220000000000000000 6744073709551616 6744073709551616 -9220000000000000000 6744073709551616 6744073709551616 -9220000000000000000 6744073709551616 6744073709551616
-var1 var2 var3 var4 var5 var6 var7 var8
-4290000000 4290000010 6744073709551616 6744073709551616 6744073709551616 6744073709551616 6744073709551616 6744073709551616
DROP PROCEDURE spexecute81;
DROP PROCEDURE sp81;
DROP PROCEDURE IF EXISTS sp82;
@@ -21424,11 +21407,6 @@ set var7 = -9.22e+18;
CALL sp82(4.29e+09, var1, var2, -9.22e+18, var3, var4, -9.22e+18, var5, var6, -9.22e+18, var7, var8);
SELECT var1, var2, var3, var4, var5, var6, var7, var8;
END//
-CALL spexecute82();
-f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
-4290000000 4290000000 4290000010 -9220000000000000000 6744073709551616 6744073709551616 -9220000000000000000 6744073709551616 6744073709551616 -9220000000000000000 6744073709551616 6744073709551616
-var1 var2 var3 var4 var5 var6 var7 var8
-4290000000 4290000010 6744073709551616 6744073709551616 6744073709551616 6744073709551616 6744073709551616 6744073709551616
DROP PROCEDURE spexecute82;
DROP PROCEDURE sp82;
DROP PROCEDURE IF EXISTS sp83;
=== modified file 'mysql-test/suite/funcs_1/t/storedproc.test'
--- a/mysql-test/suite/funcs_1/t/storedproc.test 2009-06-09 16:22:40 +0000
+++ b/mysql-test/suite/funcs_1/t/storedproc.test 2009-06-24 19:39:33 +0000
@@ -444,6 +444,7 @@ BEGIN
END//
delimiter ;//
+# -- [DISABLED Bug#33396]
# warnings for this select disabled due to diffs with/without --ps-protocol:
# without ps-protocol the following warning is shown:
# +Note 1291 Column '' has duplicated value 'value1' in SET
@@ -468,6 +469,7 @@ BEGIN
END//
delimiter ;//
+# -- [DISABLED Bug#33396]
# warnings for this select disabled due to diffs with/without --ps-protocol:
# without ps-protocol the following warning is shown:
# +Note 1291 Column '' has duplicated value 'value1' in SET
@@ -20541,7 +20543,8 @@ BEGIN
END//
delimiter ;//
-SELECT fn50(4.29e+09);
+# -- [DISABLED Bug#45293]
+# SELECT fn50(4.29e+09);
--disable_warnings
@@ -20556,7 +20559,8 @@ BEGIN
END//
delimiter ;//
-SELECT fn51(4.29e+09);
+# -- [DISABLED Bug#45293]
+# SELECT fn51(4.29e+09);
--disable_warnings
@@ -22139,7 +22143,8 @@ BEGIN
END//
delimiter ;//
-CALL sp50(4.29e+09);
+# -- [DISABLED Bug#45293]
+# CALL sp50(4.29e+09);
--disable_warnings
DROP PROCEDURE IF EXISTS sp51;
@@ -22153,7 +22158,8 @@ BEGIN
END//
delimiter ;//
-CALL sp51(4.29e+09);
+# -- [DISABLED Bug#45293]
+# CALL sp51(4.29e+09);
--disable_warnings
DROP PROCEDURE IF EXISTS sp52;
@@ -26122,7 +26128,8 @@ BEGIN
END//
delimiter ;//
-CALL spexecute81();
+# -- [DISABLED Bug#45293]
+# CALL spexecute81();
DROP PROCEDURE spexecute81;
DROP PROCEDURE sp81;
@@ -26160,7 +26167,8 @@ BEGIN
END//
delimiter ;//
-CALL spexecute82();
+# -- [DISABLED Bug#45293]
+# CALL spexecute82();
DROP PROCEDURE spexecute82;
DROP PROCEDURE sp82;
=== modified file 'mysql-test/suite/ndb/t/disabled.def'
--- a/mysql-test/suite/ndb/t/disabled.def 2009-03-06 22:17:00 +0000
+++ b/mysql-test/suite/ndb/t/disabled.def 2009-06-24 19:39:33 +0000
@@ -14,5 +14,5 @@ ndb_partition_error2 : Bug#40989 msven
# the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
#ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events
ndb_cache_trans : Bug#42565 ndb_cache_trans failure since SERVER_STATUS_IN_TRANS added to hash key
-ndb_alter_table_online : WL#4284: Needs to be reworked, tries to alter table used by a pending transaction.
-ndb_alter_table3 : WL#4284: Needs to be reworked, tries to alter table used by a pending transaction.
+ndb_alter_table_online : Bug#45621 2009-06-19 alik A few test files are disabled due to WL#4284
+ndb_alter_table3 : Bug#45621 2009-06-10 alik A few test files are disabled due to WL#4284
=== modified file 'mysql-test/suite/ndb/t/ndb_basic.test'
--- a/mysql-test/suite/ndb/t/ndb_basic.test 2008-10-15 12:14:27 +0000
+++ b/mysql-test/suite/ndb/t/ndb_basic.test 2009-06-24 19:39:33 +0000
@@ -6,6 +6,7 @@ DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t
drop database if exists mysqltest;
--enable_warnings
+# -- [DISABLED Bug#45709]
# workaround for bug#16445
# remove to reproduce bug and run tests from ndb start
# and with ndb_autodiscover disabled. Fails on Linux 50 % of the times
=== modified file 'mysql-test/suite/ndb/t/ndb_index.test'
--- a/mysql-test/suite/ndb/t/ndb_index.test 2007-07-04 20:38:53 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index.test 2009-06-24 19:39:33 +0000
@@ -43,6 +43,8 @@ select port, accessnode, pop, accesstype
select port, accessnode, pop, accesstype from t1 where pop='pop98';
select port, accessnode, pop, accesstype from t1 where pop='pop98';
select port, accessnode, pop, accesstype from t1 where pop='pop98' order by accesstype;
+
+# -- [DISABLED Bug#45720]
# The following two querys will not return any rows since
# the index used for access is case sensitive
# They are thus disabled for now
=== modified file 'mysql-test/suite/ndb/t/ndb_index_ordered.test'
--- a/mysql-test/suite/ndb/t/ndb_index_ordered.test 2009-03-06 22:17:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_index_ordered.test 2009-06-24 19:39:33 +0000
@@ -334,6 +334,7 @@ select count(*)- 4 from t1 use index (v)
drop table t1;
#
+# -- [DISABLED Bug#45721]
# Disabled due to WL#4284
#
# Needs to be reworked. It's not possible anymore to do a non-fast alter table
=== modified file 'mysql-test/suite/ndb_binlog/t/ndb_binlog_basic.test'
--- a/mysql-test/suite/ndb_binlog/t/ndb_binlog_basic.test 2009-01-29 12:44:41 +0000
+++ b/mysql-test/suite/ndb_binlog/t/ndb_binlog_basic.test 2009-06-24 19:39:33 +0000
@@ -48,6 +48,7 @@ select inserts,updates,deletes from
mysql.ndb_binlog_index where epoch > @max_epoch and updates > 0;
#
+# -- [DISABLED Bug#45722]
# check that purge clears the ndb_binlog_index
#
# TODO: make this deterministic
=== modified file 'mysql-test/suite/ndb_team/t/ndb_autodiscover.test'
--- a/mysql-test/suite/ndb_team/t/ndb_autodiscover.test 2009-02-20 13:35:24 +0000
+++ b/mysql-test/suite/ndb_team/t/ndb_autodiscover.test 2009-06-24 19:39:33 +0000
@@ -1,6 +1,7 @@
-- source include/have_ndb.inc
-- source include/not_embedded.inc
+# -- [DISABLED Bug#41308]
# Bug#41308: Test main.ndb_autodiscover.test doesn't work on Windows due
# to 'grep' calls
# Test is currently disabled on Windows via the next line until this bug
@@ -510,6 +511,7 @@ drop database test_only_ndb_tables;
# a table with tha same name as a table that can't be
# discovered( for example a table created via NDBAPI)
+# -- [DISABLED Bug#45725]
# Test disabled since it doesn't work on case insensitive systems
#--error ER_TABLE_EXISTS_ERROR
#CREATE TABLE sys.SYSTAB_0 (a int);
=== modified file 'mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc'
--- a/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc 2007-11-20 15:04:07 +0000
+++ b/mysql-test/suite/parts/inc/part_supported_sql_funcs_main.inc 2009-06-24 19:39:33 +0000
@@ -48,6 +48,7 @@ let $val1 = 5.1230;
let $val2 = 13.345;
let $val3 = 17.987;
let $val4 = 15.654 ;
+# -- [DISABLED Bug#45717]
# DISABLED due to bug 30577
#--source suite/parts/inc/partition_supported_sql_funcs.inc
@@ -59,6 +60,7 @@ let $val1 = 5.1230;
let $val2 = 13.345;
let $val3 = 17.987;
let $val4 = 15.654 ;
+# -- [DISABLED Bug#45717]
# DISABLED due to bug 30577
#--source suite/parts/inc/partition_supported_sql_funcs.inc
=== modified file 'mysql-test/suite/parts/inc/partition_decimal.inc'
--- a/mysql-test/suite/parts/inc/partition_decimal.inc 2008-02-06 14:13:56 +0000
+++ b/mysql-test/suite/parts/inc/partition_decimal.inc 2009-06-24 19:39:33 +0000
@@ -35,6 +35,7 @@ dec $count;
select count(*) from t2;
drop table t2;
+# -- [DISABLED Bug#45717]
# Bug 30577: FLOOR() and CEILING() not usable as partition functions
# Partition functions are required to return INT_RESULT; FLOOR() and
# CEILING() do not, unless they have an INT argument. Disable this
=== modified file 'mysql-test/suite/parts/inc/partition_double.inc'
--- a/mysql-test/suite/parts/inc/partition_double.inc 2008-02-06 14:13:56 +0000
+++ b/mysql-test/suite/parts/inc/partition_double.inc 2009-06-24 19:39:33 +0000
@@ -36,6 +36,7 @@ select count(*) from t2;
drop table t2;
+# -- [DISABLED Bug#45717]
# Bug 30577: FLOOR() and CEILING() not usable as partition functions
# Partition functions are required to return INT_RESULT; FLOOR() and
# CEILING() do not, unless they have an INT argument. Disable this
=== modified file 'mysql-test/suite/parts/inc/partition_float.inc'
--- a/mysql-test/suite/parts/inc/partition_float.inc 2008-02-06 14:13:56 +0000
+++ b/mysql-test/suite/parts/inc/partition_float.inc 2009-06-24 19:39:33 +0000
@@ -39,6 +39,7 @@ dec $count;
select count(*) from t2;
drop table t2;
+# -- [DISABLED Bug#45717]
# Bug 30577: FLOOR() and CEILING() not usable as partition functions
# Partition functions are required to return INT_RESULT; FLOOR() and
# CEILING() do not, unless they have an INT argument. Disable this
=== modified file 'mysql-test/suite/parts/t/disabled.def'
--- a/mysql-test/suite/parts/t/disabled.def 2009-06-11 03:59:25 +0000
+++ b/mysql-test/suite/parts/t/disabled.def 2009-06-24 19:39:33 +0000
@@ -1,4 +1,4 @@
-partition_basic_ndb : Bug#19899 Crashing the server (cannot create t1)
+partition_basic_ndb : Bug#45710
# http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-limitations-syntax.html
partition_syntax_ndb : Bug#36735 Not supported
ndb_dd_backuprestore : Bug#32659 2008-07-14 alik Disabled to make 6.0 greaner (the test fails too often)
=== 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.1 identified by 'rpl';
+flush privileges;
+set sql_log_bin=1;
+[ on slave ]
+grant replication slave on *.* to rpl@127.0.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.0.1;
+flush privileges;
=== modified file 'mysql-test/suite/rpl/t/disabled.def'
--- a/mysql-test/suite/rpl/t/disabled.def 2009-06-11 14:24:28 +0000
+++ b/mysql-test/suite/rpl/t/disabled.def 2009-06-24 19:39:33 +0000
@@ -15,6 +15,6 @@ rpl_extraColmaster_myisam : BUG#40796 2
rpl_cross_version : BUG#42311 2009-03-27 joro rpl_cross_version fails on macosx
rpl_heartbeat_basic : Bug#43828 Sporadic failures (Serge.Kozlov@stripped)
rpl_heartbeat_2slaves : Bug#43828 Sporadic failures (Serge.Kozlov@stripped)
-rpl_failed_optimize : WL#4284: Can't optimize table used by a pending transaction (there is metadata lock on the table).
-rpl_read_only : WL#4284: Setting Read only won't succeed until all metadata locks are released.
-rpl_init_slave : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows
+rpl_failed_optimize : Bug#44938 Replication fails when optimizing a table used by pending transaction.
+rpl_read_only : Bug#44958 Setting read_only won't succeed if tx is already started in different connection
+rpl_init_slave : Bug#44920 2009-05-18 pcrews MTR2 is not processing master.opt input properly on Windows
=== 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@127.0.0.1 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_backup_multi.test'
--- a/mysql-test/suite/rpl/t/rpl_backup_multi.test 2009-05-26 22:21:34 +0000
+++ b/mysql-test/suite/rpl/t/rpl_backup_multi.test 2009-06-24 19:39:33 +0000
@@ -9,6 +9,9 @@
--source include/not_embedded.inc
--source include/have_innodb.inc
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
# Set up multi master-slave configuration
--source suite/rpl/include/rpl_backup_multi.inc
=== modified file 'mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test'
--- a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test 2008-10-29 17:40:17 +0000
+++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test 2009-06-24 19:39:33 +0000
@@ -6,6 +6,10 @@
# AUTO_INCREMENT_OFFSET variables and failover
#############################################################
--source include/have_innodb.inc
+
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
# Use wait_for_slave_to_(start|stop) for current connections
let $keep_connection= 1;
=== modified file 'mysql-test/suite/rpl/t/rpl_cross_version.test'
--- a/mysql-test/suite/rpl/t/rpl_cross_version.test 2009-02-16 12:51:39 +0000
+++ b/mysql-test/suite/rpl/t/rpl_cross_version.test 2009-06-24 19:39:33 +0000
@@ -12,6 +12,7 @@
--source include/have_log_bin.inc
+# -- [DISABLED Bug#42879]
# The test is disabled for windows due to
# Bug #42879 CHANGE MASTER RELAY_LOG_FILE=path fails on windows
# Todo: release it from not_windows
=== modified file 'mysql-test/suite/rpl/t/rpl_extraCol_myisam.test'
--- a/mysql-test/suite/rpl/t/rpl_extraCol_myisam.test 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_extraCol_myisam.test 2009-06-24 19:39:33 +0000
@@ -4,7 +4,12 @@
# Purpose: Wapper for rpl_extraSlave_Col.test
# Using MyISAM
###########################################
+
-- source include/have_binlog_format_row.inc
+
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
-- source include/master-slave.inc
let $engine_type = 'MyISAM';
-- source extra/rpl_tests/rpl_extraSlave_Col.test
=== 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;
=== modified file 'mysql-test/suite/rpl/t/rpl_killed_ddl.test'
--- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test 2009-04-08 23:42:51 +0000
+++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test 2009-06-24 19:39:33 +0000
@@ -144,6 +144,7 @@ let $diff_statement= SHOW DATABASES LIKE
send CREATE DATABASE d2;
source include/kill_query_and_diff_master_slave.inc;
+# -- [DISABLED Bug#44041]
# Temporarily disabled, see BUG#44041, the ALTER DATABASE can affect the
# collation of other database on slave
#send ALTER DATABASE d1
@@ -166,6 +167,7 @@ send CREATE EVENT e2
DO INSERT INTO test.t1 VALUES (2);
source include/kill_query_and_diff_master_slave.inc;
+# -- [DISABLED Bug#44171]
# Temporarily disabled because of BUG#44171, killing ALTER EVENT can
# crash the server
#send ALTER EVENT e1
@@ -197,6 +199,7 @@ source include/kill_query_and_diff_maste
# function f2 probably does not exist because the CREATE query was
# killed
#
+# -- [DISABLED Bug#43353]
# Temporarily disabled. Because of BUG#43353, KILL the query may
# result in function not found, and for 5.1, DROP statements will be
# logged if the function is not found on master, so the following DROP
@@ -256,6 +259,7 @@ source include/kill_query_and_diff_maste
######## SERVER ########
+# -- [DISABLED Bug#25705]
# Tempoarily disabled, see bug#25705
# let $diff_statement= SELECT * FROM mysql.server WHERE name like 's%';
=== modified file 'mysql-test/suite/rpl/t/rpl_row_colSize.test'
--- a/mysql-test/suite/rpl/t/rpl_row_colSize.test 2007-08-10 16:48:01 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_colSize.test 2009-06-24 19:39:33 +0000
@@ -6,6 +6,9 @@
# having columns that are smaller (shorter) than the slave. #
##################################################################
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
-- source include/master-slave.inc
-- source include/have_binlog_format_row.inc
=== modified file 'mysql-test/suite/rpl/t/rpl_row_create_table.test'
--- a/mysql-test/suite/rpl/t/rpl_row_create_table.test 2009-02-02 15:58:48 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_create_table.test 2009-06-24 19:39:33 +0000
@@ -1,6 +1,9 @@
# Testing table creations for row-based replication.
-
--source include/have_binlog_format_row.inc
+
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
--source include/master-slave.inc
--source include/have_innodb.inc
connection slave;
=== modified file 'mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test'
--- a/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test 2009-04-28 22:19:38 +0000
+++ b/mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test 2009-06-24 19:39:33 +0000
@@ -181,8 +181,6 @@ select "--- Test 3 First Remote test --"
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --stop-position=569 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
-# This part is disabled due to bug #17654
-
--disable_query_log
select "--- Test 4 Second Remote test --" as "";
--enable_query_log
=== 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@127.0.0.1 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/suite/rpl/t/rpl_stm_log.test'
--- a/mysql-test/suite/rpl/t/rpl_stm_log.test 2007-06-27 12:29:10 +0000
+++ b/mysql-test/suite/rpl/t/rpl_stm_log.test 2009-06-24 19:39:33 +0000
@@ -1,5 +1,10 @@
# Requires statement logging
+
-- source include/have_binlog_format_mixed_or_statement.inc
+
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
-- source include/master-slave.inc
let $engine_type=MyISAM;
-- source extra/rpl_tests/rpl_log.test
=== modified file 'mysql-test/suite/rpl/t/rpl_temporary.test'
--- a/mysql-test/suite/rpl/t/rpl_temporary.test 2009-05-22 23:44:08 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temporary.test 2009-06-24 19:39:33 +0000
@@ -1,6 +1,9 @@
# Test need anonymous user when connection are made as "zedjzlcsjhd"
source include/add_anonymous_users.inc;
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
-- source include/master-slave.inc
# Clean up old slave's binlogs.
=== modified file 'mysql-test/suite/rpl/t/rpl_truncate_3innodb.test'
--- a/mysql-test/suite/rpl/t/rpl_truncate_3innodb.test 2007-06-27 12:28:02 +0000
+++ b/mysql-test/suite/rpl/t/rpl_truncate_3innodb.test 2009-06-24 19:39:33 +0000
@@ -2,5 +2,9 @@
--source include/have_innodb.inc
--source include/not_ndb_default.inc
+# -- [DISABLED Bug#45238]
+--source include/not_windows.inc
+
+
let $engine=InnoDB;
--source extra/rpl_tests/rpl_truncate.test
=== modified file 'mysql-test/suite/sys_vars/inc/timestamp_basic.inc'
--- a/mysql-test/suite/sys_vars/inc/timestamp_basic.inc 2009-02-03 09:16:53 +0000
+++ b/mysql-test/suite/sys_vars/inc/timestamp_basic.inc 2009-06-24 19:39:33 +0000
@@ -102,6 +102,7 @@ SET @@timestamp = 9999999999999999999999
# Check if the value in SESSION Table matches value in variable #
#########################################################################
+# -- [DISABLED Bug#41584]
# disabled due to bug#41584
#SELECT @@timestamp = VARIABLE_VALUE
#FROM INFORMATION_SCHEMA.SESSION_VARIABLES
=== modified file 'mysql-test/suite/sys_vars/t/automatic_sp_privileges_func.test'
--- a/mysql-test/suite/sys_vars/t/automatic_sp_privileges_func.test 2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/t/automatic_sp_privileges_func.test 2009-06-24 19:39:33 +0000
@@ -127,6 +127,7 @@ disconnect conUser1;
SET GLOBAL automatic_sp_privileges = @global_automatic_sp_privileges;
+# -- [DISABLED Bug#35384]
# Disabled due to differences in results: Bug#35384
#SHOW GRANTS FOR 'userTest'@'localhost';
=== modified file 'mysql-test/suite/sys_vars/t/foreign_key_checks_func.test'
--- a/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test 2008-12-19 15:12:15 +0000
+++ b/mysql-test/suite/sys_vars/t/foreign_key_checks_func.test 2009-06-24 19:39:33 +0000
@@ -112,6 +112,7 @@ ALTER TABLE t2 DROP FOREIGN KEY fk;
SET @@session.foreign_key_checks = 1;
+# -- [DISABLED Bug#45726]
# Test disabled as error description is different. The resulting description has
# difference in code #sql-xxx_2 where xxx is different for each run.
#--Error ER_NO_REFERENCED_ROW_2
=== modified file 'mysql-test/t/alter_table.test'
--- a/mysql-test/t/alter_table.test 2009-02-13 16:30:54 +0000
+++ b/mysql-test/t/alter_table.test 2009-06-24 09:53:11 +0000
@@ -1016,3 +1016,14 @@ ALTER TABLE t1
ADD i INT UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 1;
DROP TABLE t1;
+
+#
+# Bug #45052 ALTER TABLE ADD COLUMN crashes server with multiple foreign key columns
+# The alter table fails if 2 or more new fields added and
+# also added a key with these fields
+#
+CREATE TABLE t1 (id int);
+INSERT INTO t1 VALUES (1), (2);
+ALTER TABLE t1 ADD COLUMN (f1 INT), ADD COLUMN (f2 INT), ADD KEY f2k(f2);
+DROP TABLE t1;
+
=== modified file 'mysql-test/t/csv_not_null.test'
--- a/mysql-test/t/csv_not_null.test 2009-02-05 09:49:32 +0000
+++ b/mysql-test/t/csv_not_null.test 2009-06-24 19:39:33 +0000
@@ -55,6 +55,7 @@ INSERT INTO t1 VALUES();
SELECT * FROM t1;
-- disable_warnings
+# -- [DISABLED Bug#33717]
# NOTE - Test disabled due to enum crash for this INSERT
# See Bug#33717 - INSERT...(default) fails for enum.
# Crashes CSV tables, loads spaces for MyISAM
=== modified file 'mysql-test/t/ctype_ldml.test'
--- a/mysql-test/t/ctype_ldml.test 2009-06-08 14:58:33 +0000
+++ b/mysql-test/t/ctype_ldml.test 2009-06-24 19:39:33 +0000
@@ -1,12 +1,5 @@
--source include/have_ucs2.inc
-#
-# Disabled due to WL#1213 removal
-#
-# --source include/have_utf16.inc
-# --source include/have_utf32.inc
-
-
--disable_warnings
drop table if exists t1;
--enable_warnings
=== modified file 'mysql-test/t/ctype_utf8.test'
--- a/mysql-test/t/ctype_utf8.test 2009-06-11 09:13:52 +0000
+++ b/mysql-test/t/ctype_utf8.test 2009-06-24 19:39:33 +0000
@@ -1449,33 +1449,6 @@ DROP TABLE t1;
--echo End of 5.0 tests
#
-# Disabled due to removal of WL#1213.
-#
-# #
-# # Bug#32914 Character sets: illegal characters in utf8 and utf32 columns
-# #
-# create table t1 (utf8 char(1) character set utf8);
-# --echo Testing [F0][90..BF][80..BF][80..BF]
-# insert into t1 values (0xF0908080);
-# insert into t1 values (0xF0BFBFBF);
-# insert into t1 values (0xF08F8080);
-# select hex(utf8) from t1;
-# delete from t1;
-
-# --echo Testing [F2..F3][80..BF][80..BF][80..BF]
-# insert into t1 values (0xF2808080);
-# insert into t1 values (0xF2BFBFBF);
-# select hex(utf8) from t1;
-# delete from t1;
-
-# --echo Testing [F4][80..8F][80..BF][80..BF]
-# insert into t1 values (0xF4808080);
-# insert into t1 values (0xF48F8080);
-# insert into t1 values (0xF4908080);
-# select hex(utf8) from t1;
-# drop table t1;
-
-#
# Bug#26474: Add Sinhala script (Sri Lanka) collation to MySQL
#
--disable_warnings
@@ -1541,19 +1514,4 @@ INSERT INTO t1 VALUES (19, x'E0B696'), (
SELECT predicted_order, hex(utf8_encoding) FROM t1 ORDER BY utf8_encoding COLLATE utf8_sinhala_ci;
DROP TABLE t1;
-#
-# Disabled due to removal of WL#1213.
-#
-# #
-# # Check that supplementary characters are not allowed in identifiers
-# #
-# --error 1300
-# CREATE DATABASE `𐀀`;
-# --error 1300
-# CREATE TABLE `𐀀` (a int);
-# --error 1166
-# CREATE TABLE test.t1 SELECT '𐀀';
-# --error 1300
-# CREATE USER `𐀀`;
-
--echo End of tests
=== modified file 'mysql-test/t/gis.test'
--- a/mysql-test/t/gis.test 2009-04-29 03:50:14 +0000
+++ b/mysql-test/t/gis.test 2009-06-24 19:39:33 +0000
@@ -108,7 +108,8 @@ explain extended select AsText(Centroid(
SELECT fid, IsClosed(g) FROM gis_multi_line;
-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
+# -- [DISABLED Bug#38092]
+# SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
SELECT fid, Area(g) FROM gis_multi_polygon;
SELECT fid, NumGeometries(g) from gis_multi_point;
=== modified file 'mysql-test/t/index_merge_innodb.test'
--- a/mysql-test/t/index_merge_innodb.test 2006-09-18 14:55:56 +0000
+++ b/mysql-test/t/index_merge_innodb.test 2009-06-24 19:39:33 +0000
@@ -15,6 +15,7 @@ let $engine_type= InnoDB;
# InnoDB does not support Merge tables (affects include/index_merge1.inc)
let $merge_table_support= 0;
+# -- [DISABLED Bug#45727]
# The first two tests are disabled because of non deterministic explain output.
# If include/index_merge1.inc can be enabled for InnoDB and all other
# storage engines, please remove the subtest for Bug#21277 from
=== modified file 'mysql-test/t/information_schema.test'
--- a/mysql-test/t/information_schema.test 2009-05-15 13:45:06 +0000
+++ b/mysql-test/t/information_schema.test 2009-06-24 09:41:25 +0000
@@ -1562,3 +1562,15 @@ disconnect con7;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+#
+# Bug #43834 Assertion in Natural_join_column::db_name() on an I_S query
+#
+
+SELECT *
+FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
+LEFT JOIN INFORMATION_SCHEMA.COLUMNS
+USING (TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME)
+WHERE COLUMNS.TABLE_SCHEMA = 'test'
+AND COLUMNS.TABLE_NAME = 't1';
+
+
=== modified file 'mysql-test/t/information_schema_db.test'
--- a/mysql-test/t/information_schema_db.test 2009-05-15 15:59:57 +0000
+++ b/mysql-test/t/information_schema_db.test 2009-06-24 19:39:33 +0000
@@ -1,5 +1,5 @@
# this test mostly test privilege control (what doesn't work
-# in the embedded server by default). So disabled in embedded-server mode
+# in the embedded server by default). So skip the test in embedded-server mode.
-- source include/not_embedded.inc
-- source include/testdb_only.inc
=== modified file 'mysql-test/t/innodb_ctype_ldml.test'
--- a/mysql-test/t/innodb_ctype_ldml.test 2009-06-02 18:04:09 +0000
+++ b/mysql-test/t/innodb_ctype_ldml.test 2009-06-24 19:39:33 +0000
@@ -1,13 +1,6 @@
--source include/have_innodb.inc
--source include/have_ucs2.inc
-#
-# Disabled due to WL#1213 removal.
-#
-# --source include/have_utf16.inc
-# --source include/have_utf32.inc
-
-
--disable_warnings
drop table if exists t1;
--enable_warnings
=== modified file 'mysql-test/t/mysqlbinlog-cp932.test'
--- a/mysql-test/t/mysqlbinlog-cp932.test 2007-12-12 17:19:24 +0000
+++ b/mysql-test/t/mysqlbinlog-cp932.test 2009-06-24 19:39:33 +0000
@@ -1,3 +1,4 @@
+# -- [DISABLED Bug#45728]
# disabled in embedded until tools running is fixed with embedded
--source include/not_embedded.inc
=== modified file 'mysql-test/t/mysqldump.test'
--- a/mysql-test/t/mysqldump.test 2009-05-29 16:22:30 +0000
+++ b/mysql-test/t/mysqldump.test 2009-06-24 19:39:33 +0000
@@ -1698,6 +1698,7 @@ DROP TABLE t1;
# Added for use-thread option
#
+# -- [DISABLED Bug#32991]
# THIS PART OF THE TEST IS DISABLED UNTIL Bug#32991 IS FIXED
if ($bug32991_fixed) {
=== modified file 'mysql-test/t/partition_mgm_err2.test'
--- a/mysql-test/t/partition_mgm_err2.test 2008-10-02 14:14:27 +0000
+++ b/mysql-test/t/partition_mgm_err2.test 2009-06-24 19:39:33 +0000
@@ -4,9 +4,8 @@
--source include/have_partition.inc
--source include/have_symlink.inc
-#
-# This test is disabled on windows due to BUG#19107
-#
+# -- [DISABLED Bug#33687]
+# This test is disabled on windows due to BUG#33687
--source include/not_windows.inc
#
# BUG: 14354 Partitions: data directory clause fails
=== modified file 'mysql-test/t/partition_not_windows.test'
--- a/mysql-test/t/partition_not_windows.test 2009-02-02 15:58:48 +0000
+++ b/mysql-test/t/partition_not_windows.test 2009-06-24 19:39:33 +0000
@@ -4,7 +4,8 @@
# DATA DIRECTORY/INDEX DIRECTORY require symbolic link support
--source include/have_symlink.inc
-# The test for Bug 20770 is disabled on Windows due to BUG#19107; it
+# -- [DISABLED Bug#33687]
+# The test for Bug 20770 is disabled on Windows due to BUG#33687; it
# should be moved into partition.test once the bug has been resolved.
#
=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test 2009-05-29 08:09:00 +0000
+++ b/mysql-test/t/ps.test 2009-06-24 19:39:33 +0000
@@ -2795,7 +2795,7 @@ execute abc;
deallocate prepare abc;
drop table t1, t2;
-#
+# -- [DISABLED Bug#45716]
# Bug #21422: GRANT/REVOKE possible inside stored function, probably in a trigger
# This is disabled for now till it is resolved in 5.0
#
=== modified file 'mysql-test/t/query_cache.test'
--- a/mysql-test/t/query_cache.test 2009-02-13 16:30:54 +0000
+++ b/mysql-test/t/query_cache.test 2009-06-24 19:39:33 +0000
@@ -1185,6 +1185,8 @@ set global query_cache_type=0;
show status like 'Qcache_free_blocks';
--echo Restore default values.
+#
+# -- [DISABLED Bug#45729]
# Bug#28211 RENAME DATABASE and query cache don't play nicely together
#
# TODO: enable these tests when RENAME DATABASE is implemented.
=== modified file 'mysql-test/t/show_check.test'
--- a/mysql-test/t/show_check.test 2009-03-06 20:33:52 +0000
+++ b/mysql-test/t/show_check.test 2009-06-24 19:39:33 +0000
@@ -1,4 +1,4 @@
-# Uses GRANT commands that usually disabled in embedded server
+# Uses GRANT commands that are not available in embedded server
-- source include/not_embedded.inc
# check that CSV engine was compiled in, as the result of the test
@@ -362,6 +362,7 @@ delete from mysql.db
where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
flush privileges;
+# -- [DISABLED Bug#45730]
# This test fails on MAC OSX, so it is temporary disabled.
# This needs WL#1324 to be done.
#set names latin1;
=== modified file 'mysql-test/t/skip_name_resolve.test'
--- a/mysql-test/t/skip_name_resolve.test 2009-03-10 16:11:53 +0000
+++ b/mysql-test/t/skip_name_resolve.test 2009-06-24 19:39:33 +0000
@@ -1,6 +1,9 @@
# Can't be tested with embedded server
--source include/not_embedded.inc
+# -- [DISABLED Bug#43006]
+--source include/not_windows.inc
+
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
=== modified file 'mysql-test/t/sp.test'
--- a/mysql-test/t/sp.test 2009-06-17 07:30:19 +0000
+++ b/mysql-test/t/sp.test 2009-06-24 19:39:33 +0000
@@ -3352,6 +3352,7 @@ begin
select plus;
end|
+# -- [DISABLED Bug#45707]
# QQ: This is currently disabled. Not only does it slow down a normal test
# run, it makes running with valgrind (or similar tools) extremely
# painful.
@@ -4069,6 +4070,7 @@ drop procedure if exists bug7088_1|
drop procedure if exists bug7088_2|
--enable_warnings
+# -- [DISABLED Bug#45708]
--disable_parsing # temporarily disabled until Bar fixes BUG#11986
create procedure bug6063()
lâbel: begin end|
=== modified file 'mysql-test/t/symlink.test'
--- a/mysql-test/t/symlink.test 2009-05-15 13:45:06 +0000
+++ b/mysql-test/t/symlink.test 2009-06-24 19:39:33 +0000
@@ -73,6 +73,7 @@ create database mysqltest;
--error 1,1
create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="/this-dir-does-not-exist";
+# -- [DISABLED Bug#45731]
# temporarily disabled as it returns different result in the embedded server
# --error ER_WRONG_ARGUMENTS, ER_WRONG_ARGUMENTS
# create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) engine=myisam index directory="not-hard-path";
=== modified file 'mysql-test/t/trigger.test'
--- a/mysql-test/t/trigger.test 2009-06-16 12:27:49 +0000
+++ b/mysql-test/t/trigger.test 2009-06-24 19:39:33 +0000
@@ -862,6 +862,7 @@ select * from t1;
drop trigger t1_bi;
drop tables t1, t2;
+# -- [DISABLED Bug#45732]
# Tests for bug #12704 "Server crashes during trigger execution".
# If we run DML statements and CREATE TRIGGER statements concurrently
# it may happen that trigger will be created while DML statement is
=== 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 'sql/log.cc'
--- a/sql/log.cc 2009-06-08 14:58:33 +0000
+++ b/sql/log.cc 2009-06-15 14:00:15 +0000
@@ -4218,7 +4218,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)
{
/*
@@ -6687,6 +6687,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-08 14:58:33 +0000
+++ b/sql/log.h 2009-06-15 14:00:15 +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/opt_range.cc'
--- a/sql/opt_range.cc 2009-06-09 16:53:34 +0000
+++ b/sql/opt_range.cc 2009-06-24 10:55:41 +0000
@@ -4862,13 +4862,14 @@ static TRP_RANGE *get_key_scans_params(P
found_records= check_quick_select(param, idx, read_index_only, *key,
update_tbl_stats, &mrr_flags,
&buf_size, &cost);
- found_read_time= cost.total_cost();
+
if ((found_records != HA_POS_ERROR) && param->is_ror_scan)
{
tree->n_ror_scans++;
tree->ror_scans_map.set_bit(idx);
}
- if (found_records != HA_POS_ERROR && read_time > found_read_time)
+ if (found_records != HA_POS_ERROR &&
+ read_time > (found_read_time= cost.total_cost()))
{
read_time= found_read_time;
best_records= found_records;
=== 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/slave.cc'
--- a/sql/slave.cc 2009-06-12 02:01:08 +0000
+++ b/sql/slave.cc 2009-06-15 13:30:20 +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_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_table.cc'
--- a/sql/sql_table.cc 2009-06-02 11:46:19 +0000
+++ b/sql/sql_table.cc 2009-06-24 09:53:11 +0000
@@ -5937,18 +5937,16 @@ compare_tables(THD *thd,
end= key_part + new_key->key_parts;
for(; key_part != end; key_part++)
{
- /* Mark field to be part of new key */
- if ((field= table->field[key_part->fieldnr]))
- field->flags|= FIELD_IN_ADD_INDEX;
/*
Check if all fields in key are declared
NOT NULL
*/
if (key_part->fieldnr < table->s->fields)
{
- is_not_null=
- (is_not_null &&
- (!table->field[key_part->fieldnr]->maybe_null()));
+ /* Mark field to be part of new key */
+ field= table->field[key_part->fieldnr];
+ field->flags|= FIELD_IN_ADD_INDEX;
+ is_not_null= (is_not_null && (!field->maybe_null()));
}
else
{
=== modified file 'sql/table.cc'
--- a/sql/table.cc 2009-05-29 08:09:00 +0000
+++ b/sql/table.cc 2009-06-24 09:41:25 +0000
@@ -4036,7 +4036,7 @@ const char *Natural_join_column::db_name
DBUG_ASSERT(!strcmp(table_ref->db,
table_ref->table->s->db.str) ||
(table_ref->schema_table &&
- table_ref->table->s->db.str[0] == 0));
+ is_schema_db(table_ref->table->s->db.str)));
return table_ref->db;
}
@@ -4254,7 +4254,7 @@ const char *Field_iterator_table_ref::ge
*/
DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db.str) ||
(table_ref->schema_table &&
- table_ref->table->s->db.str[0] == 0));
+ is_schema_db(table_ref->table->s->db.str)));
return table_ref->db;
}
Attachment: [text/bzr-bundle] bzr/jon.hauglid@sun.com-20090625092953-xiur7w0mz78g6nmo.bundle
| Thread |
|---|
| • bzr commit into mysql-5.4 branch (jon.hauglid:2803) | Jon Olav Hauglid | 25 Jun |