List:Commits« Previous MessageNext Message »
From:Sven Sandberg Date:January 3 2008 3:52pm
Subject:bk commit into 5.1 tree (sven:1.2658) BUG#27779
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of sven. When sven 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-03 16:52:18+01:00, sven@riska.(none) +2 -0
  BUG#27779: Slave cannot read old rows log events.
  Problem: Some previous versions use a different binlog format. In order
  to replicate from old versions to new versions, the new version must be
  aware of all old formats. This patch fixes one of several issues when
  replicating from mysql-5.1-wl2325-5.0-drop6 to mysql-5.1-new-rpl.
  Specifically, in mysql-5.1-wl2325-5.0-drop6, the event type id's were
  different than in mysql-5.1-new-rpl.
  Fix (in mysql-5.1-new-rpl):
   (1) detect that the server that generated the events uses the old
  format, by checking the server version of the format_description_log_event
  This patch recognizes mysql-5.1-wl2325-5.0-drop6 and -drop5.
   (2) if the generating server is old, map old event types to new event
  types using a permutation array.
  
  This fixes part of the bug (specifically, mysqlbinlog can read the
  binlog rpl_bug27779_a.dat attached to the bug report for BUG#27779
  without problems). However, there are remaining problems with replicating
  from mysql-5.1-wl2325-5.0-drop6 to mysql-5.1-new-rpl (specifically, the
  test case for BUG#27779 fails: when the output of
  'mysqlbinlog rpl_bug27779_a.dat' is piped to a client, the client fails to
  execute an Update_rows_log_event).

  sql/log_event.cc@stripped, 2008-01-03 16:52:15+01:00, sven@riska.(none) +61 -2
    Added code to read events generated by mysql-5.1-wl2325-5.0-drop5 and
    ...-drop6. More precisely, the event type id's had different numbers in
    that version. To fix, we add a permutation array which maps old_id to
    new_id when the format_description_log_event indicates that the
    originating server is *-drop6 or *-drop5.

  sql/log_event.h@stripped, 2008-01-03 16:52:15+01:00, sven@riska.(none) +5 -1
    Added declaration needed in log_event.cc. Also, the destructor of
    Format_description_log_event is sometimes called when post_header_len is
    null, so we must pass the MY_ALLOW_ZERO_PTR flag to my_free.

diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc	2007-12-17 14:21:19 +01:00
+++ b/sql/log_event.cc	2008-01-03 16:52:15 +01:00
@@ -1071,6 +1071,28 @@ Log_event* Log_event::read_log_event(con
   }
   else
   {
+    /*
+      In mysql-5.1-wl2325-5.0-drop6 and -drop5 (and possibly other
+      versions), the event types were assigned different id numbers
+      than in the present version. In order to replicate from such
+      versions to the present version, we must map those event type
+      id's to our event type id's.  This is done with the
+      event_type_permutation array, which was set up when the
+      Format_description_log_event was read.
+    */
+    if (description_event->event_type_permutation)
+    {
+      IF_DBUG({
+          int new_event_type=
+            description_event->event_type_permutation[event_type];
+          DBUG_PRINT("info",
+                     ("converting event type %d to %d (%s)",
+                      event_type, new_event_type,
+                      get_type_str((Log_event_type)new_event_type)));
+        });
+      event_type= description_event->event_type_permutation[event_type];
+    }
+
     switch(event_type) {
     case QUERY_EVENT:
       ev  = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
@@ -2771,7 +2793,7 @@ int Start_log_event_v3::do_apply_event(R
 
 Format_description_log_event::
 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
-  :Start_log_event_v3()
+  :Start_log_event_v3(), event_type_permutation(0)
 {
   binlog_version= binlog_ver;
   switch (binlog_ver) {
@@ -2896,7 +2918,7 @@ Format_description_log_event(const char*
                              const
                              Format_description_log_event*
                              description_event)
-  :Start_log_event_v3(buf, description_event)
+  :Start_log_event_v3(buf, description_event), event_type_permutation(0)
 {
   DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
   buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
@@ -2911,6 +2933,43 @@ Format_description_log_event(const char*
                                       number_of_event_types*
                                       sizeof(*post_header_len), MYF(0));
   calc_server_version_split();
+
+  /*
+    In versions like 5.1.5-a_drop5p20-log, the events were given other
+    event type id numbers than in the present version. When
+    replicating from such a version, we therefore set up an array that
+    maps those id numbers to the id numbers of the present server.
+  */
+  if (strstr(server_version, "a_drop5") ||
+      strstr(server_version, "a_drop6"))
+  {
+    if (number_of_event_types != 22)
+    {
+      DBUG_PRINT("info", (" number_of_event_types=%d",
+                          number_of_event_types));
+      /* this makes is_valid() return false. */
+      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
+      post_header_len= NULL;
+      DBUG_VOID_RETURN;
+    }
+    static const uint8 perm[23]=
+      {
+        UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
+        INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
+        APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
+        NEW_LOAD_EVENT,
+        RAND_EVENT, USER_VAR_EVENT,
+        FORMAT_DESCRIPTION_EVENT,
+        TABLE_MAP_EVENT,
+        PRE_GA_WRITE_ROWS_EVENT,
+        PRE_GA_UPDATE_ROWS_EVENT,
+        PRE_GA_DELETE_ROWS_EVENT,
+        XID_EVENT,
+        BEGIN_LOAD_QUERY_EVENT,
+        EXECUTE_LOAD_QUERY_EVENT,
+      };
+    event_type_permutation= perm;
+  }
   DBUG_VOID_RETURN;
 }
 
diff -Nrup a/sql/log_event.h b/sql/log_event.h
--- a/sql/log_event.h	2007-12-14 19:01:59 +01:00
+++ b/sql/log_event.h	2008-01-03 16:52:15 +01:00
@@ -2106,12 +2106,16 @@ public:
   /* The list of post-headers' lengthes */
   uint8 *post_header_len;
   uchar server_version_split[3];
+  const uint8 *event_type_permutation;
 
   Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
   Format_description_log_event(const char* buf, uint event_len,
                                const Format_description_log_event
                                *description_event);
-  ~Format_description_log_event() { my_free((uchar*)post_header_len, MYF(0)); }
+  ~Format_description_log_event()
+  {
+    my_free((uchar*)post_header_len, MYF(MY_ALLOW_ZERO_PTR));
+  }
   Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
 #ifndef MYSQL_CLIENT
   bool write(IO_CACHE* file);
Thread
bk commit into 5.1 tree (sven:1.2658) BUG#27779Sven Sandberg3 Jan