List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:January 15 2008 9:46pm
Subject:bk commit into 5.1 tree (aelkin:1.2659) BUG#32971
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, 2008-01-15 22:46:01+02:00, aelkin@stripped +8 -0
  Bug #32971 No user level error message from slave sql thread when
ER_NO_DEFAULT_FOR_FIELD
  
  The error message due to lack of the default value for an extra field
  was not as informative as it should be.
  
  Fixed with improving the scheme of row events handling errors gathering,
  propagating and reporting.
  The scheme is in the following.
  Any kind of error of processing of a row event incidents are to be 
  registered with my_error().
  In the end Rows_log_event::do_apply_event() invokes rli->report() with the 
  message to display consisting of all the errors.
  A simple test checks two errors in processing an event.
  Two hunks - a user level error and pushing it into the list - 
  have been devoted to already fixed Bug@31702.

  include/my_base.h@stripped, 2008-01-15 22:45:55+02:00, aelkin@stripped +3 -1
    A new handler level error code that is supposed to be mapped to a set of more
    specific ER_ user level errors.

  mysql-test/extra/rpl_tests/rpl_row_tabledefs.test@stripped, 2008-01-15 22:45:56+02:00,
aelkin@stripped +3 -3
    Adding yet another extra field to see more than one error in show
    slave status' report.

  sql/log_event.cc@stripped, 2008-01-15 22:45:56+02:00, aelkin@stripped +37 -12
    Refining slave_rows_error_report to iterate on the list of gathered errors;
    Simplifying signature of prepare_record as the function does not call
    rli->report to leave that duty to the event's top level code.

  sql/log_event.h@stripped, 2008-01-15 22:45:56+02:00, aelkin@stripped +2 -0
    adding a corrupt event error pushing. The error will be seen with
    show slave status.

  sql/log_event_old.cc@stripped, 2008-01-15 22:45:56+02:00, aelkin@stripped +2 -2
    similar to log_event.cc changes

  sql/rpl_record.cc@stripped, 2008-01-15 22:45:57+02:00, aelkin@stripped +5 -12
    prepare_record only pushes an error to the list

  sql/rpl_record.h@stripped, 2008-01-15 22:45:57+02:00, aelkin@stripped +1 -2
    signature changed

  sql/share/errmsg.txt@stripped, 2008-01-15 22:45:57+02:00, aelkin@stripped +2 -0
    The user level error code that corresponds to HA_ERR_CORRUPT_EVENT.
    The error will be reported in show slave status if such a failure happens.

diff -Nrup a/include/my_base.h b/include/my_base.h
--- a/include/my_base.h	2007-10-20 19:19:50 +03:00
+++ b/include/my_base.h	2008-01-15 22:45:55 +02:00
@@ -411,7 +411,9 @@ enum ha_base_keytype {
                                             statement */
 #define HA_ERR_CORRUPT_EVENT      171    /* The event was corrupt, leading to
                                             illegal data being read */
-#define HA_ERR_LAST              171     /*Copy last error nr.*/
+#define HA_ERR_ROWS_EVENT_APPLY   172    /* The event could not be processed
+                                            no other hanlder error happened */
+#define HA_ERR_LAST              172     /*Copy last error nr.*/
 /* Add error numbers before HA_ERR_LAST and change it accordingly. */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
 
diff -Nrup a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
--- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test	2007-12-12 12:14:49 +02:00
+++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test	2008-01-15 22:45:56 +02:00
@@ -46,7 +46,7 @@ ALTER TABLE t1_bit
 ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test';
 # ... and add one non-nullable INT column last in table 't1_text'
 #     with no default,
-ALTER TABLE t1_nodef ADD x INT NOT NULL;
+ALTER TABLE t1_nodef ADD x INT NOT NULL, ADD y INT NOT NULL;
 # ... and remove the last column in t2
 ALTER TABLE t2 DROP b;
 # ... change the type of the single column in table 't4'
@@ -222,8 +222,8 @@ sync_slave_with_master;
 
 --echo **** On Slave ****
 connection slave;
-INSERT INTO t1_nodef VALUES (1,2,3);
-INSERT INTO t1_nodef VALUES (2,4,6);
+INSERT INTO t1_nodef VALUES (1,2,3,4);
+INSERT INTO t1_nodef VALUES (2,4,6,8);
 
 --echo **** On Master ****
 connection master;
diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc	2007-12-17 15:21:19 +02:00
+++ b/sql/log_event.cc	2008-01-15 22:45:56 +02:00
@@ -99,27 +99,48 @@ static const char *HA_ERR(int i)
   case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
   case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
   case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
+  case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
   }
   return 0;
 }
 
 /**
-   macro to call from different branches of Rows_log_event::do_apply_event
+   Error reporting facility for Rows_log_event::do_apply_event
+
+   @param
+   @param
+   @param
+   @param
+   @param
+   @param
+
 */
 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
                                            Relay_log_info const *rli, THD *thd,
                                            TABLE *table, const char * type,
                                            const char *log_name, ulong pos)
 {
-  const char *handler_error=  HA_ERR(ha_error);
+  const char *handler_error= HA_ERR(ha_error);
+  char buff[MAX_SLAVE_ERRMSG], *slider;
+  uint len;
+  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
+  MYSQL_ERROR *err;
+  buff[0]= 0;
+
+  for (err= it++, slider= buff; err && slider < buff + sizeof(buff) - 1;
+       slider= buff + len, err= it++)
+  {
+    len= my_snprintf(slider, buff - slider + sizeof(buff),
+                     " %s, Error_code: %d;", err->msg, err->code);
+  }
+  
   rli->report(level, thd->net.last_errno,
               "Could not execute %s event on table %s.%s;"
-              "%s%s handler error %s; "
+              "%s handler error %s; "
               "the event's master log %s, end_log_pos %lu",
               type, table->s->db.str,
               table->s->table_name.str,
-              thd->net.last_error[0] != 0 ? thd->net.last_error : "",
-              thd->net.last_error[0] != 0 ? ";" : "",
+              buff,
               handler_error == NULL? "<unknown>" : handler_error,
               log_name, pos);
 }
@@ -7548,7 +7569,7 @@ Rows_log_event::write_row(const Relay_lo
 
   /* fill table->record[0] with default values */
 
-  if ((error= prepare_record(rli, table, m_width,
+  if ((error= prepare_record(table, m_width,
                              TRUE /* check if columns have def. values */)))
     DBUG_RETURN(error);
   
@@ -7863,13 +7884,17 @@ int Rows_log_event::find_row(const Relay
   DBUG_ASSERT(m_table && m_table->in_use != NULL);
 
   TABLE *table= m_table;
-  int error;
-
-  /* unpack row - missing fields get default values */
+  int error= 0;
 
-  // TODO: shall we check and report errors here?
-  prepare_record(NULL,table,m_width,FALSE /* don't check errors */); 
-  error= unpack_current_row(rli); 
+  /*
+    rpl_row_tabledefs.test specifies that
+    if the extra field on the slave does not have a default value
+    and this is okay with Delete or Update events.
+    Todo: fix wl3228 hld that requires defauls for all types of events
+  */
+  
+  prepare_record(table, m_width, FALSE);
+  error= unpack_current_row(rli);
 
 #ifndef DBUG_OFF
   DBUG_PRINT("info",("looking for the following record"));
diff -Nrup a/sql/log_event.h b/sql/log_event.h
--- a/sql/log_event.h	2007-12-14 20:01:59 +02:00
+++ b/sql/log_event.h	2008-01-15 22:45:56 +02:00
@@ -3127,6 +3127,8 @@ protected:
     ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
     int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
                                    &m_curr_row_end, &m_master_reclength);
+    if (m_curr_row_end > m_rows_end)
+      my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
     ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
     return result;
   }
diff -Nrup a/sql/log_event_old.cc b/sql/log_event_old.cc
--- a/sql/log_event_old.cc	2007-12-05 21:00:06 +02:00
+++ b/sql/log_event_old.cc	2008-01-15 22:45:56 +02:00
@@ -2077,7 +2077,7 @@ Old_rows_log_event::write_row(const Rela
 
   /* fill table->record[0] with default values */
 
-  if ((error= prepare_record(rli, table, m_width,
+  if ((error= prepare_record(table, m_width,
                              TRUE /* check if columns have def. values */)))
     DBUG_RETURN(error);
   
@@ -2288,7 +2288,7 @@ int Old_rows_log_event::find_row(const R
   /* unpack row - missing fields get default values */
 
   // TODO: shall we check and report errors here?
-  prepare_record(NULL,table,m_width,FALSE /* don't check errors */); 
+  prepare_record(table, m_width, FALSE /* don't check errors */); 
   error= unpack_current_row(rli); 
 
 #ifndef DBUG_OFF
diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
--- a/sql/rpl_record.cc	2007-10-17 10:29:06 +03:00
+++ b/sql/rpl_record.cc	2008-01-15 22:45:57 +02:00
@@ -307,17 +307,15 @@ unpack_row(Relay_log_info const *rli,
   If @c check is true, fields are explicitly initialized only if they have
   default value or can be NULL. Otherwise error is reported.
  
-  @param log    Used to report errors.
   @param table  Table whose record[0] buffer is prepared. 
   @param skip   Number of columns for which default value initialization 
                 should be skipped.
   @param check  Indicates if errors should be checked when setting default
                 values.
                 
-  @returns 0 on success. 
+  @returns 0 on success or a handler level error code
  */ 
-int prepare_record(const Slave_reporting_capability *const log, 
-                   TABLE *const table, 
+int prepare_record(TABLE *const table, 
                    const uint skip, const bool check)
 {
   DBUG_ENTER("prepare_record");
@@ -337,18 +335,13 @@ int prepare_record(const Slave_reporting
 
     if (check && ((f->flags & mask) == mask))
     {
-      DBUG_ASSERT(log);
-      log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
-                  "Field `%s` of table `%s`.`%s` "
-                  "has no default value and cannot be NULL",
-                  f->field_name, table->s->db.str,
-                  table->s->table_name.str);
-      error = ER_NO_DEFAULT_FOR_FIELD;
+      my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), f->field_name);
+      error = HA_ERR_ROWS_EVENT_APPLY;
     }
     else
       f->set_default();
   }
-
+  
   DBUG_RETURN(error);
 }
 
diff -Nrup a/sql/rpl_record.h b/sql/rpl_record.h
--- a/sql/rpl_record.h	2007-09-10 14:15:59 +03:00
+++ b/sql/rpl_record.h	2008-01-15 22:45:57 +02:00
@@ -30,8 +30,7 @@ int unpack_row(Relay_log_info const *rli
                uchar const **const row_end, ulong *const master_reclength);
 
 // Fill table's record[0] with default values.
-int prepare_record(const Slave_reporting_capability *const, TABLE *const, 
-                   const uint =0, const bool =FALSE);
+int prepare_record(TABLE *const, const uint =0, const bool =FALSE);
 #endif
 
 #endif
diff -Nrup a/sql/share/errmsg.txt b/sql/share/errmsg.txt
--- a/sql/share/errmsg.txt	2007-12-14 20:01:59 +02:00
+++ b/sql/share/errmsg.txt	2008-01-15 22:45:57 +02:00
@@ -6119,3 +6119,5 @@ ER_SLAVE_AMBIGOUS_EXEC_MODE
 
 ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT
   eng "The BINLOG statement of type `%s` was not preceded by a format description BINLOG
statement."
+ER_SLAVE_CORRUPT_EVENT
+  eng "Currupted replication event was detected"
Thread
bk commit into 5.1 tree (aelkin:1.2659) BUG#32971Andrei Elkin15 Jan