List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:May 11 2007 10:19am
Subject:bk commit into 5.1 tree (aelkin:1.2414)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of elkin. When elkin 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-05-11 11:18:59+03:00, aelkin@stripped
+2 -0
  WL3557 Conflict detection
  
  Key info printing withing the conflict detection error message.
  Testing was basically done (ndb not - needs merging with the latest tree first), result
files left unchanged
  for a while (waiting for input how proceed with this part of WL's work)

  sql/log_event.cc@stripped, 2007-05-11 11:18:56+03:00,
aelkin@stripped +112 -22
    buffer for transiting key info back to the error mutliplexor;
    the buffer filler function;
    its calls deployment in replace_record and find_and_fetch_record;
    compile_time_assert() borrowed from 5.1 tree

  sql/log_event.h@stripped, 2007-05-11 11:18:56+03:00,
aelkin@stripped +4 -4
    the 2nd arg key_info message to the error multiplexor (in Rows_log::exec_event)

# 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:	aelkin
# Host:	dsl-hkibras-fe31f900-164.dhcp.inet.fi
# Root:	/home/elkin/MySQL/TEAM/FIXES/5.1/wl3557_conflict_detection

--- 1.267/sql/log_event.cc	2007-05-09 11:11:54 +03:00
+++ 1.268/sql/log_event.cc	2007-05-11 11:18:56 +03:00
@@ -31,6 +31,8 @@
 
 #define log_cs	&my_charset_latin1
 
+#define MAX_SLAVE_ERRMSG_KEY_INFO  (MAX_SLAVE_ERRMSG/2)
+
 /*
   Cache that will automatically be written to a dedicated file on
   destruction.
@@ -5844,6 +5846,10 @@ int Rows_log_event::exec_event(st_relay_
     {
       char const *row_end= NULL;
       bool rows_done= row_start >= (const char*) m_rows_end;
+      char err_key_msg[MAX_SLAVE_ERRMSG_KEY_INFO];
+      
+      err_key_msg[0]= 0;
+
       if (!rows_done)
       {
         if ((error= do_prepare_row(thd, rli, table, row_start, &row_end)))
@@ -5857,7 +5863,7 @@ int Rows_log_event::exec_event(st_relay_
         THD* old_thd= table->in_use;
         if (!table->in_use)
           table->in_use= thd;
-        error= do_exec_row(table);
+        error= do_exec_row(table, err_key_msg);
         table->in_use = old_thd;
       }
       else
@@ -5911,6 +5917,8 @@ int Rows_log_event::exec_event(st_relay_
       {
         char llbuf[22];
         int report_error= error;
+        const char *format_err= "%s applying on table %s.%s %s failed at %s:%s";
+
         if (ignored_error_code(error))
         {
           error= 0;
@@ -5925,10 +5933,10 @@ int Rows_log_event::exec_event(st_relay_
         */
         if (conflict_check && report_error == ER_REPLICATION_CONFLICT)
           slave_print_msg(error? ERROR_LEVEL : WARNING_LEVEL,
-                          rli, report_error,
-                          "%s applying on table %s.%s failed at %s:%s",
+                          rli, report_error, 
+                          format_err,
                           get_type_str(), table->s->db.str, 
-                          table->s->table_name.str,
+                          table->s->table_name.str, err_key_msg,
                           rli->event_relay_log_name,
                           llstr(rli->event_relay_log_pos,llbuf));
       }
@@ -6754,6 +6762,64 @@ copy_extra_record_fields(TABLE *table,
   return 0;                                     // All OK
 }
 
+
+/*
+  auxiliary function implementing logic a'la handler::print_keydup_error
+  to store key info into a buffer
+  
+  input: table
+  input: key_nr - key index
+  input/output: buf
+*/
+
+/*
+  Todo: remove in merging as the 5.1 has the declaration
+ */
+#ifndef __GNUC__
+#define compile_time_assert(X)  do { } while(0)
+#else
+#define compile_time_assert(X)                                  \
+  do                                                            \
+  {                                                             \
+    char compile_time_assert[(X) ? 1 : -1]                      \
+                             __attribute__ ((unused));          \
+  } while(0)
+#endif
+
+
+inline char * fill_buf_key_error(TABLE * table, int key_nr, char *buf)
+{
+  char key[MAX_KEY_LENGTH];
+  String str(key,sizeof(key),system_charset_info);
+  const char format[]= "keyname: %s, values of fields: %s";
+
+  if (key_nr == MAX_KEY || key_nr == -1)
+  {
+    /* Key is unknown */
+    strcpy(buf, "*UNKNOWN*");
+  }
+  else
+  {
+    key_unpack(&str, table, (uint) key_nr);
+    int max_length= MAX_SLAVE_ERRMSG_KEY_INFO -
+      (uint) strlen(table->key_info[key_nr].name) - sizeof(format);
+    compile_time_assert(MAX_SLAVE_ERRMSG_KEY_INFO - NAME_LEN -
+                        (int) sizeof(format) > 0);
+    DBUG_ASSERT(max_length > 0);
+    if (str.length() >= (uint) max_length)
+    {
+      str.length(max_length - 4);
+      str.append(STRING_WITH_LEN("..."));
+    }
+    uint length=
+      (uint) my_sprintf(buf,(buf, format,
+                             table->key_info[key_nr].name, str.c_ptr()));
+    DBUG_ASSERT(length < MAX_SLAVE_ERRMSG_KEY_INFO);
+  }
+  return buf;
+}
+
+
 /*
   Replace the provided record in the database.
 
@@ -6781,33 +6847,39 @@ static int
 replace_record(THD *thd, TABLE *table,
                ulong const master_reclength,
                uint const master_fields,
-               bool conflict_check)
+               bool conflict_check,
+               char *msg)
 {
   DBUG_ENTER("replace_record");
   DBUG_ASSERT(table != NULL && thd != NULL);
 
   int error;
-  int keynum;
   auto_afree_ptr<char> key(NULL);
 
   while ((error= table->file->ha_write_row(table->record[0])))
   {
+    int keynum;
     if (error == HA_ERR_LOCK_DEADLOCK ||
         error == HA_ERR_LOCK_WAIT_TIMEOUT ||
         conflict_check)
     {
-      if (conflict_check &&
-          (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE))
+      if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE)
+      {
+        keynum= table->file->get_dup_key(error);
+        fill_buf_key_error(table, keynum, msg);
         error= HA_ERR_REPLICATION_CONFLICT;
+      }
       DBUG_PRINT("info", ("error: %d", error));
       DBUG_RETURN(error);
     }
-    if ((keynum= table->file->get_dup_key(error)) < 0) //ER(ER_DUP_ENTRY)
+    
+    if ((keynum= table->file->get_dup_key(error)) == -1)
     {
-      /* We failed to retrieve the duplicate key, sever error */
+      /* We failed to retrieve the duplicate key,
+         TODO: not dup but rather sever error */
       DBUG_RETURN(error);
     }
-
+    
     /*
       The following is in fact conflict resolution.
 
@@ -6891,12 +6963,12 @@ replace_record(THD *thd, TABLE *table,
   DBUG_RETURN(error);
 }
 
-int Write_rows_log_event::do_exec_row(TABLE *table)
+int Write_rows_log_event::do_exec_row(TABLE *table, char *key_err_msg)
 {
   DBUG_ASSERT(table != NULL);
   int error= replace_record(thd, table, m_master_reclength, m_width,
                             /* mismatch of cols with master does not matter */
-                            conflict_check);
+                            conflict_check, key_err_msg);
   return error;
 }
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
@@ -6966,7 +7038,7 @@ static bool record_compare(TABLE *table)
           row before its updating)
 */
 
-static int find_and_fetch_row(TABLE *table, byte *key, bool conflict_check)
+static int find_and_fetch_row(TABLE *table, byte *key, bool conflict_check, char *msg)
 {
   int error;
   DBUG_ENTER("find_and_fetch_row(TABLE *table, byte *key, byte *record)");
@@ -7017,6 +7089,10 @@ static int find_and_fetch_row(TABLE *tab
          */
         error= HA_ERR_REPLICATION_CONFLICT;
     }
+    if (error == HA_ERR_REPLICATION_CONFLICT)
+    {
+      fill_buf_key_error(table, table->s->primary_key, msg);
+    }
     DBUG_RETURN(error);
   }
 
@@ -7046,7 +7122,10 @@ static int find_and_fetch_row(TABLE *tab
       if (conflict_check &&
           /* benign errors due to locate OR are */
           (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE))
+      {
+        fill_buf_key_error(table, 0, msg);
         error= HA_ERR_REPLICATION_CONFLICT;
+      }
       table->file->ha_index_end();
       DBUG_RETURN(error);
     }
@@ -7079,8 +7158,13 @@ static int find_and_fetch_row(TABLE *tab
     if (table->key_info->flags & HA_NOSAME)
     {
       table->file->ha_index_end();
-      if (conflict_check)
-	error= record_compare(table) == 0 ?  0: HA_ERR_REPLICATION_CONFLICT;
+      if (!conflict_check || record_compare(table) == 0)
+        error= 0;
+      else
+      {
+        fill_buf_key_error(table, 0, msg);
+        error= HA_ERR_REPLICATION_CONFLICT;
+      }
       DBUG_RETURN(error);
     }
 
@@ -7098,7 +7182,10 @@ static int find_and_fetch_row(TABLE *tab
       if ((error= table->file->index_next(table->record[1])))
       {
         if (conflict_check && error == HA_ERR_END_OF_FILE)
+        {
+          fill_buf_key_error(table, 0, msg);
           error= HA_ERR_REPLICATION_CONFLICT;
+        }
         table->file->ha_index_end();
         DBUG_RETURN(error);
       }
@@ -7161,7 +7248,10 @@ static int find_and_fetch_row(TABLE *tab
     
     if (conflict_check &&
         (error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED))
+    {
+      strcpy(msg, "*NO KEYS DEFINED*");
       error= HA_ERR_REPLICATION_CONFLICT;
+    }
     DBUG_RETURN(error);
   }
   DBUG_RETURN(0);
@@ -7279,14 +7369,14 @@ int Delete_rows_log_event::do_prepare_ro
   return error;
 }
 
-int Delete_rows_log_event::do_exec_row(TABLE *table)
+int Delete_rows_log_event::do_exec_row(TABLE *table, char *key_err_msg)
 {
   int error;
   DBUG_ASSERT(table != NULL);
 
   if (!(error= find_and_fetch_row(table, m_key,
-				  (table->s->fields == m_width) &&
-				  conflict_check)))
+                                  table->s->fields == m_width &&
conflict_check,
+                                  key_err_msg)))
   {
     /*
       Now we should have the right row to delete.  We are using
@@ -7440,13 +7530,13 @@ int Update_rows_log_event::do_prepare_ro
   return error;
 }
 
-int Update_rows_log_event::do_exec_row(TABLE *table)
+int Update_rows_log_event::do_exec_row(TABLE *table, char *key_err_msg)
 {
   DBUG_ASSERT(table != NULL);
 
   int error= find_and_fetch_row(table, m_key,
-                                (table->s->fields == m_width) &&
-                                conflict_check);
+                                table->s->fields == m_width &&
conflict_check,
+                                key_err_msg);
   if (error)
     return error;
   

--- 1.147/sql/log_event.h	2007-05-03 21:54:11 +03:00
+++ 1.148/sql/log_event.h	2007-05-11 11:18:56 +03:00
@@ -2016,7 +2016,7 @@ private:
       0 if execution succeeded, 1 if execution failed.
       
   */
-  virtual int do_exec_row(TABLE *table) = 0;
+  virtual int do_exec_row(TABLE *table, char *key_err_msg) = 0;
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 };
 
@@ -2076,7 +2076,7 @@ private:
   virtual int do_after_row_operations(TABLE *table, int error);
   virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*,
                              char const *row_start, char const **row_end);
-  virtual int do_exec_row(TABLE *table);
+  virtual int do_exec_row(TABLE *table, char *key_err_msg);
 #endif
 };
 
@@ -2141,7 +2141,7 @@ private:
   virtual int do_after_row_operations(TABLE *table, int error);
   virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*,
                              char const *row_start, char const **row_end);
-  virtual int do_exec_row(TABLE *table);
+  virtual int do_exec_row(TABLE *table, char *key_err_msg);
 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 };
 
@@ -2212,7 +2212,7 @@ private:
   virtual int do_after_row_operations(TABLE *table, int error);
   virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*,
                              char const *row_start, char const **row_end);
-  virtual int do_exec_row(TABLE *table);
+  virtual int do_exec_row(TABLE *table, char *key_err_msg);
 #endif
 };
 
Thread
bk commit into 5.1 tree (aelkin:1.2414)Andrei Elkin11 May