MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:November 13 2009 7:20pm
Subject:bzr commit into mysql-5.0-bugteam branch (aelkin:2845) Bug#47142
View as plain text  
#At file:///home/andrei/MySQL/BZR/FIXES/5.0-bt-bug47142-until_catches_local_rotate-andrii/ based on revid:joro@stripped

 2845 Andrei Elkin	2009-11-13
      Bug #47142 "slave start until" stops 1 event too late in 4.1 to 5.0 replication
      
      When replicating from 4.1 master to 5.0 slave START SLAVE UNTIL can stop too late.
      The necessary in calculating of the beginning of an event the event's length
      did not correspond to the master's genuine information at the event's execution time.
      That piece of info was changed at the event's relay-logging.
      
      Fixed with storing the master genuine Query_log_event size into a new status
      variable at relay-logging of the event. The stored info is extacted at the event
      execution and participate further in the until-pos stopping routine.
      The new status variable's algorithm will be only active when the event comes
      from the master of version less than 5.0.
       
     @ sql/log_event.cc
        Storing and extracting the master's genuine size of the event from the status
        var of the event packet header.
     @ sql/log_event.h
        Incrementing the max szie of MAX_SIZE_LOG_EVENT_STATUS because of the new status var;
        Defining the new status variable to hold the master's genuine event size;
        Augmending the Query_log_event with a new member to hold a value to store/extact from the status
        var of the event packet header.

    modified:
      sql/log_event.cc
      sql/log_event.h
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2009-08-12 03:54:05 +0000
+++ b/sql/log_event.cc	2009-11-13 19:20:40 +0000
@@ -1271,10 +1271,20 @@ bool Query_log_event::write(IO_CACHE* fi
     int8store(start, table_map_for_update);
     start+= 8;
   }
+  if (master_data_written != 0)
+  {
+    /*
+      the event is originated by an old master
+    */
+    *start++= Q_MASTER_DATA_WRITTEN_CODE;
+    int4store(start, master_data_written);
+    start+= 4;
+  }
+
   /*
     NOTE: When adding new status vars, please don't forget to update
-    the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update function
-    code_name in this file.
+    the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
+    code_name() in this file.
    
     Here there could be code like
     if (command-line-option-which-says-"log_this_variable" && inited)
@@ -1354,6 +1364,7 @@ Query_log_event::Query_log_event(THD* th
    auto_increment_offset(thd_arg->variables.auto_increment_offset),
    lc_time_names_number(thd_arg->variables.lc_time_names->number),
    charset_database_number(0),
+   master_data_written(0),
    table_map_for_update((ulonglong)thd_arg->table_map_for_update)
 {
   time_t end_time;
@@ -1481,6 +1492,7 @@ code_name(int code)
   case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
   case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
   case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
+  case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
   }
   sprintf(buf, "CODE#%d", code);
   return buf;
@@ -1518,7 +1530,7 @@ Query_log_event::Query_log_event(const c
    flags2_inited(0), sql_mode_inited(0), charset_inited(0),
    auto_increment_increment(1), auto_increment_offset(1),
    time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
-   table_map_for_update(0)
+   table_map_for_update(0), master_data_written(0)
 {
   ulong data_len;
   uint32 tmp;
@@ -1574,6 +1586,17 @@ Query_log_event::Query_log_event(const c
     DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
                         (uint) status_vars_len));
     tmp-= 2;
+  } 
+  else
+  {
+    /*
+      old (of server version < 5.0) master's event will be relay-logged
+      to skew the original log_pos.
+      log_pos is saved in a status variable to restore at reading the event
+      from the relay log.
+    */
+    DBUG_ASSERT(description_event->binlog_version < 4);
+    master_data_written= data_written;
   }
   /*
     We have parsed everything we know in the post header for QUERY_EVENT,
@@ -1665,6 +1688,12 @@ Query_log_event::Query_log_event(const c
       table_map_for_update= uint8korr(pos);
       pos+= 8;
       break;
+    case Q_MASTER_DATA_WRITTEN_CODE:
+      CHECK_SPACE(pos, end, 4);
+      data_written= master_data_written= uint4korr(pos);
+      pos+= 4;
+      DBUG_ASSERT(description_event->binlog_version >= 4);
+      break;
     default:
       /* That's why you must write status vars in growing order of code */
       DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2009-03-27 05:19:50 +0000
+++ b/sql/log_event.h	2009-11-13 19:20:40 +0000
@@ -212,7 +212,8 @@ struct sql_ex_info
                                    1 + 1 + 255    /* type, length, time_zone */ + \
                                    1 + 2          /* type, lc_time_names_number */ + \
                                    1 + 2          /* type, charset_database_number */ + \
-                                   1 + 8          /* type, table_map_for_update */)
+                                   1 + 8          /* type, table_map_for_update */ + \
+                                   1 + 4          /* type, master_data_written */)
 #define MAX_LOG_EVENT_HEADER   ( /* in order of Query_log_event::write */ \
   LOG_EVENT_HEADER_LEN + /* write_header */ \
   QUERY_HEADER_LEN     + /* write_data */   \
@@ -278,6 +279,9 @@ struct sql_ex_info
 #define Q_CHARSET_DATABASE_CODE 8
 
 #define Q_TABLE_MAP_FOR_UPDATE_CODE 9
+
+#define Q_MASTER_DATA_WRITTEN_CODE 10
+
 /* Intvar event post-header */
 
 #define I_TYPE_OFFSET        0
@@ -810,6 +814,13 @@ public:
     statement, for other query statements, this will be zero.
   */
   ulonglong table_map_for_update;
+  /*
+    placeholder for data_written of a Query_log_event originated by an old 
+    (version < 5.0) master. The geniune master's value is necessary
+    to calculate the master size event's  parameters out of log_pos
+    for instance the beginning of position of the event (log_pos - data_written)
+  */
+  uint32 master_data_written;
 
 #ifndef MYSQL_CLIENT
 


Attachment: [text/bzr-bundle] bzr/aelkin@mysql.com-20091113192040-1dp1ssd2qof7tis6.bundle
Thread
bzr commit into mysql-5.0-bugteam branch (aelkin:2845) Bug#47142Andrei Elkin13 Nov
  • Re: bzr commit into mysql-5.0-bugteam branch (aelkin:2845) Bug#47142Sven Sandberg22 Dec