List:Commits« Previous MessageNext Message »
From:Lars Thalmann Date:February 24 2007 11:10pm
Subject:bk commit into 5.0 tree (lars:1.2421)
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of lthalmann. When lthalmann 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, 2007-02-25 00:10:51+01:00, lars@stripped +9 -0
  Merge mysql.com:/nfsdisk1/lars/bkroot/mysql-5.0-rpl
  into  mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge
  MERGE: 1.2414.1.5

  sql/field.cc@stripped, 2007-02-25 00:10:45+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.335.1.6

  sql/item_func.cc@stripped, 2007-02-25 00:10:45+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.317.1.11

  sql/log.cc@stripped, 2007-02-25 00:10:46+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.200.1.1

  sql/log_event.cc@stripped, 2007-02-25 00:10:46+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.223.1.1

  sql/log_event.h@stripped, 2007-02-25 00:10:46+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.130.1.1

  sql/mysql_priv.h@stripped, 2007-02-25 00:10:46+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.429.1.3

  sql/mysqld.cc@stripped, 2007-02-25 00:10:46+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.582.13.1

  sql/slave.cc@stripped, 2007-02-25 00:10:47+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.286.1.5

  sql/sql_insert.cc@stripped, 2007-02-25 00:10:47+01:00, lars@stripped +0 -0
    Auto merged
    MERGE: 1.211.3.4

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	lars
# Host:	dl145j.mysql.com
# Root:	/nfsdisk1/lars/MERGE/mysql-5.0-merge/RESYNC

--- 1.339/sql/field.cc	2007-02-25 00:10:58 +01:00
+++ 1.340/sql/field.cc	2007-02-25 00:10:58 +01:00
@@ -7014,7 +7014,7 @@ int Field_blob::store(const char *from,u
                               cannot_convert_error_pos, from + length))
     return 2;
 
-  if (copy_length < length)
+  if (from_end_pos < from + length)
   {
     report_data_too_long(this);
     return 2;

--- 1.202/sql/log.cc	2007-02-25 00:10:58 +01:00
+++ 1.203/sql/log.cc	2007-02-25 00:10:58 +01:00
@@ -2524,7 +2524,7 @@ int TC_LOG_MMAP::open(const char *opt_na
       goto err;
     if (using_heuristic_recover())
       return 1;
-    if ((fd= my_create(logname, O_RDWR, 0, MYF(MY_WME))) < 0)
+    if ((fd= my_create(logname, CREATE_MODE, O_RDWR, MYF(MY_WME))) < 0)
       goto err;
     inited=1;
     file_length= opt_tc_log_size;

--- 1.225/sql/log_event.cc	2007-02-25 00:10:58 +01:00
+++ 1.226/sql/log_event.cc	2007-02-25 00:10:58 +01:00
@@ -2051,6 +2051,8 @@ Start_log_event_v3::Start_log_event_v3(c
   binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
   memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
 	 ST_SERVER_VER_LEN);
+  // prevent overrun if log is corrupted on disk
+  server_version[ST_SERVER_VER_LEN-1]= 0;
   created= uint4korr(buf+ST_CREATED_OFFSET);
   /* We use log_pos to mark if this was an artificial event or not */
   artificial_event= (log_pos == 0);
@@ -2174,6 +2176,8 @@ Format_description_log_event(uint8 binlo
   switch (binlog_ver) {
   case 4: /* MySQL 5.0 */
     memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
+    DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
+                    strmov(server_version, "5.0.34"););
     common_header_len= LOG_EVENT_HEADER_LEN;
     number_of_event_types= LOG_EVENT_TYPES;
     /* we'll catch my_malloc() error in is_valid() */
@@ -2245,6 +2249,7 @@ Format_description_log_event(uint8 binlo
     post_header_len= 0; /* will make is_valid() fail */
     break;
   }
+  calc_server_version_split();
 }
 
 
@@ -2284,6 +2289,7 @@ Format_description_log_event(const char*
   post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
                                       number_of_event_types*
                                       sizeof(*post_header_len), MYF(0));
+  calc_server_version_split();
   DBUG_VOID_RETURN;
 }
 
@@ -2383,6 +2389,37 @@ int Format_description_log_event::exec_e
   DBUG_RETURN(Start_log_event_v3::exec_event(rli));
 }
 #endif
+
+
+/**
+   Splits the event's 'server_version' string into three numeric pieces stored
+   into 'server_version_split':
+   X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
+   X.Yabc -> {X,Y,0}
+   Xabc -> {X,0,0}
+   'server_version_split' is then used for lookups to find if the server which
+   created this event has some known bug.
+*/
+void Format_description_log_event::calc_server_version_split()
+{
+  char *p= server_version, *r;
+  ulong number;
+  for (uint i= 0; i<=2; i++)
+  {
+    number= strtoul(p, &r, 10);
+    server_version_split[i]= (uchar)number;
+    DBUG_ASSERT(number < 256); // fit in uchar
+    p= r;
+    DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
+    if (*r == '.')
+      p++; // skip the dot
+  }
+  DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
+                     " '%s' %d %d %d", server_version,
+                     server_version_split[0],
+                     server_version_split[1], server_version_split[2]));
+}
+
 
   /**************************************************************************
         Load_log_event methods

--- 1.132/sql/log_event.h	2007-02-25 00:10:58 +01:00
+++ 1.133/sql/log_event.h	2007-02-25 00:10:58 +01:00
@@ -1104,6 +1104,7 @@ public:
   uint8 number_of_event_types;
   /* The list of post-headers' lengthes */
   uint8 *post_header_len;
+  uchar server_version_split[3];
 
   Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
 
@@ -1135,6 +1136,7 @@ public:
     */
     return FORMAT_DESCRIPTION_HEADER_LEN;
   }
+  void calc_server_version_split();
 };
 
 

--- 1.431/sql/mysql_priv.h	2007-02-25 00:10:58 +01:00
+++ 1.432/sql/mysql_priv.h	2007-02-25 00:10:58 +01:00
@@ -60,10 +60,10 @@ typedef ulonglong nested_join_map;
 
 /* query_id */
 typedef ulonglong query_id_t;
-extern query_id_t query_id;
+extern query_id_t global_query_id;
 
 /* increment query_id and return it.  */
-inline query_id_t next_query_id() { return query_id++; }
+inline query_id_t next_query_id() { return global_query_id++; }
 
 /* useful constants */
 extern const key_map key_map_empty;
@@ -175,7 +175,7 @@ MY_LOCALE *my_locale_by_number(uint numb
  Feel free to raise this by the smallest amount you can to get the
  "execution_constants" test to pass.
  */
-#define STACK_MIN_SIZE          10788   // Abort if less stack during eval.
+#define STACK_MIN_SIZE          12000   // Abort if less stack during eval.
 
 #define STACK_MIN_SIZE_FOR_OPEN 1024*80
 #define STACK_BUFF_ALLOC	256	// For stack overrun checks
@@ -1213,7 +1213,7 @@ void my_dbopt_free(void);
   External variables
 */
 
-extern time_t start_time;
+extern time_t server_start_time;
 extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
 	    mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
             def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];

--- 1.590/sql/mysqld.cc	2007-02-25 00:10:58 +01:00
+++ 1.591/sql/mysqld.cc	2007-02-25 00:10:58 +01:00
@@ -355,6 +355,8 @@ my_bool opt_safe_user_create = 0, opt_no
 my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
 my_bool opt_log_slave_updates= 0;
 my_bool	opt_innodb;
+bool slave_warning_issued = false; 
+
 #ifdef HAVE_NDBCLUSTER_DB
 const char *opt_ndbcluster_connectstring= 0;
 const char *opt_ndb_connectstring= 0;
@@ -3198,7 +3200,7 @@ server.");
                                (TC_LOG *) &tc_log_mmap) :
            (TC_LOG *) &tc_log_dummy);
 
-  if (tc_log->open(opt_bin_logname))
+  if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
   {
     sql_print_error("Can't init tc log");
     unireg_abort(1);
@@ -6936,6 +6938,29 @@ get_one_option(int optid, const struct m
   case (int) OPT_STANDALONE:		/* Dummy option for NT */
     break;
 #endif
+  /*
+    The following change issues a deprecation warning if the slave
+    configuration is specified either in the my.cnf file or on
+    the command-line. See BUG#21490.
+  */
+  case OPT_MASTER_HOST:
+  case OPT_MASTER_USER:
+  case OPT_MASTER_PASSWORD:
+  case OPT_MASTER_PORT:
+  case OPT_MASTER_CONNECT_RETRY:
+  case OPT_MASTER_SSL:          
+  case OPT_MASTER_SSL_KEY:
+  case OPT_MASTER_SSL_CERT:       
+  case OPT_MASTER_SSL_CAPATH:
+  case OPT_MASTER_SSL_CIPHER:
+  case OPT_MASTER_SSL_CA:
+    if (!slave_warning_issued)                 //only show the warning once
+    {
+      slave_warning_issued = true;   
+      WARN_DEPRECATED(0, "5.2", "for replication startup options", 
+        "'CHANGE MASTER'");
+    }
+    break;
   case OPT_CONSOLE:
     if (opt_console)
       opt_error_log= 0;			// Force logs to stdout

--- 1.291/sql/slave.cc	2007-02-25 00:10:58 +01:00
+++ 1.292/sql/slave.cc	2007-02-25 00:10:58 +01:00
@@ -5174,6 +5174,70 @@ end:
 }
 
 
+/**
+   Detects, based on master's version (as found in the relay log), if master
+   has a certain bug.
+   @param rli RELAY_LOG_INFO which tells the master's version
+   @param bug_id Number of the bug as found in bugs.mysql.com
+   @return TRUE if master has the bug, FALSE if it does not.
+*/
+bool rpl_master_has_bug(RELAY_LOG_INFO *rli, uint bug_id)
+{
+  struct st_version_range_for_one_bug {
+    uint        bug_id;
+    const uchar introduced_in[3]; // first version with bug
+    const uchar fixed_in[3];      // first version with fix
+  };
+  static struct st_version_range_for_one_bug versions_for_all_bugs[]=
+  {
+    {24432, { 5, 0, 24 }, { 5, 0, 38 } },
+    {24432, { 5, 1, 12 }, { 5, 1, 17 } }
+  };
+  const uchar *master_ver=
+    rli->relay_log.description_event_for_exec->server_version_split;
+
+  DBUG_ASSERT(sizeof(rli->relay_log.description_event_for_exec->server_version_split) == 3);
+
+  for (uint i= 0;
+       i < sizeof(versions_for_all_bugs)/sizeof(*versions_for_all_bugs);i++)
+  {
+    const uchar *introduced_in= versions_for_all_bugs[i].introduced_in,
+      *fixed_in= versions_for_all_bugs[i].fixed_in;
+    if ((versions_for_all_bugs[i].bug_id == bug_id) &&
+        (memcmp(introduced_in, master_ver, 3) <= 0) &&
+        (memcmp(fixed_in,      master_ver, 3) >  0))
+    {
+      // a verbose message for the error log
+      slave_print_error(rli, ER_UNKNOWN_ERROR,
+                        "According to the master's version ('%s'),"
+                        " it is probable that master suffers from this bug:"
+                        " http://bugs.mysql.com/bug.php?id=%u"
+                        " and thus replicating the current binary log event"
+                        " may make the slave's data become different from the"
+                        " master's data."
+                        " To take no risk, slave refuses to replicate"
+                        " this event and stops."
+                        " We recommend that all updates be stopped on the"
+                        " master and slave, that the data of both be"
+                        " manually synchronized,"
+                        " that master's binary logs be deleted,"
+                        " that master be upgraded to a version at least"
+                        " equal to '%d.%d.%d'. Then replication can be"
+                        " restarted.",
+                        rli->relay_log.description_event_for_exec->server_version,
+                        bug_id,
+                        fixed_in[0], fixed_in[1], fixed_in[2]);
+      // a short message for SHOW SLAVE STATUS (message length constraints)
+      my_printf_error(ER_UNKNOWN_ERROR, "master may suffer from"
+                      " http://bugs.mysql.com/bug.php?id=%u"
+                      " so slave stops; check error log on slave"
+                      " for more info", MYF(0), bug_id);
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
 #ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
 template class I_List_iterator<i_string>;
 template class I_List_iterator<i_string_pair>;

--- 1.216/sql/sql_insert.cc	2007-02-25 00:10:58 +01:00
+++ 1.217/sql/sql_insert.cc	2007-02-25 00:10:58 +01:00
@@ -58,6 +58,7 @@
 #include "sp_head.h"
 #include "sql_trigger.h"
 #include "sql_select.h"
+#include "slave.h"
 
 #ifndef EMBEDDED_LIBRARY
 static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list);
@@ -405,6 +406,27 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
       (duplic == DUP_UPDATE))
     lock_type=TL_WRITE;
 #endif
+  if ((lock_type == TL_WRITE_DELAYED) &&
+      log_on && mysql_bin_log.is_open() &&
+      (values_list.elements > 1))
+  {
+    /*
+      Statement-based binary logging does not work in this case, because:
+      a) two concurrent statements may have their rows intermixed in the
+      queue, leading to autoincrement replication problems on slave (because
+      the values generated used for one statement don't depend only on the
+      value generated for the first row of this statement, so are not
+      replicable)
+      b) if first row of the statement has an error the full statement is
+      not binlogged, while next rows of the statement may be inserted.
+      c) if first row succeeds, statement is binlogged immediately with a
+      zero error code (i.e. "no error"), if then second row fails, query
+      will fail on slave too and slave will stop (wrongly believing that the
+      master got no error).
+      So we fallback to non-delayed INSERT.
+    */
+    lock_type= TL_WRITE;
+  }
   table_list->lock_type= lock_type;
 
 #ifndef EMBEDDED_LIBRARY
@@ -519,6 +541,14 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   thd->cuted_fields = 0L;
   table->next_number_field=table->found_next_number_field;
 
+#ifdef HAVE_REPLICATION
+  if (thd->slave_thread &&
+      (info.handle_duplicates == DUP_UPDATE) &&
+      (table->next_number_field != NULL) &&
+      rpl_master_has_bug(&active_mi->rli, 24432))
+    goto abort;
+#endif
+
   error=0;
   id=0;
   thd->proc_info="update";
@@ -1184,11 +1214,11 @@ int write_record(THD *thd, TABLE *table,
         if (res == VIEW_CHECK_ERROR)
           goto before_trg_err;
 
+        table->file->restore_auto_increment();
         if ((error=table->file->update_row(table->record[1],table->record[0])))
         {
           if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
           {
-            table->file->restore_auto_increment();
             goto ok_or_after_trg_err;
           }
           goto err;
@@ -2427,6 +2457,15 @@ select_insert::prepare(List<Item> &value
   }
   restore_record(table,s->default_values);		// Get empty record
   table->next_number_field=table->found_next_number_field;
+
+#ifdef HAVE_REPLICATION
+  if (thd->slave_thread &&
+      (info.handle_duplicates == DUP_UPDATE) &&
+      (table->next_number_field != NULL) &&
+      rpl_master_has_bug(&active_mi->rli, 24432))
+    DBUG_RETURN(1);
+#endif
+
   thd->cuted_fields=0;
   if (info.ignore || info.handle_duplicates != DUP_ERROR)
     table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
Thread
bk commit into 5.0 tree (lars:1.2421)Lars Thalmann25 Feb