List:Commits« Previous MessageNext Message »
From:Magnus Blåudd Date:November 25 2010 10:40am
Subject:bzr commit into mysql-trunk-bugfixing branch (magnus.blaudd:3388) WL#3127
View as plain text  
#At file:///data0/magnus/mysql/trunk-bugfixing-wl3127/ based on revid:magnus.blaudd@strippedw81dur833h06

 3388 Magnus Blåudd	2010-11-25
      WL#3127 slave side TCP address binding
       - Extend CHANGE MASTER with MASTER_BIND='interface'
       - Extend SHOW SLAVE STATUS with a new column Master_Bind
       - Add testcase

    added:
      mysql-test/suite/rpl/t/rpl_change_master_bind.inc
    modified:
      mysql-test/include/check_ipv6.inc
      mysql-test/suite/rpl/r/rpl_change_master.result
      mysql-test/suite/rpl/t/rpl_change_master.test
      sql/lex.h
      sql/rpl_mi.cc
      sql/rpl_mi.h
      sql/rpl_slave.cc
      sql/sql_lex.h
      sql/sql_yacc.yy
=== modified file 'mysql-test/include/check_ipv6.inc'
--- a/mysql-test/include/check_ipv6.inc	2009-11-23 16:38:42 +0000
+++ b/mysql-test/include/check_ipv6.inc	2010-11-25 10:40:05 +0000
@@ -1,10 +1,20 @@
-# Check if ipv6 is available. If not, server is crashing (see BUG#48915).
+# Check if ipv6 is available.
+#
+# Parameters:
+#  $check_ipv6_just_check - don't skip the test if IPv6 is unsupported,
+#                           just set the variable $check_ipv6_supported
+#
 --disable_query_log
 --disable_abort_on_error
+let $check_ipv6_supported=1;
 connect (checkcon123456789,::1,root,,test);
 if($mysql_errno)
 {
-skip wrong IP;
+  let $check_ipv6_supported=0;
+  if(!$check_ipv6_just_check)
+  {
+    skip No IPv6 support;
+  }
 }
 connection default;
 disconnect checkcon123456789;

=== modified file 'mysql-test/suite/rpl/r/rpl_change_master.result'
--- a/mysql-test/suite/rpl/r/rpl_change_master.result	2010-11-18 15:51:24 +0000
+++ b/mysql-test/suite/rpl/r/rpl_change_master.result	2010-11-25 10:40:05 +0000
@@ -71,6 +71,34 @@ ERROR 42000: You have an error in your S
 CHANGE MASTER TO master_retry_count=-1;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-1' at line 1
 include/start_slave.inc
+include/stop_slave.inc
+create table t1(n int, b varchar(256));
+insert into t1 values(1, <master_bind>);
+change master to master_bind=<master_bind>;
+start slave;
+drop table t1;
+include/stop_slave.inc
+create table t1(n int, b varchar(256));
+insert into t1 values(1, <master_bind>);
+change master to master_bind=<master_bind>;
+start slave;
+got expected error 2003
+include/stop_slave.inc
+change master to master_bind='';
+start slave;
+drop table t1;
+include/stop_slave.inc
+create table t1(n int, b varchar(256));
+insert into t1 values(1, <master_bind>);
+change master to master_bind=<master_bind>;
+start slave;
+drop table t1;
+include/stop_slave.inc
+create table t1(n int, b varchar(256));
+insert into t1 values(1, <master_bind>);
+change master to master_bind=<master_bind>;
+start slave;
+drop table t1;
 stop slave;
 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
 reset master;

=== modified file 'mysql-test/suite/rpl/t/rpl_change_master.test'
--- a/mysql-test/suite/rpl/t/rpl_change_master.test	2010-11-25 09:12:05 +0000
+++ b/mysql-test/suite/rpl/t/rpl_change_master.test	2010-11-25 10:40:05 +0000
@@ -254,5 +254,38 @@ if (`SELECT $retry_count6 <> $retry_coun
   -- die
 }
 
+#
+# WL#3127 slave side TCP address binding
+# - CHANGE MASTER ... MASTER_BIND='interface'
+# - SHOW SLAVE STATUS has new column Master_Bind
+#
+
+let $check_ipv6_just_check=1;
+source include/check_ipv6.inc;
+let $check_ipv6_just_check=0;
+
+# Test valid IPv4 address
+let $master_bind='127.0.0.1';
+--source rpl_change_master_bind.inc
+
+# Test invalid IPv4 address
+let $master_bind='1.1.1.1';
+let $master_bind_error_expected=2003;
+--source rpl_change_master_bind.inc
+let $master_bind_error_expected=0;
+
+# Test valid IPv6 address
+let $master_bind='::1';
+if (!$check_ipv6_supported)
+{
+  # No IPv6 support, fallback to IPv4
+  let $master_bind='127.0.0.1';
+}
+--source rpl_change_master_bind.inc
+
+# Test with no bind address(check that reset works)
+let $master_bind='';
+--source rpl_change_master_bind.inc
+
 -- source include/master-slave-reset.inc
 -- source include/master-slave-end.inc

=== added file 'mysql-test/suite/rpl/t/rpl_change_master_bind.inc'
--- a/mysql-test/suite/rpl/t/rpl_change_master_bind.inc	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_change_master_bind.inc	2010-11-25 10:40:05 +0000
@@ -0,0 +1,69 @@
+#
+# Test CHANGE MASTER MASTER_BIND=xxx
+#
+# Parameters:
+#  $master_bind - the address to use for MASTER_BIND
+#  $master_bind_error_expected - expect an error when using the specified
+#                                master_bind address
+#
+#
+
+# Stop the slave
+connection slave;
+source include/stop_slave.inc;
+
+# Create table and insert one record with the bind address on master
+connection master;
+create table t1(n int, b varchar(256));
+--replace_result $master_bind <master_bind>
+eval insert into t1 values(1, $master_bind);
+
+# Configure slave to connect to master with then give bind address
+connection slave;
+--replace_result $master_bind <master_bind>
+eval change master to master_bind=$master_bind;
+start slave;
+
+# Check that SHOW SLAVE STATUS has Master_bind column set to $master_bind
+let $master_bind_value= query_get_value(SHOW SLAVE STATUS, Master_Bind, 1);
+if (`select '$master_bind_value' != $master_bind`)
+{
+  source include/show_rpl_debug_info.inc;
+  echo 'master_bind_value: $master_bind_value' != 'master_bind: $master_bind';
+  die Master_bind in SHOW SLAVE STAUS not showing configured value;
+}
+
+if ($master_bind_error_expected)
+{
+  # The given master bind address is not valid
+  # and replication should fail
+  let $slave_io_errno= $master_bind_error_expected;
+  source include/wait_for_slave_io_error.inc;
+  echo got expected error $master_bind_error_expected;
+  source include/stop_slave.inc;
+
+  # Reset the master_bind to that cleanup can run
+  eval change master to master_bind='';
+  start slave;
+
+}
+
+source include/wait_for_slave_to_start.inc;
+
+connection master;
+sync_slave_with_master;
+
+connection slave;
+let $master_bind_repl= query_get_value(select b from t1, b, 1);
+if (`select '$master_bind_repl' != $master_bind`)
+{
+  select * from t1;
+  source include/show_rpl_debug_info.inc;
+  echo 'master_bind_repl: $master_bind_repl' != 'master_bind: $master_bind';
+  die The replicated value to show replication working was not correct;
+}
+
+# Clean up
+connection master;
+drop table t1;
+sync_slave_with_master;

=== modified file 'sql/lex.h'
--- a/sql/lex.h	2010-10-21 12:18:25 +0000
+++ b/sql/lex.h	2010-11-25 10:40:05 +0000
@@ -316,6 +316,7 @@ static SYMBOL symbols[] = {
   { "LOOP",             SYM(LOOP_SYM)},
   { "LOW_PRIORITY",	SYM(LOW_PRIORITY)},
   { "MASTER",           SYM(MASTER_SYM)},
+  { "MASTER_BIND",      SYM(MASTER_BIND_SYM)},
   { "MASTER_CONNECT_RETRY",           SYM(MASTER_CONNECT_RETRY_SYM)},
   { "MASTER_DELAY",     SYM(MASTER_DELAY_SYM)},
   { "MASTER_HOST",           SYM(MASTER_HOST_SYM)},

=== modified file 'sql/rpl_mi.cc'
--- a/sql/rpl_mi.cc	2010-08-24 08:39:26 +0000
+++ b/sql/rpl_mi.cc	2010-11-25 10:40:05 +0000
@@ -89,7 +89,7 @@ Master_info::Master_info(PSI_mutex_key *
    clock_diff_with_master(0), heartbeat_period(0),
    received_heartbeats(0), master_id(0), retry_count(master_retry_count)
 {
-  host[0] = 0; user[0] = 0; password[0] = 0;
+  host[0] = 0; user[0] = 0; password[0] = 0; bind_addr[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;
@@ -371,13 +371,7 @@ bool Master_info::read_info(Rpl_info_han
   */
   if (lines >= LINE_FOR_MASTER_BIND)
   {
-    /*
-      This is a placeholder for the bind option.
-      Please, update this after WL#3126 and
-      WL#3127.
-    */
-    char fake_bind[2];
-    if (from->get_info(fake_bind, sizeof(fake_bind), ""))
+    if (from->get_info(bind_addr, sizeof(bind_addr), ""))
       DBUG_RETURN(TRUE);
   }
 
@@ -447,12 +441,7 @@ bool Master_info::write_info(Rpl_info_ha
       to->set_info(ssl_key) ||
       to->set_info(ssl_verify_server_cert) ||
       to->set_info(heartbeat_period) ||
-      /*
-        This is a placeholder for the bind option.
-        Please, update this after WL#3126 and
-        WL#3127.
-      */
-      to->set_info("") || 
+      to->set_info(bind_addr) ||
       to->set_info(ignore_server_ids) ||
       to->set_info(master_uuid) ||
       to->set_info(retry_count))

=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h	2010-08-05 17:45:25 +0000
+++ b/sql/rpl_mi.h	2010-11-25 10:40:05 +0000
@@ -72,6 +72,7 @@ class Master_info : public Rpl_info
 
   /* the variables below are needed because we can change masters on the fly */
   char host[HOSTNAME_LENGTH+1];
+  char bind_addr[HOSTNAME_LENGTH+1];
   char user[USERNAME_LENGTH+1];
   char password[MAX_PASSWORD_LENGTH+1];
   my_bool ssl; // enables use of SSL connection if true

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2010-11-18 16:34:56 +0000
+++ b/sql/rpl_slave.cc	2010-11-25 10:40:05 +0000
@@ -1912,6 +1912,8 @@ bool show_master_info(THD* thd, Master_i
   field_list.push_back(new Item_empty_string("Slave_SQL_Running_State", 20));
   field_list.push_back(new Item_return_int("Master_Retry_Count", 10,
                                            MYSQL_TYPE_LONGLONG));
+  field_list.push_back(new Item_empty_string("Master_Bind",
+                                             sizeof(mi->bind_addr)));
 
   if (protocol->send_result_set_metadata(&field_list,
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
@@ -2100,6 +2102,8 @@ bool show_master_info(THD* thd, Master_i
     protocol->store(slave_sql_running_state, &my_charset_bin);
     // Master_Retry_Count
     protocol->store((ulonglong) mi->retry_count);
+    // Master_Bind
+    protocol->store(mi->bind_addr, &my_charset_bin);
 
     mysql_mutex_unlock(&mi->rli->err_lock);
     mysql_mutex_unlock(&mi->err_lock);
@@ -4450,6 +4454,12 @@ static int connect_to_master(THD* thd, M
   mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
   mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
 
+  if (mi->bind_addr[0])
+  {
+    DBUG_PRINT("info",("bind_addr: %s", mi->bind_addr));
+    mysql_options(mysql, MYSQL_OPT_BIND, mi->bind_addr);
+  }
+
 #ifdef HAVE_OPENSSL
   if (mi->ssl)
   {
@@ -4576,6 +4586,12 @@ MYSQL *rpl_connect_master(MYSQL *mysql)
   mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
   mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
 
+  if (mi->bind_addr[0])
+  {
+    DBUG_PRINT("info",("bind_addr: %s", mi->bind_addr));
+    mysql_options(mysql, MYSQL_OPT_BIND, mi->bind_addr);
+  }
+
 #ifdef HAVE_OPENSSL
   if (mi->ssl)
   {
@@ -5509,7 +5525,7 @@ bool change_master(THD* thd, Master_info
   bool need_relay_log_purge= 1;
   char *var_master_log_name= NULL, *var_group_master_log_name= NULL;
   bool ret= FALSE;
-  char saved_host[HOSTNAME_LENGTH + 1];
+  char saved_host[HOSTNAME_LENGTH + 1], saved_bind_addr[HOSTNAME_LENGTH + 1];
   uint saved_port= 0;
   char saved_log_name[FN_REFLEN];
   my_off_t saved_log_pos= 0;
@@ -5558,6 +5574,7 @@ bool change_master(THD* thd, Master_info
     Before processing the command, save the previous state.
   */
   strmake(saved_host, mi->host, HOSTNAME_LENGTH);
+  strmake(saved_bind_addr, mi->bind_addr, HOSTNAME_LENGTH);
   saved_port= mi->port;
   strmake(saved_log_name, mi->get_master_log_name(), FN_REFLEN - 1);
   saved_log_pos= mi->get_master_log_pos();
@@ -5591,6 +5608,8 @@ bool change_master(THD* thd, Master_info
 
   if (lex_mi->host)
     strmake(mi->host, lex_mi->host, sizeof(mi->host)-1);
+  if (lex_mi->bind_addr)
+    strmake(mi->bind_addr, lex_mi->bind_addr, sizeof(mi->bind_addr)-1);
   if (lex_mi->user)
     strmake(mi->user, lex_mi->user, sizeof(mi->user)-1);
   if (lex_mi->password)
@@ -5773,11 +5792,12 @@ bool change_master(THD* thd, Master_info
 
   sql_print_information("'CHANGE MASTER TO executed'. "
     "Previous state master_host='%s', master_port='%u', master_log_file='%s', "
-    "master_log_pos='%ld'. "
+    "master_log_pos='%ld', master_bind='%s'. "
     "New state master_host='%s', master_port='%u', master_log_file='%s', "
-    "master_log_pos='%ld'.", saved_host, saved_port, saved_log_name,
-    (ulong) saved_log_pos, mi->host, mi->port, mi->get_master_log_name(),
-    (ulong) mi->get_master_log_pos());
+    "master_log_pos='%ld', master_bind='%s'.", 
+    saved_host, saved_port, saved_log_name, (ulong) saved_log_pos,
+    saved_bind_addr, mi->host, mi->port, mi->get_master_log_name(),
+    (ulong) mi->get_master_log_pos(), mi->bind_addr);
 
   /*
     If we don't write new coordinates to disk now, then old will remain in

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2010-11-18 16:34:56 +0000
+++ b/sql/sql_lex.h	2010-11-25 10:40:05 +0000
@@ -205,7 +205,7 @@ typedef struct st_lex_server_options
 */
 typedef struct st_lex_master_info
 {
-  char *host, *user, *password, *log_file_name;
+  char *host, *user, *password, *log_file_name, *bind_addr;
   uint port, connect_retry;
   float heartbeat_period;
   int sql_delay;

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-11-18 16:34:56 +0000
+++ b/sql/sql_yacc.yy	2010-11-25 10:40:05 +0000
@@ -1072,6 +1072,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  LOOP_SYM
 %token  LOW_PRIORITY
 %token  LT                            /* OPERATOR */
+%token  MASTER_BIND_SYM
 %token  MASTER_CONNECT_RETRY_SYM
 %token  MASTER_DELAY_SYM
 %token  MASTER_HOST_SYM
@@ -1894,6 +1895,10 @@ master_def:
           {
             Lex->mi.host = $3.str;
           }
+        | MASTER_BIND_SYM EQ TEXT_STRING_sys
+          {
+            Lex->mi.bind_addr = $3.str;
+          }
         | MASTER_USER_SYM EQ TEXT_STRING_sys
           {
             Lex->mi.user = $3.str;

Attachment: [text/bzr-bundle] bzr/magnus.blaudd@oracle.com-20101125104005-s7j05q5k3uws619i.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (magnus.blaudd:3388) WL#3127Magnus Blåudd25 Nov