List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:June 22 2010 9:47am
Subject:bzr push into mysql-next-mr-rpl-merge branch (Li-Bing.Song:2997 to 2998)
View as plain text  
 2998 Li-Bing.Song@stripped	2010-06-22 [merge]
      Manual merge from mysql-5.1-rep+2

    added:
      mysql-test/include/show_slave_hosts.inc
      mysql-test/r/server_uuid.result
      mysql-test/suite/rpl/r/rpl_server_uuid.result
      mysql-test/suite/rpl/t/rpl_server_uuid.cnf
      mysql-test/suite/rpl/t/rpl_server_uuid.test
      mysql-test/suite/sys_vars/r/server_uuid_basic.result
      mysql-test/suite/sys_vars/t/server_uuid_basic.test
      mysql-test/t/server_uuid.test
    modified:
      mysql-test/include/mtr_warnings.sql
      mysql-test/mysql-test-run.pl
      mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result
      mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result
      mysql-test/suite/rpl/r/rpl_show_slave_hosts.result
      mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test
      mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test
      mysql-test/suite/rpl/t/rpl_show_slave_hosts.test
      mysys/default.c
      sql/item_strfunc.h
      sql/mysqld.cc
      sql/mysqld.h
      sql/repl_failsafe.cc
      sql/rpl_mi.cc
      sql/rpl_mi.h
      sql/slave.cc
      sql/slave.h
      sql/sql_parse.cc
      sql/sql_repl.cc
      sql/sql_repl.h
      sql/sys_vars.cc
 2997 Sven Sandberg	2010-06-21 [merge]
      In next-mr-rpl-bugfixing, the following things happened concurrently:
       - luis merged next-mr -> next-mr-rpl-merge
       - sven merged WL#344/BUG#28760 from 5.1-rep+2 -> next-mr-rpl-merge
      This merge merges these two merges.

    added:
      mysql-test/include/ctype_ascii_order.inc
      mysql-test/include/ctype_pad_space.inc
      mysql-test/include/weight_string.inc
      mysql-test/include/weight_string_8140.inc
      mysql-test/include/weight_string_8EA1.inc
      mysql-test/include/weight_string_8FA2C3.inc
      mysql-test/include/weight_string_A1A1.inc
      mysql-test/include/weight_string_chde.inc
      mysql-test/include/weight_string_euro.inc
      mysql-test/include/weight_string_l1.inc
      mysql-test/include/weight_string_l12.inc
      mysql-test/include/weight_string_l14.inc
      mysql-test/include/weight_string_l2.inc
      mysql-test/include/weight_string_l3.inc
      mysql-test/include/weight_string_l4.inc
      mysql-test/r/func_weight_string.result
      mysql-test/t/func_weight_string.test
    modified:
      include/m_ctype.h
      mysql-test/include/ctype_german.inc
      mysql-test/r/ctype_big5.result
      mysql-test/r/ctype_cp1250_ch.result
      mysql-test/r/ctype_cp1251.result
      mysql-test/r/ctype_cp932_binlog_stm.result
      mysql-test/r/ctype_eucjpms.result*
      mysql-test/r/ctype_euckr.result
      mysql-test/r/ctype_gb2312.result
      mysql-test/r/ctype_gbk.result
      mysql-test/r/ctype_latin1.result
      mysql-test/r/ctype_latin1_de.result
      mysql-test/r/ctype_latin2.result
      mysql-test/r/ctype_latin2_ch.result
      mysql-test/r/ctype_sjis.result
      mysql-test/r/ctype_tis620.result
      mysql-test/r/ctype_uca.result
      mysql-test/r/ctype_ucs.result
      mysql-test/r/ctype_ujis.result
      mysql-test/r/ctype_utf16.result
      mysql-test/r/ctype_utf16_uca.result
      mysql-test/r/ctype_utf32.result
      mysql-test/r/ctype_utf32_uca.result
      mysql-test/r/ctype_utf8.result
      mysql-test/r/ctype_utf8mb4.result
      mysql-test/r/ctype_utf8mb4_heap.result
      mysql-test/r/ctype_utf8mb4_innodb.result
      mysql-test/r/ctype_utf8mb4_myisam.result
      mysql-test/r/ctype_utf8mb4_ndb.result
      mysql-test/r/locale.result
      mysql-test/r/variables.result
      mysql-test/suite/sys_vars/r/lc_time_names_basic.result
      mysql-test/suite/sys_vars/t/lc_time_names_basic.test
      mysql-test/t/ctype_big5.test
      mysql-test/t/ctype_cp1250_ch.test
      mysql-test/t/ctype_cp1251.test
      mysql-test/t/ctype_cp932_binlog_stm.test
      mysql-test/t/ctype_eucjpms.test
      mysql-test/t/ctype_euckr.test
      mysql-test/t/ctype_gb2312.test
      mysql-test/t/ctype_gbk.test
      mysql-test/t/ctype_latin1.test
      mysql-test/t/ctype_latin1_de.test
      mysql-test/t/ctype_latin2.test
      mysql-test/t/ctype_latin2_ch.test
      mysql-test/t/ctype_sjis.test
      mysql-test/t/ctype_tis620.test
      mysql-test/t/ctype_uca.test
      mysql-test/t/ctype_ucs.test
      mysql-test/t/ctype_ujis.test
      mysql-test/t/ctype_utf16.test
      mysql-test/t/ctype_utf16_uca.test
      mysql-test/t/ctype_utf32.test
      mysql-test/t/ctype_utf32_uca.test
      mysql-test/t/ctype_utf8.test
      mysql-test/t/locale.test
      mysql-test/t/variables.test
      mysys/charset-def.c
      mysys/charset.c
      scripts/mysqld_safe.sh
      sql/field.cc
      sql/filesort.cc
      sql/item_strfunc.cc
      sql/item_strfunc.h
      sql/lex.h
      sql/sql_locale.cc
      sql/sql_yacc.yy
      storage/ndb/src/common/util/NdbSqlUtil.cpp
      strings/conf_to_src.c
      strings/ctype-big5.c
      strings/ctype-bin.c
      strings/ctype-cp932.c
      strings/ctype-czech.c
      strings/ctype-euc_kr.c
      strings/ctype-eucjpms.c
      strings/ctype-extra.c
      strings/ctype-gb2312.c
      strings/ctype-gbk.c
      strings/ctype-latin1.c
      strings/ctype-mb.c
      strings/ctype-simple.c
      strings/ctype-sjis.c
      strings/ctype-tis620.c
      strings/ctype-uca.c
      strings/ctype-ucs2.c
      strings/ctype-ujis.c
      strings/ctype-utf8.c
      strings/ctype-win1250ch.c
=== modified file 'mysql-test/include/mtr_warnings.sql'
--- a/mysql-test/include/mtr_warnings.sql	2010-04-11 07:17:42 +0000
+++ b/mysql-test/include/mtr_warnings.sql	2010-06-22 09:34:59 +0000
@@ -162,9 +162,14 @@ INSERT INTO global_suppressions VALUES
  ("Slave: Unknown column 'c7' in 't15' Error_code: 1054"),
  ("Slave: Can't DROP 'c7'.* 1091"),
  ("Slave: Key column 'c6'.* 1072"),
+ ("The slave I.O thread stops because a fatal error is encountered when it try to get the value of SERVER_UUID variable from master."),
+ ("init-command:'.*' failed with error:.*"),
  ("The slave I.O thread stops because a fatal error is encountered when it try to get the value of SERVER_ID variable from master."),
  (".SELECT UNIX_TIMESTAMP... failed on master, do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS"),
 
+ /*It will print a warning if a new UUID of server is generated.*/
+ ("It might be a maiden lunch of the server, for there is no UUID existing.*"),
+
  /* Test case for Bug#31590 in order_by.test produces the following error */
  ("Out of sort memory; increase server sort buffer size"),
 
@@ -205,6 +210,7 @@ INSERT INTO global_suppressions VALUES
    Transient network failures that cause warnings on reconnect.
    BUG#47743 and BUG#47983.
  */
+ ("Slave I/O: Get master SERVER_UUID failed with error:.*"),
  ("Slave I/O: Get master SERVER_ID failed with error:.*"),
  ("Slave I/O: Get master clock failed with error:.*"),
  ("Slave I/O: Get master COLLATION_SERVER failed with error:.*"),

=== added file 'mysql-test/include/show_slave_hosts.inc'
--- a/mysql-test/include/show_slave_hosts.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/show_slave_hosts.inc	2010-04-01 11:34:04 +0000
@@ -0,0 +1,3 @@
+--replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT
+--replace_regex /[0-9, a-f]{8}-[0-9, a-f]{4}-[0-9, a-f]{4}-[0-9, a-f]{4}-[0-9, a-f]{12}/SLAVE_UUID/
+SHOW SLAVE HOSTS;

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2010-06-07 09:14:56 +0000
+++ b/mysql-test/mysql-test-run.pl	2010-06-22 09:34:59 +0000
@@ -4820,6 +4820,7 @@ sub start_servers($) {
 
       # Save this test case information, so next can examine it
       $mysqld->{'started_tinfo'}= $tinfo;
+      mtr_milli_sleep(500);
     }
 
   }

=== added file 'mysql-test/r/server_uuid.result'
--- a/mysql-test/r/server_uuid.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/r/server_uuid.result	2010-04-01 11:34:04 +0000
@@ -0,0 +1,19 @@
+CALL mtr.add_suppression("Master's UUID has changed, its old UUID is");
+
+# Case 1:
+# @@SERVER_UUID is readonly.
+-----------------------------------------------------------------------------
+SET GLOBAL SERVER_UUID= UUID();
+ERROR HY000: Variable 'server_uuid' is a read only variable
+
+# Case 2:
+# If the file does not exists, mysqld generates it automatically.
+-----------------------------------------------------------------------------
+
+# Case 3:
+# If there is no UUID in the file, mysqld generates it automatically.
+-----------------------------------------------------------------------------
+
+# Case 4:
+# If there is a UUID in the file, it will be loaded into SERVER_UUID.
+-----------------------------------------------------------------------------

=== modified file 'mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result'
--- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result	2010-06-19 09:24:34 +0000
+++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result	2010-06-22 09:34:59 +0000
@@ -24,6 +24,14 @@ slave is unblocked
 SET DEBUG_SYNC='now SIGNAL signal.get_server_id';
 Check network error happened here
 set @@global.debug = "-d,'debug_lock.before_get_SERVER_ID'";
+stop slave;
+SET @@global.debug= "+d,'dbug.before_get_MASTER_UUID'";
+start slave;
+slave is going to hang in get_master_version_and_clock
+slave is unblocked
+SET DEBUG_SYNC='now SIGNAL signal.get_master_uuid';
+Check network error happened here
+set @@global.debug = "-d,'dbug.before_get_MASTER_UUID'";
 set global debug= '';
 reset master;
 include/stop_slave.inc

=== modified file 'mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result'
--- a/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result	2009-10-20 06:30:15 +0000
+++ b/mysql-test/suite/rpl/r/rpl_mixed_ddl_dml.result	2010-06-22 01:41:53 +0000
@@ -12,9 +12,9 @@ n
 2000
 2001
 2002
-show slave hosts;
-Server_id	Host	Port	Master_id
-2	127.0.0.1	9999	1
+SHOW SLAVE HOSTS;
+Server_id	Host	Port	Master_id	Slave_UUID
+2	127.0.0.1	SLAVE_PORT	1	SLAVE_UUID
 drop table t1;
 stop slave;
 create table t2(id int auto_increment primary key, created datetime);

=== added file 'mysql-test/suite/rpl/r/rpl_server_uuid.result'
--- a/mysql-test/suite/rpl/r/rpl_server_uuid.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_server_uuid.result	2010-06-22 09:34:59 +0000
@@ -0,0 +1,84 @@
+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;
+CALL mtr.add_suppression(".*master and slave have equal MySQL server UUIDs.*");
+CALL mtr.add_suppression("Master's UUID has changed, its old UUID is.*");
+
+# Case 1:
+# Master's UUID appears in the result of 'SHOW SLAVE STATUS'.
+# Slave's UUID appears in the resule of 'SHOW SLAVE HOSTS'.
+-----------------------------------------------------------------------------
+SHOW SLAVE HOSTS;
+Server_id	Host	Port	Master_id	Slave_UUID
+2	127.0.0.1	SLAVE_PORT	1	SLAVE_UUID
+
+# Case 2: 
+# After executing 'STOP SLAVE [IO_THREAD|SQL_THREAD]' successfully, Master's UUID
+# is still kept into Slave status.
+-----------------------------------------------------------------------------
+STOP SLAVE IO_THREAD;
+STOP SLAVE SQL_THREAD;
+include/start_slave.inc
+include/stop_slave.inc
+
+# Case 3:
+# Slave generates an errror and aborts, if master's UUID is
+# equal to slave's UUID unless --replicate-same-server-id
+# option is set.
+-----------------------------------------------------------------------------
+START SLAVE IO_THREAD;
+
+# slave2 is running with --replicate-same-server-id option 
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
+MASTER_PORT= MASTER_PORT,
+MASTER_USER= 'root',
+MASTER_LOG_FILE='master-bin.000001';
+include/start_slave.inc
+include/stop_slave.inc
+
+# Case 4:
+# When executing 'CHANGE MASTER ...', master's UUID and server_id will be
+# cleared if master_host or/and master_port are changed.
+# Master's UUID and server_id will not be cleared if both master_port
+# and master_host are not changed.
+-----------------------------------------------------------------------------
+START SLAVE IO_THREAD;
+include/stop_slave.inc
+
+# Only change MASTER_PORT
+CHANGE MASTER TO MASTER_PORT= 1111;
+CHANGE MASTER TO MASTER_PORT= MASTER_PORT,
+MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
+START SLAVE IO_THREAD;
+
+# Only change MASTER_HOST
+STOP SLAVE IO_THREAD;
+CHANGE MASTER TO MASTER_HOST= 'localhost';
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
+MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
+START SLAVE IO_THREAD;
+
+# Both MASTER_HOST and MASTER_PORT are changed
+STOP SLAVE IO_THREAD;
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= 1111;
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= MASTER_PORT,
+MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
+START SLAVE IO_THREAD;
+
+# Both MASTER_HOST and MASTER_PORT are NOT changed
+STOP SLAVE IO_THREAD;
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= MASTER_PORT;
+CHANGE MASTER TO 
+MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
+
+# Case 5:
+# After executing 'RESET SLAVE' successfully, Master's UUID is still kept 
+# into Slave status.
+-----------------------------------------------------------------------------
+RESET SLAVE;
+CHANGE MASTER TO 
+MASTER_LOG_FILE= 'MASTER_LOG_FILE', MASTER_LOG_POS= MASTER_POS;
+include/start_slave.inc

=== modified file 'mysql-test/suite/rpl/r/rpl_show_slave_hosts.result'
--- a/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result	2009-10-23 02:19:50 +0000
+++ b/mysql-test/suite/rpl/r/rpl_show_slave_hosts.result	2010-06-22 01:41:53 +0000
@@ -8,10 +8,10 @@ RESET SLAVE;
 CHANGE MASTER TO master_host='127.0.0.1',master_port=MASTER_PORT,master_user='root';
 START SLAVE IO_THREAD;
 SHOW SLAVE HOSTS;
-Server_id	Host	Port	Master_id
-3	slave2	DEFAULT_PORT	1
-2		SLAVE_PORT	1
+Server_id	Host	Port	Master_id	Slave_UUID
+3	slave2	DEFAULT_PORT	1	SLAVE_UUID
+2		SLAVE_PORT	1	SLAVE_UUID
 STOP SLAVE IO_THREAD;
 SHOW SLAVE HOSTS;
-Server_id	Host	Port	Master_id
-2		SLAVE_PORT	1
+Server_id	Host	Port	Master_id	Slave_UUID
+2		SLAVE_PORT	1	SLAVE_UUID

=== modified file 'mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test'
--- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test	2010-05-26 14:34:25 +0000
+++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test	2010-06-22 09:34:59 +0000
@@ -46,9 +46,16 @@ let $dbug_sync_point= 'debug_lock.before
 let $debug_sync_action= 'now SIGNAL signal.get_server_id';
 source extra/rpl_tests/rpl_get_master_version_and_clock.test;
 
+#Test case 3: Try to get the value of the MASTER_UUID from master under network disconnection
+connection slave;
+
+let $dbug_sync_point= 'dbug.before_get_MASTER_UUID';
+let $debug_sync_action= 'now SIGNAL signal.get_master_uuid';
+source extra/rpl_tests/rpl_get_master_version_and_clock.test;
+
 eval set global debug= '$debug_saved';
 
-#Test case 3: This test checks that the slave I/O thread refuses to start
+#Test case 4: This test checks that the slave I/O thread refuses to start
 #if slave and master have the same server id.
 connection slave;
 reset master;

=== modified file 'mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test'
--- a/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test	2009-11-27 23:34:47 +0000
+++ b/mysql-test/suite/rpl/t/rpl_mixed_ddl_dml.test	2010-06-22 01:41:53 +0000
@@ -13,8 +13,7 @@ insert into t1 values (NULL),(NULL),(NUL
 sync_slave_with_master;
 select * from t1;
 connection master;
---replace_result $SLAVE_MYPORT 9999
-show slave hosts;
+--source include/show_slave_hosts.inc
 drop table t1;
 sync_slave_with_master;
 stop slave;

=== added file 'mysql-test/suite/rpl/t/rpl_server_uuid.cnf'
--- a/mysql-test/suite/rpl/t/rpl_server_uuid.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_server_uuid.cnf	2010-06-22 01:41:53 +0000
@@ -0,0 +1,8 @@
+!include ../my.cnf
+
+[mysqld.3]
+replicate-same-server-id=1
+
+[ENV]
+SLAVE_MYPORT1=		@mysqld.3.port
+SLAVE_MYSOCK1=		@mysqld.3.socket

=== added file 'mysql-test/suite/rpl/t/rpl_server_uuid.test'
--- a/mysql-test/suite/rpl/t/rpl_server_uuid.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_server_uuid.test	2010-06-22 09:34:59 +0000
@@ -0,0 +1,229 @@
+##############################################################################
+# WL#4677 Unique Server Ids for Replication Topology (UUIDs)                 #
+#
+# Master and slave exchange their UUID each other when connecting. Master's
+# UUID is set into the result of 'SHOW SLAVE STATUS' and stored into
+# master.info file. Slave's UUID appears in the result of 'SHOW SLAVE HOSTS'.
+# Slave and master cannot have the same UUID, except
+# --replicate-same-server-id is set.
+#
+##############################################################################
+--source include/master-slave.inc
+--source include/not_embedded.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+
+CALL mtr.add_suppression(".*master and slave have equal MySQL server UUIDs.*");
+CALL mtr.add_suppression("Master's UUID has changed, its old UUID is.*");
+
+--let $uuid_file= auto.cnf
+
+--let $master_datadir=`SELECT @@DATADIR`
+# Sync suppressions
+sync_slave_with_master;
+--let $slave_datadir=`SELECT @@DATADIR`
+
+connect (slave2,127.0.0.1,root,,test,$SLAVE_MYPORT1,);
+connection slave2;
+--let $slave2_datadir=`SELECT @@DATADIR`
+
+connection master;
+--let $original_master_uuid=query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+--copy_file $master_datadir/$uuid_file $master_datadir/original_$uuid_file
+
+--echo
+--echo # Case 1:
+--echo # Master's UUID appears in the result of 'SHOW SLAVE STATUS'.
+--echo # Slave's UUID appears in the resule of 'SHOW SLAVE HOSTS'.
+--echo -----------------------------------------------------------------------------
+connection master;
+--let $master_uuid_on_master= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+--let $slave_uuid_on_master= query_get_value(SHOW SLAVE HOSTS, Slave_UUID, 1)
+
+--source include/show_slave_hosts.inc
+
+connection slave;
+--let $slave_uuid_on_slave= query_get_value(SHOW VARIABLES LIKE 'SERVER_UUID', Value, 1)
+
+--let $slave_param= Master_UUID
+--let $slave_param_value= $master_uuid_on_master
+source include/check_slave_param.inc;
+
+if (`SELECT '$slave_uuid_on_slave' <> '$slave_uuid_on_master'`)
+{
+  --echo slave_uuid_on_slave <> slave_uuid_on_master
+  --echo $slave_uuid_on_slave <> $slave_uuid_on_master
+}
+
+--echo 
+--echo # Case 2: 
+--echo # After executing 'STOP SLAVE [IO_THREAD|SQL_THREAD]' successfully, Master's UUID
+--echo # is still kept into Slave status.
+--echo -----------------------------------------------------------------------------
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+source include/check_slave_param.inc;
+
+STOP SLAVE SQL_THREAD;
+--source include/wait_for_slave_sql_to_stop.inc
+--source include/check_slave_param.inc
+
+--source include/start_slave.inc
+--source include/stop_slave.inc
+source include/check_slave_param.inc;
+
+--echo
+--echo # Case 3:
+--echo # Slave generates an errror and aborts, if master's UUID is
+--echo # equal to slave's UUID unless --replicate-same-server-id
+--echo # option is set.
+--echo -----------------------------------------------------------------------------
+connection master;
+# copy slave's server_properties file to master, so master will have a same
+# UUID as slave.
+--remove_file $master_datadir/$uuid_file
+--copy_file $slave_datadir/$uuid_file $master_datadir/$uuid_file
+--source include/restart_mysqld.inc
+
+connection slave;
+START SLAVE IO_THREAD;
+
+let $show_statement= SHOW SLAVE STATUS;
+--let $slave_io_errno= 1593
+--source include/wait_for_slave_io_error.inc
+
+connection master;
+--remove_file $master_datadir/$uuid_file
+--copy_file $slave2_datadir/$uuid_file $master_datadir/$uuid_file
+--source include/restart_mysqld.inc
+--let $master_log_file= query_get_value(SHOW MASTER STATUS, 'File', 1)
+--let $master_log_pos= query_get_value(SHOW MASTER STATUS, 'Position', 1)
+
+--echo 
+--echo # slave2 is running with --replicate-same-server-id option 
+connection slave2;
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
+     MASTER_PORT= $MASTER_MYPORT,
+     MASTER_USER= 'root',
+     MASTER_LOG_FILE='master-bin.000001';
+--source include/start_slave.inc
+--source include/check_slave_no_error.inc
+
+connection master;
+sync_slave_with_master slave2;
+--source include/stop_slave.inc
+
+connection master;
+--remove_file $master_datadir/$uuid_file
+--move_file $master_datadir/original_$uuid_file $master_datadir/$uuid_file
+--source include/restart_mysqld.inc
+
+--echo
+--echo # Case 4:
+--echo # When executing 'CHANGE MASTER ...', master's UUID and server_id will be
+--echo # cleared if master_host or/and master_port are changed.
+--echo # Master's UUID and server_id will not be cleared if both master_port
+--echo # and master_host are not changed.
+--echo -----------------------------------------------------------------------------
+connection slave;
+START SLAVE IO_THREAD;
+--let $slave_param= Master_UUID
+--let $slave_param_value= $original_master_uuid
+--source include/wait_for_slave_param.inc
+
+--source include/stop_slave.inc
+
+--echo
+--echo # Only change MASTER_PORT
+let $old_master_log_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1);
+let $old_master_log_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1);
+
+CHANGE MASTER TO MASTER_PORT= 1111;
+--let $slave_param= Master_UUID
+--let $slave_param_value= 
+--source include/check_slave_param.inc
+--let $slave_param= Master_Server_Id
+--let $slave_param_value= 0
+--source include/check_slave_param.inc
+
+--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
+eval CHANGE MASTER TO MASTER_PORT= $MASTER_MYPORT,
+       MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
+START SLAVE IO_THREAD;
+--let $slave_param= Master_UUID
+--let $slave_param_value= $original_master_uuid
+--source include/wait_for_slave_param.inc
+
+--echo
+--echo # Only change MASTER_HOST
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+let $old_master_log_file= query_get_value(SHOW SLAVE STATUS, Master_Log_File, 1);
+let $old_master_log_pos= query_get_value(SHOW SLAVE STATUS, Read_Master_Log_Pos, 1);
+
+CHANGE MASTER TO MASTER_HOST= 'localhost';
+--let $slave_param= Master_UUID
+--let $slave_param_value=
+--source include/check_slave_param.inc
+--let $slave_param= Master_Server_Id
+--let $slave_param_value= 0
+--source include/check_slave_param.inc
+
+--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
+eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1',
+       MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
+START SLAVE IO_THREAD;
+--let $slave_param= Master_UUID
+--let $slave_param_value= $original_master_uuid
+--source include/wait_for_slave_param.inc
+
+--echo
+--echo # Both MASTER_HOST and MASTER_PORT are changed
+STOP SLAVE IO_THREAD;
+
+--source include/wait_for_slave_io_to_stop.inc
+CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= 1111;
+--let $slave_param= Master_UUID
+--let $slave_param_value=
+--source include/check_slave_param.inc
+--let $slave_param= Master_Server_Id
+--let $slave_param_value= 0
+--source include/check_slave_param.inc
+
+--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
+eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= $MASTER_MYPORT,
+       MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
+START SLAVE IO_THREAD;
+--let $slave_param= Master_UUID
+--let $slave_param_value= $original_master_uuid
+--source include/wait_for_slave_param.inc
+
+--echo
+--echo # Both MASTER_HOST and MASTER_PORT are NOT changed
+STOP SLAVE IO_THREAD;
+--source include/wait_for_slave_io_to_stop.inc
+
+--replace_result $MASTER_MYPORT MASTER_PORT
+eval CHANGE MASTER TO MASTER_HOST= '127.0.0.1', MASTER_PORT= $MASTER_MYPORT;
+--source include/check_slave_param.inc
+
+--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
+eval CHANGE MASTER TO 
+       MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
+--source include/check_slave_param.inc
+
+--echo
+--echo # Case 5:
+--echo # After executing 'RESET SLAVE' successfully, Master's UUID is still kept 
+--echo # into Slave status.
+--echo -----------------------------------------------------------------------------
+connection slave;
+RESET SLAVE;
+--source include/check_slave_param.inc
+
+--replace_result $old_master_log_file MASTER_LOG_FILE $MASTER_MYPORT MASTER_PORT $old_master_log_pos MASTER_POS
+eval CHANGE MASTER TO 
+       MASTER_LOG_FILE= '$old_master_log_file', MASTER_LOG_POS= $old_master_log_pos;
+--source include/start_slave.inc
+--source include/master-slave-end.inc

=== modified file 'mysql-test/suite/rpl/t/rpl_show_slave_hosts.test'
--- a/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test	2009-10-23 02:19:50 +0000
+++ b/mysql-test/suite/rpl/t/rpl_show_slave_hosts.test	2010-06-22 01:41:53 +0000
@@ -25,8 +25,7 @@ let $field= Server_id;
 # 3 is server_id of slave2.
 let $connection= ='3';
 source include/wait_show_condition.inc;
---replace_result $SLAVE_MYPORT SLAVE_PORT $DEFAULT_MASTER_PORT DEFAULT_PORT
-SHOW SLAVE HOSTS;
+source include/show_slave_hosts.inc;
 
 connection slave2;
 STOP SLAVE IO_THREAD;
@@ -41,7 +40,6 @@ let $condition= <> '3';
 # knew the leave of slave2 and has unregistered it.
 let $wait_for_all= 1;
 source include/wait_show_condition.inc;
---replace_result $SLAVE_MYPORT SLAVE_PORT
-SHOW SLAVE HOSTS;
+source include/show_slave_hosts.inc;
 
 source include/master-slave-end.inc;

=== added file 'mysql-test/suite/sys_vars/r/server_uuid_basic.result'
--- a/mysql-test/suite/sys_vars/r/server_uuid_basic.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/r/server_uuid_basic.result	2010-06-22 09:34:59 +0000
@@ -0,0 +1,53 @@
+'#---------------------BS_STVARS_004_01----------------------#'
+SELECT COUNT(@@GLOBAL.server_uuid);
+COUNT(@@GLOBAL.server_uuid)
+1
+1 Expected
+'#---------------------BS_STVARS_004_02----------------------#'
+SET @@GLOBAL.server_uuid=1;
+ERROR HY000: Variable 'server_uuid' is a read only variable
+Expected error 'Read only variable'
+SELECT COUNT(@@GLOBAL.server_uuid);
+COUNT(@@GLOBAL.server_uuid)
+1
+1 Expected
+'#---------------------BS_STVARS_004_03----------------------#'
+SELECT @@GLOBAL.server_uuid = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='server_uuid';
+@@GLOBAL.server_uuid = VARIABLE_VALUE
+1
+1 Expected
+SELECT COUNT(@@GLOBAL.server_uuid);
+COUNT(@@GLOBAL.server_uuid)
+1
+1 Expected
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+WHERE VARIABLE_NAME='server_uuid';
+COUNT(VARIABLE_VALUE)
+1
+1 Expected
+'#---------------------BS_STVARS_004_04----------------------#'
+SELECT @@server_uuid = @@GLOBAL.datadir;
+@@server_uuid = @@GLOBAL.datadir
+0
+1 Expected
+'#---------------------BS_STVARS_004_05----------------------#'
+SELECT COUNT(@@server_uuid);
+COUNT(@@server_uuid)
+1
+1 Expected
+SELECT COUNT(@@local.server_uuid);
+ERROR HY000: Variable 'server_uuid' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@SESSION.server_uuid);
+ERROR HY000: Variable 'server_uuid' is a GLOBAL variable
+Expected error 'Variable is a GLOBAL variable'
+SELECT COUNT(@@GLOBAL.server_uuid);
+COUNT(@@GLOBAL.server_uuid)
+1
+1 Expected
+SELECT server_uuid = @@SESSION.datadir;
+ERROR 42S22: Unknown column 'server_uuid' in 'field list'
+Expected error 'Readonly variable'

=== added file 'mysql-test/suite/sys_vars/t/server_uuid_basic.test'
--- a/mysql-test/suite/sys_vars/t/server_uuid_basic.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/sys_vars/t/server_uuid_basic.test	2010-06-22 09:34:59 +0000
@@ -0,0 +1,95 @@
+
+
+################## mysql-test\t\server_uuid_basic.test ########################
+#                                                                             #
+# Variable Name: server_uuid                                                  #
+# Scope: Global                                                               #
+# Access Type: Static                                                         #
+# Data Type: filename                                                         #
+#                                                                             #
+#                                                                             #
+# Creation Date: 2010-06-22                                                   #
+# Author : Libing Song                                                        #
+#                                                                             #
+#                                                                             #
+#
+# Description:Test Cases of Static  System Variable server_uuid               #
+#             that checks the behavior of this variable in the following ways #
+#              * Value Check                                                  #
+#              * Scope Check                                                  #
+#                                                                             #
+# Reference: http://dev.mysql.com/doc/refman/6.0/en/                          #
+#  server-system-variables.html                                               #
+#                                                                             #
+###############################################################################
+
+--echo '#---------------------BS_STVARS_004_01----------------------#'
+####################################################################
+#   Displaying default value                                       #
+####################################################################
+SELECT COUNT(@@GLOBAL.server_uuid);
+--echo 1 Expected
+
+
+--echo '#---------------------BS_STVARS_004_02----------------------#'
+####################################################################
+#   Check if Value can set                                         #
+####################################################################
+
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SET @@GLOBAL.server_uuid=1;
+--echo Expected error 'Read only variable'
+
+SELECT COUNT(@@GLOBAL.server_uuid);
+--echo 1 Expected
+
+
+
+
+--echo '#---------------------BS_STVARS_004_03----------------------#'
+#################################################################
+# Check if the value in GLOBAL Table matches value in variable  #
+#################################################################
+
+SELECT @@GLOBAL.server_uuid = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='server_uuid';
+--echo 1 Expected
+
+SELECT COUNT(@@GLOBAL.server_uuid);
+--echo 1 Expected
+
+SELECT COUNT(VARIABLE_VALUE)
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES 
+WHERE VARIABLE_NAME='server_uuid';
+--echo 1 Expected
+
+
+
+--echo '#---------------------BS_STVARS_004_04----------------------#'
+################################################################################
+#  Check if accessing variable with and without GLOBAL point to same variable  #
+################################################################################
+SELECT @@server_uuid = @@GLOBAL.datadir;
+--echo 1 Expected
+
+
+
+--echo '#---------------------BS_STVARS_004_05----------------------#'
+################################################################################
+#   Check if server_uuid can be accessed with and without @@ sign              #
+################################################################################
+
+SELECT COUNT(@@server_uuid);
+--echo 1 Expected
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@local.server_uuid);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT COUNT(@@SESSION.server_uuid);
+--echo Expected error 'Variable is a GLOBAL variable'
+
+SELECT COUNT(@@GLOBAL.server_uuid);
+--echo 1 Expected

=== added file 'mysql-test/t/server_uuid.test'
--- a/mysql-test/t/server_uuid.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/t/server_uuid.test	2010-06-22 09:34:59 +0000
@@ -0,0 +1,74 @@
+##############################################################################
+# WL#4677 Unique Server Ids for Replication Topology (UUIDs)                 #
+# 
+# Each server has a UUID generated by server itself. It is stored in auto.cnf
+# in @@DATADIR directory. 
+#
+# @@SERVER_UUID is a readonly system variable, it is initialized as the
+# server's UUID when starting. Users can get the server's UUID from
+# @@SERVER_UUID.
+#
+# This test case tests whether the server's UUID can be generated, stored,
+# initialized correctly.
+##############################################################################
+source include/not_embedded.inc;
+
+CALL mtr.add_suppression("Master's UUID has changed, its old UUID is");
+
+--let $uuid_file= auto.cnf
+--let $original_server_uuid= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+
+--let $datadir= query_get_value(SELECT @@DATADIR, @@DATADIR, 1)
+--copy_file $datadir/$uuid_file $datadir/original_$uuid_file
+
+--echo
+--echo # Case 1:
+--echo # @@SERVER_UUID is readonly.
+--echo -----------------------------------------------------------------------------
+--error 1238
+SET GLOBAL SERVER_UUID= UUID();
+
+--echo
+--echo # Case 2:
+--echo # If the file does not exists, mysqld generates it automatically.
+--echo -----------------------------------------------------------------------------
+--remove_file $datadir/$uuid_file
+--source include/restart_mysqld.inc
+--let $server_uuid= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+if (`SELECT '$server_uuid' = '' OR '$server_uuid' = 'NULL'`)
+{
+  --echo server's UUID is null
+}
+
+--echo
+--echo # Case 3:
+--echo # If there is no UUID in the file, mysqld generates it automatically.
+--echo -----------------------------------------------------------------------------
+
+--remove_file $datadir/$uuid_file
+# There is a blank line in the file
+--write_file $datadir/$uuid_file
+[auto]
+EOF
+--source include/restart_mysqld.inc
+
+--let $server_uuid= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+if (`SELECT '$server_uuid' = '' OR '$server_uuid' = 'NULL'`)
+{
+  --echo server's UUID is null
+}
+
+--echo
+--echo # Case 4:
+--echo # If there is a UUID in the file, it will be loaded into SERVER_UUID.
+--echo -----------------------------------------------------------------------------
+
+--remove_file $datadir/$uuid_file
+--move_file $datadir/original_$uuid_file $datadir/$uuid_file
+--source include/restart_mysqld.inc
+
+--let $server_uuid= query_get_value(SELECT @@SERVER_UUID, @@SERVER_UUID, 1)
+if (`SELECT '$server_uuid' <> '$original_server_uuid'`)
+{
+  --echo $server_uuid<> $original_server_uuid
+}

=== modified file 'mysys/default.c'
--- a/mysys/default.c	2010-03-20 09:35:40 +0000
+++ b/mysys/default.c	2010-06-22 09:34:59 +0000
@@ -458,11 +458,12 @@ int my_load_defaults(const char *conf_fi
   MEM_ROOT alloc;
   char *ptr,**res;
   struct handle_option_ctx ctx;
-  const char **dirs;
+  const char **dirs= NULL;
   DBUG_ENTER("load_defaults");
 
   init_alloc_root(&alloc,512,0);
-  if ((dirs= init_default_directories(&alloc)) == NULL)
+  if (default_directories != NULL &&
+      (dirs= init_default_directories(&alloc)) == NULL)
     goto err;
   /*
     Check if the user doesn't want any default option processing

=== modified file 'sql/item_strfunc.h'
--- a/sql/item_strfunc.h	2010-06-21 08:39:53 +0000
+++ b/sql/item_strfunc.h	2010-06-22 09:34:59 +0000
@@ -897,7 +897,6 @@ public:
   String *val_str(String *) ZLIB_DEPENDED_FUNCTION
 };
 
-#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
 class Item_func_uuid: public Item_str_func
 {
 public:

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-06-19 07:50:33 +0000
+++ b/sql/mysqld.cc	2010-06-22 09:34:59 +0000
@@ -579,6 +579,8 @@ const double log_10[] = {
 
 time_t server_start_time, flush_status_time;
 
+char server_uuid[UUID_LENGTH+1];
+const char *server_uuid_ptr;
 char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
 char default_logfile_name[FN_REFLEN];
 char *default_tz_name;
@@ -3978,6 +3980,161 @@ static void end_ssl()
 #endif /* HAVE_OPENSSL */
 }
 
+/**
+  Generate a UUID and save it into server_uuid variable.
+
+  @return Retur 0 or 1 if an error occurred.
+ */
+static int generate_server_uuid()
+{
+  THD *thd;
+  Item_func_uuid *func_uuid;
+  String uuid;
+
+  /*
+    To be able to run this from boot, we allocate a temporary THD
+   */
+  if (!(thd=new THD))
+  {
+    sql_print_error("Failed to generate a server UUID because it is failed"
+                    " to allocate the THD.");
+    return 1;
+  }
+  thd->thread_stack= (char*) &thd;
+  thd->store_globals();
+  lex_start(thd);
+  func_uuid= new (thd->mem_root) Item_func_uuid();
+  func_uuid->fixed= 1;
+  func_uuid->val_str(&uuid);
+  delete thd;
+  /* Remember that we don't have a THD */
+  my_pthread_setspecific_ptr(THR_THD,  0);
+
+  strncpy(server_uuid, uuid.c_ptr(), UUID_LENGTH);
+  server_uuid[UUID_LENGTH]= '\0';
+  return 0;
+}
+
+/**
+  Save all options which was auto-generated by server-self into the given file.
+
+  @param fname The name of the file in which the auto-generated options will b
+  e saved.
+
+  @return Return 0 or 1 if an error occurred.
+ */
+int flush_auto_options(const char* fname)
+{
+  File fd;
+  IO_CACHE io_cache;
+  int result= 0;
+
+  if ((fd= my_open((const char *)fname, O_CREAT|O_RDWR, MYF(MY_WME))) < 0)
+  {
+    sql_print_error("Failed to create file(file: '%s', errno %d)", fname, my_errno);
+    return 1;
+  }
+
+  if (init_io_cache(&io_cache, fd, IO_SIZE*2, WRITE_CACHE, 0L, 0, MYF(MY_WME)))
+  {
+    sql_print_error("Failed to create a cache on (file: %s', errno %d)", fname, my_errno);
+    my_close(fd, MYF(MY_WME));
+    return 1;
+  }
+
+  my_b_seek(&io_cache, 0L);
+  my_b_printf(&io_cache, "%s\n", "[auto]");
+  my_b_printf(&io_cache, "server-uuid=%s\n", server_uuid);
+
+  if (flush_io_cache(&io_cache) || my_sync(fd, MYF(MY_WME)))
+    result= 1;
+
+  my_close(fd, MYF(MY_WME));
+  end_io_cache(&io_cache);
+  return result;
+}
+
+/**
+  File 'auto.cnf' resides in the data directory to hold values of options that
+  server evaluates itself and that needs to be durable to sustain the server
+  restart. There is only a section ['auto'] in the file. All these options are
+  in the section. Only one option exists now, it is server_uuid.
+  Note, the user may not supply any literal value to these auto-options, and
+  only allowed to trigger (re)evaluation.
+  For instance, 'server_uuid' value will be evaluated and stored if there is
+  no corresponding line in the file.
+  Because of the specifics of the auto-options, they need a seperate storage.
+  Meanwhile, it is the 'auto.cnf' that has the same structure as 'my.cnf'.
+
+  @todo consider to implement sql-query-able persistent storage by WL#5279.
+  @return Return 0 or 1 if an error occurred.
+ */
+static int init_server_auto_options()
+{
+  bool flush= false;
+  char fname[FN_REFLEN];
+  char *name= "auto";
+  const char *groups[]= {"auto", NULL};
+  char *uuid= 0;
+  my_option auto_options[]= {
+    {"server-uuid", 0, "", (uchar**) &uuid, (uchar **) &uuid,
+      0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+    {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+  };
+
+  DBUG_ENTER("init_server_auto_options");
+
+  if (NULL == fn_format(fname, "auto.cnf", mysql_data_home, "",
+                        MY_UNPACK_FILENAME | MY_SAFE_PATH))
+    DBUG_RETURN(1);
+
+  /* load_defaults require argv[0] is not null */
+  char **argv= &name;
+  int argc= 1;
+  /* load all options in 'auto.cnf'. */
+  if (my_load_defaults(fname, groups, &argc, &argv, NULL))
+    DBUG_RETURN(1);
+
+  /*
+    Record the origial pointer allocated by my_load_defaults for free,
+    because argv will be changed by handle_options
+   */
+  char **old_argv= argv;
+  if (handle_options(&argc, &argv, auto_options, mysqld_get_one_option))
+    DBUG_RETURN(1);
+
+  if (uuid)
+  {
+    if (strlen(uuid) != UUID_LENGTH)
+    {
+      sql_print_error("Invalid UUID in the auto.cnf file");
+      goto err;
+    }
+    strcpy(server_uuid, uuid);
+  }
+  else
+  {
+    flush= TRUE;
+    /* server_uuid will be set in the function */
+    if (generate_server_uuid())
+      goto err;
+    sql_print_warning("It might be a maiden lunch of the server, for there is"
+                      " no UUID existing. A new UUID is generated. it is %s",
+                      server_uuid);
+  }
+  /*
+    The uuid has been copied to server_uuid, so the memory allocated by
+    my_load_defaults can be freed now.
+   */
+  free_defaults(old_argv);
+
+  if (flush)
+    DBUG_RETURN(flush_auto_options(fname));
+  DBUG_RETURN(0);
+err:
+  free_defaults(argv);
+  DBUG_RETURN(1);
+}
 
 static int init_server_components()
 {
@@ -4201,6 +4358,15 @@ a file name for --log-bin-index option",
 
   if (opt_help)
     unireg_abort(0);
+  /*
+    Each server should have one UUID. We will create it automatically, if it
+    does not exist.
+   */
+  if (!opt_bootstrap && init_server_auto_options())
+  {
+    sql_print_error("Initializing server's UUID failed");
+    unireg_abort(1);
+  }
 
   /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
   if (!DEFAULT_ERRMSGS[0][0])
@@ -7031,6 +7197,7 @@ static int mysql_init_variables(void)
   opt_debug_sync_timeout= 0;
 #endif /* defined(ENABLED_DEBUG_SYNC) */
   key_map_full.set_all();
+  server_uuid[0]= 0;
 
   /* Character sets */
   system_charset_info= &my_charset_utf8_general_ci;

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2010-05-28 05:49:57 +0000
+++ b/sql/mysqld.h	2010-06-22 09:34:59 +0000
@@ -150,6 +150,10 @@ extern char glob_hostname[FN_REFLEN], my
 extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file;
 extern char default_logfile_name[FN_REFLEN];
 extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
+/*Move UUID_LENGTH from item_strfunc.h*/
+#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
+extern char server_uuid[UUID_LENGTH+1];
+extern const char *server_uuid_ptr;
 extern const double log_10[309];
 extern ulonglong keybuff_size;
 extern ulonglong thd_startup_options;

=== modified file 'sql/repl_failsafe.cc'
--- a/sql/repl_failsafe.cc	2010-04-01 19:34:09 +0000
+++ b/sql/repl_failsafe.cc	2010-06-22 09:34:59 +0000
@@ -710,6 +710,7 @@ bool show_slave_hosts(THD* thd)
   field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG));
   field_list.push_back(new Item_return_int("Master_id", 10,
 					   MYSQL_TYPE_LONG));
+  field_list.push_back(new Item_empty_string("Slave_UUID", UUID_LENGTH));
 
   if (protocol->send_result_set_metadata(&field_list,
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
@@ -730,6 +731,11 @@ bool show_slave_hosts(THD* thd)
     }
     protocol->store((uint32) si->port);
     protocol->store((uint32) si->master_id);
+
+    /* get slave's UUID */
+    String slave_uuid;
+    if (get_slave_uuid(si->thd, &slave_uuid));
+      protocol->store(slave_uuid.c_ptr_safe(), &my_charset_bin);
     if (protocol->write())
     {
       mysql_mutex_unlock(&LOCK_slave_list);

=== modified file 'sql/rpl_mi.cc'
--- a/sql/rpl_mi.cc	2010-06-21 12:32:29 +0000
+++ b/sql/rpl_mi.cc	2010-06-22 09:34:59 +0000
@@ -37,6 +37,7 @@ Master_info::Master_info(bool is_slave_r
   host[0] = 0; user[0] = 0; password[0] = 0;
   ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
   ssl_cipher[0]= 0; ssl_key[0]= 0;
+  master_uuid[0]=0;
 
   my_init_dynamic_array(&ignore_server_ids, sizeof(::server_id), 16, 16);
   bzero((char*) &file, sizeof(file));
@@ -130,8 +131,10 @@ enum {
   LINE_FOR_MASTER_BIND = 17,
   /* 6.0 added value of master_ignore_server_id */
   LINE_FOR_REPLICATE_IGNORE_SERVER_IDS= 18,
+  /* 6.0 added value of master_uuid */
+  LINE_FOR_MASTER_UUID= 19,
   /* Number of lines currently used when saving master info file */
-  LINES_IN_MASTER_INFO= LINE_FOR_REPLICATE_IGNORE_SERVER_IDS
+  LINES_IN_MASTER_INFO= LINE_FOR_MASTER_UUID
 };
 
 int init_master_info(Master_info* mi, const char* master_info_fname,
@@ -343,6 +346,10 @@ file '%s')", mi->info_file_name);
         sql_print_error("Failed to initialize master info ignore_server_ids");
         goto errwithmsg;
       }
+
+      if (lines >= LINE_FOR_MASTER_UUID &&
+          init_strvar_from_file(mi->master_uuid, sizeof(mi->master_uuid), &mi->file, 0))
+        goto errwithmsg;
     }
 
 #ifndef HAVE_OPENSSL
@@ -485,14 +492,14 @@ int flush_master_info(Master_info* mi, 
   my_sprintf(heartbeat_buf, (heartbeat_buf, "%.3f", mi->heartbeat_period));
   my_b_seek(file, 0L);
   my_b_printf(file,
-              "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n",
+              "%u\n%s\n%s\n%s\n%s\n%s\n%d\n%d\n%d\n%s\n%s\n%s\n%s\n%s\n%d\n%s\n%s\n%s\n%s\n",
               LINES_IN_MASTER_INFO,
               mi->master_log_name, llstr(mi->master_log_pos, lbuf),
               mi->host, mi->user,
               mi->password, mi->port, mi->connect_retry,
               (int)(mi->ssl), mi->ssl_ca, mi->ssl_capath, mi->ssl_cert,
               mi->ssl_cipher, mi->ssl_key, mi->ssl_verify_server_cert,
-              heartbeat_buf, "", ignore_server_ids_buf);
+              heartbeat_buf, "", ignore_server_ids_buf, mi->master_uuid);
   my_free(ignore_server_ids_buf, MYF(0));
   err= flush_io_cache(file);
   if (sync_masterinfo_period && !err && 

=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h	2010-05-18 15:35:14 +0000
+++ b/sql/rpl_mi.h	2010-06-22 09:34:59 +0000
@@ -112,6 +112,7 @@ class Master_info : public Slave_reporti
   ulonglong received_heartbeats;  // counter of received heartbeat events
   DYNAMIC_ARRAY ignore_server_ids;
   ulong master_id;
+  char master_uuid[UUID_LENGTH+1];
   char info_file_name[FN_REFLEN + 128];
 };
 void init_master_log_pos(Master_info* mi);

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2010-06-21 12:32:29 +0000
+++ b/sql/slave.cc	2010-06-22 09:34:59 +0000
@@ -156,6 +156,8 @@ static int connect_to_master(THD* thd, M
 static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
                       void* thread_killed_arg);
 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
+static int get_master_uuid(MYSQL *mysql, Master_info *mi);
+int io_thread_init_commands(MYSQL *mysql, Master_info *mi);
 static Log_event* next_event(Relay_log_info* rli);
 static int queue_event(Master_info* mi,const char* buf,ulong event_len);
 static int terminate_slave_thread(THD *thd,
@@ -1180,6 +1182,139 @@ bool is_network_error(uint errorno)
   return FALSE;   
 }
 
+/**
+  An auxiliary function extracts slave UUID.
+
+  @param[in]    thd  THD to access a user variable
+  @param[out]   value String to return UUID value.
+
+  @return       if success value is returned else NULL is returned.
+*/
+String *get_slave_uuid(THD *thd, String *value)
+{
+  uchar name[]= "slave_uuid";
+
+  if (value == NULL)
+    return NULL;
+  user_var_entry *entry=
+    (user_var_entry*) my_hash_search(&thd->user_vars, name, sizeof(name)-1);
+  if (entry && entry->length > 0)
+  {
+    value->copy(entry->value, entry->length, NULL);
+    return value;
+  }
+  else
+    return NULL;
+}
+
+int io_thread_init_commands(MYSQL *mysql, Master_info *mi)
+{
+  char query[256];
+  int ret= 0;
+
+  my_sprintf(query, (query, "SET @slave_uuid= '%s'", server_uuid));
+  if (mysql_real_query(mysql, query, strlen(query))
+      && !check_io_slave_killed(mi->io_thd, mi, NULL))
+    goto err;
+
+  mysql_free_result(mysql_store_result(mysql));
+  return ret;
+
+err:
+  if (mysql_errno(mysql) && is_network_error(mysql_errno(mysql)))
+  {
+    mi->report(WARNING_LEVEL, mysql_errno(mysql),
+               "init-command:'%s' failed with error: %s", mysql_error(mysql));
+    ret= 2;
+  }
+  else
+  {
+    mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
+               query);
+    ret= 1;
+  }
+  mysql_free_result(mysql_store_result(mysql));
+  return ret;
+}
+
+/**
+  Get master's uuid on connecting.
+
+  @param  mysql MYSQL to request uuid from master.
+  @param  mi    Master_info to set master_uuid
+
+  @return 0: Success, 1: Fatal error, 2: Network error.
+*/
+static int get_master_uuid(MYSQL *mysql, Master_info *mi)
+{
+  const char *errmsg;
+  MYSQL_RES *master_res= NULL;
+  MYSQL_ROW master_row= NULL;
+  int ret= 0;
+
+  DBUG_EXECUTE_IF("dbug.before_get_MASTER_UUID",
+                  {
+                    const char act[]= "now wait_for signal.get_master_uuid";
+                    DBUG_ASSERT(opt_debug_sync_timeout > 0);
+                    DBUG_ASSERT(!debug_sync_set_action(current_thd,
+                                                       STRING_WITH_LEN(act)));
+                  };);
+
+  if (!mysql_real_query(mysql,
+                        STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_UUID'")) &&
+      (master_res= mysql_store_result(mysql)) &&
+      (master_row= mysql_fetch_row(master_res)))
+  {
+    if (!strcmp(::server_uuid, master_row[1]) &&
+        !mi->rli.replicate_same_server_id)
+    {
+      errmsg= "The slave I/O thread stops because master and slave have equal "
+              "MySQL server UUIDs; these UUIDs must be different for "
+              "replication to work.";
+      mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
+                 errmsg);
+      // Fatal error
+      ret= 1;
+    }
+    else
+    {
+      if (mi->master_uuid[0] != 0 && strcmp(mi->master_uuid, master_row[1]))
+        sql_print_warning("Master's UUID has changed, its old UUID is %s, "
+                          "the new one is %s", mi->master_uuid, master_row[1]);
+      strncpy(mi->master_uuid, master_row[1], UUID_LENGTH);
+      mi->master_uuid[UUID_LENGTH]= 0;
+    }
+  }
+  else if (mysql_errno(mysql))
+  {
+    if (is_network_error(mysql_errno(mysql)))
+    {
+      mi->report(WARNING_LEVEL, mysql_errno(mysql),
+                 "Get master SERVER_UUID failed with error: %s",
+                 mysql_error(mysql));
+      ret= 2;
+    }
+    else
+    {
+      /* Fatal error */
+      errmsg= "The slave I/O thread stops because a fatal error is encountered "
+        "when it try to get the value of SERVER_UUID variable from master.";
+      mi->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
+                 errmsg);
+      ret= 1;
+    }
+  }
+  else if (!master_row && master_res)
+  {
+    mi->report(WARNING_LEVEL, ER_UNKNOWN_SYSTEM_VARIABLE,
+               "Unknown system variable 'SERVER_UUID' on master, "
+               "maybe it is a *VERY OLD MASTER*.");
+  }
+
+  if (master_res)
+    mysql_free_result(master_res);
+  return ret;
+}
 
 /*
   Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
@@ -1806,6 +1941,7 @@ bool show_master_info(THD* thd, Master_i
                                              FN_REFLEN));
   field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
                                            MYSQL_TYPE_LONG));
+  field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
   field_list.push_back(new Item_empty_string("Master_Info_File",
                                              sizeof(mi->info_file_name)));
   field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
@@ -1959,6 +2095,7 @@ bool show_master_info(THD* thd, Master_i
     }
     // Master_Server_id
     protocol->store((uint32) mi->master_id);
+    protocol->store(mi->master_uuid, &my_charset_bin);
     // Master_Info_File
     protocol->store(mi->info_file_name, &my_charset_bin);
     // SQL_Delay
@@ -2938,6 +3075,11 @@ connected:
   thd->slave_net = &mysql->net;
   thd_proc_info(thd, "Checking master version");
   ret= get_master_version_and_clock(mysql, mi);
+  if (!ret)
+    ret= get_master_uuid(mysql, mi);
+  if (!ret)
+    io_thread_init_commands(mysql, mi);
+
   if (ret == 1)
     /* Fatal error */
     goto err;

=== modified file 'sql/slave.h'
--- a/sql/slave.h	2010-06-21 12:32:29 +0000
+++ b/sql/slave.h	2010-06-22 09:34:59 +0000
@@ -247,6 +247,7 @@ extern char *master_ssl_cipher, *master_
        
 extern I_List<THD> threads;
 
+extern String *get_slave_uuid(THD *thd, String *value);
 #endif /* HAVE_REPLICATION */
 
 /* masks for start/stop operations on io and sql slave threads */

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-06-19 07:50:33 +0000
+++ b/sql/sql_parse.cc	2010-06-22 09:34:59 +0000
@@ -1284,7 +1284,7 @@ bool dispatch_command(enum enum_server_c
     {
       ulong pos;
       ushort flags;
-      uint32 slave_server_id;
+      String slave_uuid;
 
       status_var_increment(thd->status_var.com_other);
       thd->enable_slow_log= opt_log_slow_admin_statements;
@@ -1294,10 +1294,10 @@ bool dispatch_command(enum enum_server_c
       /* TODO: The following has to be changed to an 8 byte integer */
       pos = uint4korr(packet);
       flags = uint2korr(packet + 4);
-      thd->server_id=0; /* avoid suicide */
-      if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
-	kill_zombie_dump_threads(slave_server_id);
-      thd->server_id = slave_server_id;
+      thd->server_id= uint4korr(packet+6);
+
+      get_slave_uuid(thd, &slave_uuid);
+      kill_zombie_dump_threads(&slave_uuid);
 
       general_log_print(thd, command, "Log: '%s'  Pos: %ld", packet+10,
                       (long) pos);

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2010-06-21 12:32:29 +0000
+++ b/sql/sql_repl.cc	2010-06-22 09:34:59 +0000
@@ -1296,24 +1296,32 @@ err:
 
   SYNOPSIS
     kill_zombie_dump_threads()
-    slave_server_id     the slave's server id
+    slave_uuid      the slave's UUID
 
 */
 
 
-void kill_zombie_dump_threads(uint32 slave_server_id)
+void kill_zombie_dump_threads(String *slave_uuid)
 {
+  if (slave_uuid->length() == 0)
+    return;
+  DBUG_ASSERT(slave_uuid->length() == UUID_LENGTH);
+
   mysql_mutex_lock(&LOCK_thread_count);
   I_List_iterator<THD> it(threads);
   THD *tmp;
 
   while ((tmp=it++))
   {
-    if (tmp->command == COM_BINLOG_DUMP &&
-       tmp->server_id == slave_server_id)
+    if (tmp != current_thd && tmp->command == COM_BINLOG_DUMP)
     {
-      mysql_mutex_lock(&tmp->LOCK_thd_data);    // Lock from delete
-      break;
+      String tmp_uuid;
+      if (get_slave_uuid(tmp, &tmp_uuid) != NULL &&
+          !strncmp(slave_uuid->c_ptr(), tmp_uuid.c_ptr(), UUID_LENGTH))
+      {
+        mysql_mutex_lock(&tmp->LOCK_thd_data);	// Lock from delete
+        break;
+      }
     }
   }
   mysql_mutex_unlock(&LOCK_thread_count);
@@ -1409,6 +1417,13 @@ bool change_master(THD* thd, Master_info
     reset binlog's name to FIRST and position to 4.
   */
 
+  if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
+      (lex_mi->port && lex_mi->port != mi->port))
+  {
+    mi->master_uuid[0]= 0;
+    mi->master_id= 0;
+  }
+
   if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos)
   {
     mi->master_log_name[0] = 0;

=== modified file 'sql/sql_repl.h'
--- a/sql/sql_repl.h	2010-03-31 14:05:33 +0000
+++ b/sql/sql_repl.h	2010-06-22 09:34:59 +0000
@@ -53,7 +53,7 @@ bool log_in_use(const char* log_name);
 void adjust_linfo_offsets(my_off_t purge_offset);
 bool show_binlogs(THD* thd);
 extern int init_master_info(Master_info* mi);
-void kill_zombie_dump_threads(uint32 slave_server_id);
+void kill_zombie_dump_threads(String *slave_uuid);
 int check_binlog_magic(IO_CACHE* log, const char** errmsg);
 
 typedef struct st_load_file_info

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-06-10 10:32:52 +0000
+++ b/sql/sys_vars.cc	2010-06-22 09:34:59 +0000
@@ -585,6 +585,9 @@ static Sys_var_dbug Sys_dbug(
        ON_CHECK(check_has_super));
 #endif
 
+static Sys_var_charptr Sys_server_uuid("server_uuid", "UUID of the server",
+       READ_ONLY GLOBAL_VAR(server_uuid_ptr),
+       NO_CMD_LINE, IN_FS_CHARSET, DEFAULT(server_uuid));
 /**
   @todo
     When updating myisam_delay_key_write, we should do a 'flush tables'


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20100622093459-4pqujvbz5sdx9qv7.bundle
Thread
bzr push into mysql-next-mr-rpl-merge branch (Li-Bing.Song:2997 to 2998) Li-Bing.Song22 Jun