List:Commits« Previous MessageNext Message »
From:Sven Sandberg Date:January 9 2008 10:34am
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-09 11:34:39+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-drop6p13-alpha,
  mysql-5.1-wl2325-5.0-drop6, mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd.
   (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-09 11:34:37+01:00, sven@riska.(none) +84 -2
    Added code to read events generated by
    mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6,
    mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd.
    More precisely, the event type id's had different numbers in
    those versions. 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 of the old type. We also need to permute the
    post_header_len array accordingly.

  sql/log_event.h@stripped, 2008-01-09 11:34:37+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-09 11:34:37 +01:00
@@ -1071,6 +1071,29 @@ Log_event* Log_event::read_log_event(con
   }
   else
   {
+    /*
+      In some previuos versions (see comment in
+      Format_description_log_event::Format_description_log_event(char*,...)),
+      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.  The mapping 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 +2794,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 +2919,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 +2934,65 @@ Format_description_log_event(const char*
                                       number_of_event_types*
                                       sizeof(*post_header_len), MYF(0));
   calc_server_version_split();
+
+  /*
+    In some previous versions, 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 post_header_len is null, it means malloc failed, and is_valid
+    will fail, so there is no need to do anything.
+
+    The trees which have wrong event id's are:
+    mysql-5.1-wl2325-5.0-drop6p13-alpha, mysql-5.1-wl2325-5.0-drop6,
+    mysql-5.1-wl2325-5.0, mysql-5.1-wl2325-no-dd (`grep -C2
+    BEGIN_LOAD_QUERY_EVENT /home/bk/ * /sql/log_event.h`). The
+    corresponding version (`grep mysql, configure.in` in those trees)
+    strings are 5.2.2-a_drop6p13-alpha, 5.2.2-a_drop6p13c,
+    5.1.5-a_drop5p20, 5.1.2-a_drop5p5.
+  */
+  if (post_header_len &&
+      (strncmp(server_version, "5.1.2-a_drop5", 13) == 0 ||
+       strncmp(server_version, "5.1.5-a_drop5", 13) == 0 ||
+       strncmp(server_version, "5.2.2-a_drop6", 13) == 0))
+  {
+    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;
+    /*
+      Since we use (permuted) event id's to index the post_header_len
+      array, we need to permute the post_header_len array too.
+    */
+    uint8 post_header_len_temp[23];
+    for (int i= 0; i < 23; i++)
+      post_header_len_temp[perm[i]]= post_header_len[i];
+    for (int i= 0; i < 23; i++)
+      post_header_len[i] = post_header_len_temp[i];
+  }
   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-09 11:34:37 +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 Sandberg9 Jan
  • Re: bk commit into 5.1 tree (sven:1.2658) BUG#27779He Zhenxing10 Jan