List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:May 8 2008 5:05pm
Subject:bk commit into 6.0 tree (aelkin:1.2646) BUG#34654
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of aelkin.  When aelkin does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-05-08 20:05:25+03:00, aelkin@stripped +5 -0
  Bug #34654 RESET SLAVE and START SLAVE does not clear Last_IO_Errno
  
  There were no resetting of the io thread's error status at reset_slave() and 
  at the beginning of handle_slave_io() that corresponds to start slave.
  
  Fixed with deploying clean-up at necessary places of the code.

  mysql-test/extra/rpl_tests/rpl_reset_slave.test@stripped, 2008-05-08 20:05:23+03:00, aelkin@stripped +55 -0
    adding regression test for bug#34654 that tests clearing the IO error status
    for start slave and reset slave.

  mysql-test/suite/rpl/r/rpl_row_reset_slave.result@stripped, 2008-05-08 20:05:23+03:00, aelkin@stripped +23 -0
    results changed

  mysql-test/suite/rpl/r/rpl_stm_reset_slave.result@stripped, 2008-05-08 20:05:23+03:00, aelkin@stripped +23 -0
    results changed

  sql/slave.cc@stripped, 2008-05-08 20:05:23+03:00, aelkin@stripped +107 -107
    explicitly clearing the last mi's error at
    
    1. entering handle_slave_io
    2. right after successful connecting
    
    An assert added to watch if the error status is cleared at the beginning of the relay log
    read loop.

  sql/sql_repl.cc@stripped, 2008-05-08 20:05:23+03:00, aelkin@stripped +1 -0
    reset slave now resets the io thread error.

diff -Nrup a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test
--- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test	2008-02-05 15:29:36 +02:00
+++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test	2008-05-08 20:05:23 +03:00
@@ -42,3 +42,58 @@ reset slave;
 start slave;
 sync_with_master;
 show status like 'slave_open_temp_tables';
+
+#
+#Bug#34654  	RESET SLAVE does not clear LAST_IO_Err* 
+#
+
+# clearing the status
+stop slave;
+reset slave;
+let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
+echo *** errno must be zero: $last_io_errno ***;
+
+#
+# verifying start slave resets Last_IO_Error and Last_IO_Errno.
+#
+
+change master to master_user='impossible_user_name';
+start slave;
+source include/wait_for_slave_io_to_stop.inc;
+let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
+--disable_query_log
+eval SELECT $last_io_errno > 0 as ONE;
+--enable_query_log
+
+stop slave;
+change master to master_user='root';
+start slave;
+source include/wait_for_slave_to_start.inc;
+let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
+let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+--echo *** last errno must be  zero: $last_io_errno ***
+--echo *** last error must be blank: $last_io_error ***
+
+#
+# verifying reset slave resets Last_{IO,SQL}_Err{or,no}
+#
+
+stop slave;
+change master to master_user='impossible_user_name';
+start slave;
+source include/wait_for_slave_io_to_stop.inc;
+let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
+--disable_query_log
+eval SELECT $last_io_errno > 0 as ONE;
+--enable_query_log
+
+stop slave;
+reset slave;
+let $last_io_errno= query_get_value(SHOW SLAVE STATUS, Last_IO_Errno, 1);
+let $last_io_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1);
+let $last_sql_errno= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1);
+let $last_sql_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1);
+--echo *** io  last errno must be  zero: $last_io_errno  ***
+--echo *** io  last error must be blank: $last_io_error  ***
+--echo *** sql last errno must be  zero: $last_sql_errno ***
+--echo *** sql last error must be blank: $last_sql_error ***
diff -Nrup a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result
--- a/mysql-test/suite/rpl/r/rpl_row_reset_slave.result	2008-02-05 15:29:36 +02:00
+++ b/mysql-test/suite/rpl/r/rpl_row_reset_slave.result	2008-05-08 20:05:23 +03:00
@@ -175,3 +175,26 @@ start slave;
 show status like 'slave_open_temp_tables';
 Variable_name	Value
 Slave_open_temp_tables	0
+stop slave;
+reset slave;
+*** errno must be zero: 0 ***
+change master to master_user='impossible_user_name';
+start slave;
+ONE
+1
+stop slave;
+change master to master_user='root';
+start slave;
+*** last errno must be  zero: 0 ***
+*** last error must be blank:  ***
+stop slave;
+change master to master_user='impossible_user_name';
+start slave;
+ONE
+1
+stop slave;
+reset slave;
+*** io  last errno must be  zero: 0  ***
+*** io  last error must be blank:   ***
+*** sql last errno must be  zero: 0 ***
+*** sql last error must be blank:  ***
diff -Nrup a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result
--- a/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result	2008-02-05 15:29:36 +02:00
+++ b/mysql-test/suite/rpl/r/rpl_stm_reset_slave.result	2008-05-08 20:05:23 +03:00
@@ -175,3 +175,26 @@ start slave;
 show status like 'slave_open_temp_tables';
 Variable_name	Value
 Slave_open_temp_tables	1
+stop slave;
+reset slave;
+*** errno must be zero: 0 ***
+change master to master_user='impossible_user_name';
+start slave;
+ONE
+1
+stop slave;
+change master to master_user='root';
+start slave;
+*** last errno must be  zero: 0 ***
+*** last error must be blank:  ***
+stop slave;
+change master to master_user='impossible_user_name';
+start slave;
+ONE
+1
+stop slave;
+reset slave;
+*** io  last errno must be  zero: 0  ***
+*** io  last error must be blank:   ***
+*** sql last errno must be  zero: 0 ***
+*** sql last error must be blank:  ***
diff -Nrup a/sql/slave.cc b/sql/slave.cc
--- a/sql/slave.cc	2008-04-01 13:56:42 +03:00
+++ b/sql/slave.cc	2008-05-08 20:05:23 +03:00
@@ -2114,6 +2114,7 @@ pthread_handler_t handle_slave_io(void *
 
   pthread_detach_this_thread();
   thd->thread_stack= (char*) &thd; // remember where our stack is
+  mi->clear_error();
   if (init_slave_thread(thd, SLAVE_THD_IO))
   {
     pthread_cond_broadcast(&mi->start_cond);
@@ -2204,129 +2205,127 @@ connected:
   }
 
   DBUG_PRINT("info",("Starting reading binary log from master"));
-  while (!io_slave_killed(thd,mi))
+  thd_proc_info(thd, "Requesting binlog dump");
+  if (!io_slave_killed(thd,mi) && request_dump(mysql, mi, &suppress_warnings))
   {
-    thd_proc_info(thd, "Requesting binlog dump");
-    if (request_dump(mysql, mi, &suppress_warnings))
-    {
-      sql_print_error("Failed on request_dump()");
-      if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
+    sql_print_error("Failed on request_dump()");
+    if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
 requesting master dump") ||
-          try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
-                           reconnect_messages[SLAVE_RECON_ACT_DUMP]))
-        goto err;
-      goto connected;
-    }
-    DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP", 
-      if (!retry_count_dump)
-      {
-        retry_count_dump++;
-        sql_print_information("Forcing to reconnect slave I/O thread");
-        if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
-                             reconnect_messages[SLAVE_RECON_ACT_DUMP]))
-          goto err;
-        goto connected;
-      });
+        try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
+                         reconnect_messages[SLAVE_RECON_ACT_DUMP]))
+      goto err;
+    goto connected;
+  }
+  DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_DUMP", 
+                  if (!io_slave_killed(thd,mi) && !retry_count_dump)
+                  {
+                    retry_count_dump++;
+                    sql_print_information("Forcing to reconnect slave I/O thread");
+                    if (try_to_reconnect(thd, mysql, mi, &retry_count,
+                                         suppress_warnings,
+                                         reconnect_messages[SLAVE_RECON_ACT_DUMP]))
+                      goto err;
+                    goto connected;
+                  });
+  DBUG_ASSERT(mi->last_error().number == 0);
+  while (!io_slave_killed(thd,mi))
+  {
+    ulong event_len;
+    /*
+      We say "waiting" because read_event() will wait if there's nothing to
+      read. But if there's something to read, it will not wait. The
+      important thing is to not confuse users by saying "reading" whereas
+      we're in fact receiving nothing.
+    */
+    thd_proc_info(thd, "Waiting for master to send event");
+    event_len= read_event(mysql, mi, &suppress_warnings);
+    if (check_io_slave_killed(thd, mi,
+                              "Slave I/O thread killed while reading event"))
+      goto err;
+    DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
+                    if (!retry_count_event)
+                    {
+                      retry_count_event++;
+                      sql_print_information("Forcing to reconnect slave I/O thread");
+                      if (try_to_reconnect(thd, mysql, mi, &retry_count,
+                                           suppress_warnings,
+                                           reconnect_messages[SLAVE_RECON_ACT_EVENT]))
+                        goto err;
+                      goto connected;
+                    });
 
-    while (!io_slave_killed(thd,mi))
+    if (event_len == packet_error)
     {
-      ulong event_len;
-      /*
-         We say "waiting" because read_event() will wait if there's nothing to
-         read. But if there's something to read, it will not wait. The
-         important thing is to not confuse users by saying "reading" whereas
-         we're in fact receiving nothing.
-      */
-      thd_proc_info(thd, "Waiting for master to send event");
-      event_len= read_event(mysql, mi, &suppress_warnings);
-      if (check_io_slave_killed(thd, mi, "Slave I/O thread killed while \
-reading event"))
-        goto err;
-      DBUG_EXECUTE_IF("FORCE_SLAVE_TO_RECONNECT_EVENT",
-        if (!retry_count_event)
-        {
-          retry_count_event++;
-          sql_print_information("Forcing to reconnect slave I/O thread");
-          if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
-                               reconnect_messages[SLAVE_RECON_ACT_EVENT]))
-            goto err;
-          goto connected;
-        });
-
-      if (event_len == packet_error)
-      {
-        uint mysql_error_number= mysql_errno(mysql);
-        switch (mysql_error_number) {
-        case CR_NET_PACKET_TOO_LARGE:
-          sql_print_error("\
-Log entry on master is longer than max_allowed_packet (%ld) on \
+      uint mysql_error_number= mysql_errno(mysql);
+      switch (mysql_error_number) {
+      case CR_NET_PACKET_TOO_LARGE:
+        sql_print_error("\
+Log entry on master is longer than max_allowed_packet (%ld) on          \
 slave. If the entry is correct, restart the server with a higher value of \
 max_allowed_packet",
-                          thd->variables.max_allowed_packet);
-          goto err;
-        case ER_MASTER_FATAL_ERROR_READING_BINLOG:
-          sql_print_error(ER(mysql_error_number), mysql_error_number,
-                          mysql_error(mysql));
-          goto err;
-        case EE_OUTOFMEMORY:
-        case ER_OUTOFMEMORY:
-          sql_print_error("\
+                        thd->variables.max_allowed_packet);
+        goto err;
+      case ER_MASTER_FATAL_ERROR_READING_BINLOG:
+        sql_print_error(ER(mysql_error_number), mysql_error_number,
+                        mysql_error(mysql));
+        goto err;
+      case EE_OUTOFMEMORY:
+      case ER_OUTOFMEMORY:
+        sql_print_error("\
 Stopping slave I/O thread due to out-of-memory error from master");
-          goto err;
-        }
-        if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
-                             reconnect_messages[SLAVE_RECON_ACT_EVENT]))
-          goto err;
-        goto connected;
-      } // if (event_len == packet_error)
-
-      retry_count=0;                    // ok event, reset retry counter
-      thd_proc_info(thd, "Queueing master event to the relay log");
-      if (queue_event(mi,(const char*)mysql->net.read_pos + 1, event_len))
-      {
         goto err;
       }
-      if (flush_master_info(mi, 1))
-      {
-        sql_print_error("Failed to flush master info file");
+      if (try_to_reconnect(thd, mysql, mi, &retry_count, suppress_warnings,
+                           reconnect_messages[SLAVE_RECON_ACT_EVENT]))
         goto err;
-      }
-      /*
-        See if the relay logs take too much space.
-        We don't lock mi->rli.log_space_lock here; this dirty read saves time
-        and does not introduce any problem:
-        - if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
-        the clean value is 0), then we are reading only one more event as we
-        should, and we'll block only at the next event. No big deal.
-        - if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
-        the clean value is 1), then we are going into wait_for_relay_log_space()
-        for no reason, but this function will do a clean read, notice the clean
-        value and exit immediately.
-      */
+      goto connected;
+    } // if (event_len == packet_error)
+    
+    retry_count=0;                    // ok event, reset retry counter
+    thd_proc_info(thd, "Queueing master event to the relay log");
+    if (queue_event(mi,(const char*)mysql->net.read_pos + 1, event_len))
+    {
+      goto err;
+    }
+    if (flush_master_info(mi, 1))
+    {
+      sql_print_error("Failed to flush master info file");
+      goto err;
+    }
+    /*
+      See if the relay logs take too much space.
+      We don't lock mi->rli.log_space_lock here; this dirty read saves time
+      and does not introduce any problem:
+      - if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
+      the clean value is 0), then we are reading only one more event as we
+      should, and we'll block only at the next event. No big deal.
+      - if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
+      the clean value is 1), then we are going into wait_for_relay_log_space()
+      for no reason, but this function will do a clean read, notice the clean
+      value and exit immediately.
+    */
 #ifndef DBUG_OFF
-      {
-        char llbuf1[22], llbuf2[22];
-        DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
+    {
+      char llbuf1[22], llbuf2[22];
+      DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
 ignore_log_space_limit=%d",
-                            llstr(rli->log_space_limit,llbuf1),
-                            llstr(rli->log_space_total,llbuf2),
-                            (int) rli->ignore_log_space_limit));
-      }
+                          llstr(rli->log_space_limit,llbuf1),
+                          llstr(rli->log_space_total,llbuf2),
+                          (int) rli->ignore_log_space_limit));
+    }
 #endif
-
-      if (rli->log_space_limit && rli->log_space_limit <
-          rli->log_space_total &&
-          !rli->ignore_log_space_limit)
-        if (wait_for_relay_log_space(rli))
-        {
-          sql_print_error("Slave I/O thread aborted while waiting for relay \
+    
+    if (rli->log_space_limit && rli->log_space_limit <
+        rli->log_space_total &&
+        !rli->ignore_log_space_limit)
+      if (wait_for_relay_log_space(rli))
+      {
+        sql_print_error("Slave I/O thread aborted while waiting for relay \
 log space");
-          goto err;
-        }
-    }
+        goto err;
+      }
   }
 
-  // error = 0;
 err:
   // print the current replication position
   sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
@@ -3411,6 +3410,7 @@ static int connect_to_master(THD* thd, M
 
   if (!slave_was_killed)
   {
+    mi->clear_error();
     if (reconnect)
     {
       if (!suppress_warnings && global_system_variables.log_warnings)
diff -Nrup a/sql/sql_repl.cc b/sql/sql_repl.cc
--- a/sql/sql_repl.cc	2008-03-08 12:14:45 +02:00
+++ b/sql/sql_repl.cc	2008-05-08 20:05:23 +03:00
@@ -1114,6 +1114,7 @@ int reset_slave(THD *thd, Master_info* m
      Reset errors (the idea is that we forget about the
      old master).
   */
+  mi->clear_error();
   mi->rli.clear_error();
   mi->rli.clear_until_condition();
 
Thread
bk commit into 6.0 tree (aelkin:1.2646) BUG#34654Andrei Elkin8 May