List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:November 20 2009 1:30pm
Subject:bzr commit into mysql-5.1-rep+2 branch (aelkin:3144) Bug#48463
View as plain text  
#At file:///home/andrei/MySQL/BZR/FIXES/rep2-bug48463-backporting/ based on revid:luis.soares@stripped

 3144 Andrei Elkin	2009-11-20
      Bug #48463 backporting from 6.0-rpl to celosia a set of bugs
      
      The mentioned on the bug report set of bugs fixes have not be pushed to the main trees.
      
      Fixed with extracting commits done to 6.0-rpl tree and applying them to the main 5.1.
      Notes.
      1. part of changes - the mtr's specific - were packported to the main 5.0 tree for mtr v1
         as http://lists.mysql.com/commits/46562
         However, there is no that fix anymore in the mtr v2. (This fact was mailed to mtr maintaining
         people).
      
      2. Bug@36929  crash in kill_zombie_dump_threads-> THD::awake() with replication tests
         is not backported because the base code of the patch is libevent and that was removed
         from the main trees due to its instability.
     @ client/mysqlbinlog.cc
        fixes for BUG#35546
     @ mysql-test/suite/rpl/r/rpl_bug41902.result
        the new tests result file is added.
     @ mysql-test/suite/rpl/t/rpl_bug41902-slave.opt
        conf file for bug41902 testing is added.
     @ mysql-test/suite/rpl/t/rpl_bug41902.test
        regression tests for Bug #41902 is added.
     @ sql/log.cc
        collection of changes due to Bug #48463.
     @ sql/log.h
        collection of changes due to Bug #48463.
     @ sql/rpl_rli.h
        collection of changes due to Bug #48463.
     @ sql/slave.cc
        collection of changes due to Bug #48463.
     @ sql/sql_repl.cc
        collection of changes due to Bug #48463.

    added:
      mysql-test/suite/rpl/r/rpl_bug41902.result
      mysql-test/suite/rpl/t/rpl_bug41902-slave.opt
      mysql-test/suite/rpl/t/rpl_bug41902.test
    modified:
      client/mysqlbinlog.cc
      sql/log.cc
      sql/log.h
      sql/rpl_rli.h
      sql/slave.cc
      sql/sql_repl.cc
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2009-11-06 16:35:04 +0000
+++ b/client/mysqlbinlog.cc	2009-11-20 13:30:35 +0000
@@ -439,6 +439,7 @@ Exit_status Load_log_processor::process_
   {
     error("Could not construct local filename %s%s.",
           target_dir_name,bname);
+    my_free(fname, MYF(0));
     delete ce;
     DBUG_RETURN(ERROR_STOP);
   }
@@ -446,9 +447,15 @@ Exit_status Load_log_processor::process_
   rec.fname= fname;
   rec.event= ce;
 
+  /*
+     fname is freed in process_event()
+     after Execute_load_query_log_event or Execute_load_log_event
+     will have been processed, otherwise in Load_log_processor::destroy()
+  */
   if (set_dynamic(&file_names, (uchar*)&rec, file_id))
   {
     error("Out of memory.");
+    my_free(fname, MYF(0));
     delete ce;
     DBUG_RETURN(ERROR_STOP);
   }
@@ -828,7 +835,17 @@ Exit_status process_event(PRINT_EVENT_IN
       print_event_info->common_header_len=
         glob_description_event->common_header_len;
       ev->print(result_file, print_event_info);
-      ev->temp_buf= 0; // as the event ref is zeroed
+      if (!remote_opt)
+      {
+        ev->free_temp_buf(); // free memory allocated in dump_local_log_entries
+      }
+      else
+      {
+        /*
+          disassociate but not free dump_remote_log_entries time memory
+        */
+        ev->temp_buf= 0;
+      }
       /*
         We don't want this event to be deleted now, so let's hide it (I
         (Guilhem) should later see if this triggers a non-serious Valgrind

=== added file 'mysql-test/suite/rpl/r/rpl_bug41902.result'
--- a/mysql-test/suite/rpl/r/rpl_bug41902.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_bug41902.result	2009-11-20 13:30:35 +0000
@@ -0,0 +1,34 @@
+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;
+stop slave;
+SET @@debug="d,simulate_find_log_pos_error";
+reset slave;
+ERROR HY000: Target log not found in binlog index
+show warnings;
+Level	Code	Message
+Error	1373	Target log not found in binlog index
+Error	1371	Failed purging old relay logs: Failed during log reset
+SET @@debug="";
+reset slave;
+change master to master_host='dummy';
+SET @@debug="d,simulate_find_log_pos_error";
+change master to master_host='dummy';
+ERROR HY000: Target log not found in binlog index
+SET @@debug="";
+reset slave;
+change master to master_host='dummy';
+SET @@debug="d,simulate_find_log_pos_error";
+reset master;
+ERROR HY000: Target log not found in binlog index
+SET @@debug="";
+reset master;
+SET @@debug="d,simulate_find_log_pos_error";
+purge binary logs to 'master-bin.000001';
+ERROR HY000: Target log not found in binlog index
+SET @@debug="";
+purge binary logs to 'master-bin.000001';
+End of the tests

=== added file 'mysql-test/suite/rpl/t/rpl_bug41902-slave.opt'
--- a/mysql-test/suite/rpl/t/rpl_bug41902-slave.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_bug41902-slave.opt	2009-11-20 13:30:35 +0000
@@ -0,0 +1 @@
+--loose-debug=-d,simulate_find_log_pos_error

=== added file 'mysql-test/suite/rpl/t/rpl_bug41902.test'
--- a/mysql-test/suite/rpl/t/rpl_bug41902.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_bug41902.test	2009-11-20 13:30:35 +0000
@@ -0,0 +1,61 @@
+# Test for Bug #41902 MYSQL_BIN_LOG::reset_logs() doesn't call my_error()
+#                     in face of an error
+#
+
+source include/have_debug.inc;
+source include/master-slave.inc;
+
+#
+# test checks that 
+# a. there is no crash when find_log_pos() returns with an error
+#    that tests expect to receive;
+# b. in the case of multiple error messages the first error message is 
+#    reported to the user and others are available as warnings.
+#
+
+connection slave;
+stop slave;
+
+SET @@debug="d,simulate_find_log_pos_error";
+
+--error ER_UNKNOWN_TARGET_BINLOG
+reset slave;
+show warnings;
+
+SET @@debug="";
+reset slave;
+change master to master_host='dummy';
+
+SET @@debug="d,simulate_find_log_pos_error";
+
+--error ER_UNKNOWN_TARGET_BINLOG
+change master to master_host='dummy';
+
+SET @@debug="";
+reset slave;
+change master to master_host='dummy';
+
+connection master;
+SET @@debug="d,simulate_find_log_pos_error";
+--error ER_UNKNOWN_TARGET_BINLOG
+reset master;
+
+SET @@debug="";
+reset master;
+
+SET @@debug="d,simulate_find_log_pos_error";
+--error ER_UNKNOWN_TARGET_BINLOG
+purge binary logs to 'master-bin.000001';
+
+SET @@debug="";
+purge binary logs to 'master-bin.000001';
+
+--disable_query_log
+call mtr.add_suppression("Failed to locate old binlog or relay log files");
+call mtr.add_suppression("MYSQL_LOG::purge_logs was called with file ./master-bin.000001 not listed in the index");
+connection slave;
+call mtr.add_suppression("Failed to locate old binlog or relay log files");
+call mtr.add_suppression("MYSQL_LOG::purge_logs was called with file ./master-bin.000001 not listed in the index");
+--enable_query_log
+
+--echo End of the tests

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2009-11-06 16:35:04 +0000
+++ b/sql/log.cc	2009-11-20 13:30:35 +0000
@@ -63,6 +63,35 @@ static int binlog_rollback(handlerton *h
 static int binlog_prepare(handlerton *hton, THD *thd, bool all);
 
 /**
+   purge logs, master and slave sides both, related error code
+   convertor.
+   Called from @c purge_error_message(), @c MYSQL_BIN_LOG::reset_logs()
+
+   @param  res  an internal to purging routines error code 
+
+   @return the user level error code ER_*
+*/
+uint purge_log_get_error_code(int res)
+{
+  uint errcode= 0;
+
+  switch (res)  {
+  case 0: break;
+  case LOG_INFO_EOF:	errcode= ER_UNKNOWN_TARGET_BINLOG; break;
+  case LOG_INFO_IO:	errcode= ER_IO_ERR_LOG_INDEX_READ; break;
+  case LOG_INFO_INVALID:errcode= ER_BINLOG_PURGE_PROHIBITED; break;
+  case LOG_INFO_SEEK:	errcode= ER_FSEEK_FAIL; break;
+  case LOG_INFO_MEM:	errcode= ER_OUT_OF_RESOURCES; break;
+  case LOG_INFO_FATAL:	errcode= ER_BINLOG_PURGE_FATAL_ERR; break;
+  case LOG_INFO_IN_USE: errcode= ER_LOG_IN_USE; break;
+  case LOG_INFO_EMFILE: errcode= ER_BINLOG_PURGE_EMFILE; break;
+  default:		errcode= ER_LOG_PURGE_UNKNOWN_ERR; break;
+  }
+
+  return errcode;
+}
+
+/**
   Silence all errors and warnings reported when performing a write
   to a log table.
   Errors and warnings are not reported to the client or SQL exception
@@ -2778,8 +2807,10 @@ int MYSQL_BIN_LOG::find_log_pos(LOG_INFO
   {
     uint length;
     my_off_t offset= my_b_tell(&index_file);
-    /* If we get 0 or 1 characters, this is the end of the file */
 
+    DBUG_EXECUTE_IF("simulate_find_log_pos_error",
+                    error=  LOG_INFO_EOF; break;);
+    /* If we get 0 or 1 characters, this is the end of the file */
     if ((length= my_b_gets(&index_file, fname, FN_REFLEN)) <= 1)
     {
       /* Did not find the given entry; Return not found or error */
@@ -2881,6 +2912,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
 {
   LOG_INFO linfo;
   bool error=0;
+  int err;
   const char* save_name;
   DBUG_ENTER("reset_logs");
 
@@ -2907,9 +2939,12 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
 
   /* First delete all old log files */
 
-  if (find_log_pos(&linfo, NullS, 0))
+  if ((err= find_log_pos(&linfo, NullS, 0)) != 0)
   {
-    error=1;
+    uint errcode= purge_log_get_error_code(err);
+    sql_print_error("Failed to locate old binlog or relay log files");
+    my_message(errcode, ER(errcode), MYF(0));
+    error= 1;
     goto err;
   }
 
@@ -2978,6 +3013,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
   my_free((uchar*) save_name, MYF(0));
 
 err:
+  if (error == 1)
+    name= const_cast<char*>(save_name);
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
   pthread_mutex_unlock(&LOCK_index);
   pthread_mutex_unlock(&LOCK_log);

=== modified file 'sql/log.h'
--- a/sql/log.h	2009-10-07 21:13:07 +0000
+++ b/sql/log.h	2009-11-20 13:30:35 +0000
@@ -611,5 +611,6 @@ enum enum_binlog_format {
 extern TYPELIB binlog_format_typelib;
 
 int query_error_code(THD *thd, bool not_killed);
+uint purge_log_get_error_code(int res);
 
 #endif /* LOG_H */

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2009-10-09 13:26:37 +0000
+++ b/sql/rpl_rli.h	2009-11-20 13:30:35 +0000
@@ -221,8 +221,14 @@ public:
   int events_till_abort;
 #endif  
 
-  /* if not set, the value of other members of the structure are undefined */
-  bool inited;
+  /*
+    inited changes its value within LOCK_active_mi-guarded critical
+    sections  at times of start_slave_threads() (0->1) and end_slave() (1->0).
+    Readers may not acquire the mutex while they realize potential concurrency
+    issue.
+    If not set, the value of other members of the structure are undefined.
+  */
+  volatile bool inited;
   volatile bool abort_slave;
   volatile uint slave_running;
 

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2009-11-13 10:17:53 +0000
+++ b/sql/slave.cc	2009-11-20 13:30:35 +0000
@@ -653,11 +653,15 @@ int start_slave_thread(pthread_handler h
       DBUG_PRINT("sleep",("Waiting for slave thread to start"));
       const char* old_msg = thd->enter_cond(start_cond,cond_lock,
                                             "Waiting for slave thread to start");
-      pthread_cond_wait(start_cond,cond_lock);
+      pthread_cond_wait(start_cond, cond_lock);
       thd->exit_cond(old_msg);
       pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released
       if (thd->killed)
+      {
+        if (start_lock)
+          pthread_mutex_unlock(start_lock);
         DBUG_RETURN(thd->killed_errno());
+      }
     }
   }
   if (start_lock)
@@ -4653,9 +4657,6 @@ void rotate_relay_log(Master_info* mi)
 
   DBUG_EXECUTE_IF("crash_before_rotate_relaylog", abort(););
 
-  /* We don't lock rli->run_lock. This would lead to deadlocks. */
-  pthread_mutex_lock(&mi->run_lock);
-
   /*
      We need to test inited because otherwise, new_file() will attempt to lock
      LOCK_log, which may not be inited (if we're not a slave).
@@ -4684,7 +4685,6 @@ void rotate_relay_log(Master_info* mi)
   */
   rli->relay_log.harvest_bytes_written(&rli->log_space_total);
 end:
-  pthread_mutex_unlock(&mi->run_lock);
   DBUG_VOID_RETURN;
 }
 

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2009-11-13 10:17:53 +0000
+++ b/sql/sql_repl.cc	2009-11-20 13:30:35 +0000
@@ -259,24 +259,11 @@ bool log_in_use(const char* log_name)
 
 bool purge_error_message(THD* thd, int res)
 {
-  uint errmsg= 0;
+  uint errcode;
 
-  switch (res)  {
-  case 0: break;
-  case LOG_INFO_EOF:	errmsg= ER_UNKNOWN_TARGET_BINLOG; break;
-  case LOG_INFO_IO:	errmsg= ER_IO_ERR_LOG_INDEX_READ; break;
-  case LOG_INFO_INVALID:errmsg= ER_BINLOG_PURGE_PROHIBITED; break;
-  case LOG_INFO_SEEK:	errmsg= ER_FSEEK_FAIL; break;
-  case LOG_INFO_MEM:	errmsg= ER_OUT_OF_RESOURCES; break;
-  case LOG_INFO_FATAL:	errmsg= ER_BINLOG_PURGE_FATAL_ERR; break;
-  case LOG_INFO_IN_USE: errmsg= ER_LOG_IN_USE; break;
-  case LOG_INFO_EMFILE: errmsg= ER_BINLOG_PURGE_EMFILE; break;
-  default:		errmsg= ER_LOG_PURGE_UNKNOWN_ERR; break;
-  }
-
-  if (errmsg)
+  if ((errcode= purge_log_get_error_code(res)) != 0)
   {
-    my_message(errmsg, ER(errmsg), MYF(0));
+    my_message(errcode, ER(errcode), MYF(0));
     return TRUE;
   }
   my_ok(thd);
@@ -861,9 +848,7 @@ impossible position";
             }
             else
             {
-              DBUG_ASSERT(ret == 0 && signal_cnt != mysql_bin_log.signal_cnt ||
-                          thd->killed);
-              DBUG_PRINT("wait",("binary log received update"));
+              DBUG_PRINT("wait",("binary log received update or a broadcast signal caught"));
             }
           } while (signal_cnt == mysql_bin_log.signal_cnt && !thd->killed);
           pthread_mutex_unlock(log_lock);


Attachment: [text/bzr-bundle] bzr/aelkin@mysql.com-20091120133035-opb3nc32erqbmi1t.bundle
Thread
bzr commit into mysql-5.1-rep+2 branch (aelkin:3144) Bug#48463Andrei Elkin20 Nov