List:Commits« Previous MessageNext Message »
From:Luis Soares Date:October 7 2010 9:55am
Subject:bzr commit into mysql-5.5-bugteam branch (luis.soares:3215)
View as plain text  
#At file:///home/lsoares/Workspace/bzr/work/bugfixing/push/mysql-5.5-bugteam/ based on revid:magnus.blaudd@stripped

 3215 Luis Soares	2010-10-07 [merge]
      Automerge from mysql-5.1-bugteam.

    modified:
      sql/log_event.cc
      sql/log_event.h
      sql/rpl_rli.h
      sql/slave.cc
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-08-23 22:31:12 +0000
+++ b/sql/log_event.cc	2010-10-07 09:54:56 +0000
@@ -1239,7 +1239,7 @@ Log_event* Log_event::read_log_event(con
       break;
 #ifdef HAVE_REPLICATION
     case SLAVE_EVENT: /* can never happen (unused event) */
-      ev = new Slave_log_event(buf, event_len);
+      ev = new Slave_log_event(buf, event_len, description_event);
       break;
 #endif /* HAVE_REPLICATION */
     case CREATE_FILE_EVENT:
@@ -1327,8 +1327,10 @@ Log_event* Log_event::read_log_event(con
     (because constructor is "void") ; so instead we leave the pointer we
     wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
     Same for Format_description_log_event, member 'post_header_len'.
+
+    SLAVE_EVENT is never used, so it should not be read ever.
   */
-  if (!ev || !ev->is_valid())
+  if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
   {
     DBUG_PRINT("error",("Found invalid event in binary log"));
 
@@ -6112,8 +6114,12 @@ void Slave_log_event::init_from_mem_pool
 
 
 /** This code is not used, so has not been updated to be format-tolerant. */
-Slave_log_event::Slave_log_event(const char* buf, uint event_len)
-  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
+/* We are using description_event so that slave does not crash on Log_event
+  constructor */
+Slave_log_event::Slave_log_event(const char* buf, 
+                                 uint event_len,
+                                 const Format_description_log_event* description_event)
+  :Log_event(buf,description_event),mem_pool(0),master_host(0)
 {
   if (event_len < LOG_EVENT_HEADER_LEN)
     return;

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2010-07-15 13:47:50 +0000
+++ b/sql/log_event.h	2010-10-07 09:54:56 +0000
@@ -1846,7 +1846,9 @@ public:
   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
 #endif
 
-  Slave_log_event(const char* buf, uint event_len);
+  Slave_log_event(const char* buf,
+                  uint event_len,
+                  const Format_description_log_event *description_event);
   ~Slave_log_event();
   int get_data_size();
   bool is_valid() const { return master_host != 0; }

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2010-03-31 14:05:33 +0000
+++ b/sql/rpl_rli.h	2010-10-07 09:54:56 +0000
@@ -97,6 +97,16 @@ public:
   */
   MYSQL_BIN_LOG relay_log;
   LOG_INFO linfo;
+
+  /*
+   cur_log
+     Pointer that either points at relay_log.get_log_file() or
+     &rli->cache_buf, depending on whether the log is hot or there was
+     the need to open a cold relay_log.
+
+   cache_buf 
+     IO_CACHE used when opening cold relay logs.
+   */
   IO_CACHE cache_buf,*cur_log;
 
   /*

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2010-07-29 12:32:11 +0000
+++ b/sql/slave.cc	2010-10-07 09:54:56 +0000
@@ -4727,12 +4727,66 @@ static Log_event* next_event(Relay_log_i
         DBUG_ASSERT(rli->cur_log_fd == -1);
 
         /*
-          Read pointer has to be at the start since we are the only
-          reader.
-          We must keep the LOCK_log to read the 4 first bytes, as this is a hot
-          log (same as when we call read_log_event() above: for a hot log we
-          take the mutex).
+           When the SQL thread is [stopped and] (re)started the
+           following may happen:
+
+           1. Log was hot at stop time and remains hot at restart
+
+              SQL thread reads again from hot_log (SQL thread was
+              reading from the active log when it was stopped and the
+              very same log is still active on SQL thread restart).
+
+              In this case, my_b_seek is performed on cur_log, while
+              cur_log points to relay_log.get_log_file();
+
+           2. Log was hot at stop time but got cold before restart
+
+              The log was hot when SQL thread stopped, but it is not
+              anymore when the SQL thread restarts.
+
+              In this case, the SQL thread reopens the log, using
+              cache_buf, ie, cur_log points to &cache_buf, and thence
+              its coordinates are reset.
+
+           3. Log was already cold at stop time
+
+              The log was not hot when the SQL thread stopped, and, of
+              course, it will not be hot when it restarts.
+
+              In this case, the SQL thread opens the cold log again,
+              using cache_buf, ie, cur_log points to &cache_buf, and
+              thence its coordinates are reset.
+
+           4. Log was hot at stop time, DBA changes to previous cold
+              log and restarts SQL thread
+
+              The log was hot when the SQL thread was stopped, but the
+              user changed the coordinates of the SQL thread to
+              restart from a previous cold log.
+
+              In this case, at start time, cur_log points to a cold
+              log, opened using &cache_buf as cache, and coordinates
+              are reset. However, as it moves on to the next logs, it
+              will eventually reach the hot log. If the hot log is the
+              same at the time the SQL thread was stopped, then
+              coordinates were not reset - the cur_log will point to
+              relay_log.get_log_file(), and not a freshly opened
+              IO_CACHE through cache_buf. For this reason we need to
+              deploy a my_b_seek before calling check_binlog_magic at
+              this point of the code (see: BUG#55263 for more
+              details).
+          
+          NOTES: 
+            - We must keep the LOCK_log to read the 4 first bytes, as
+              this is a hot log (same as when we call read_log_event()
+              above: for a hot log we take the mutex).
+
+            - Because of scenario #4 above, we need to have a
+              my_b_seek here. Otherwise, we might hit the assertion
+              inside check_binlog_magic.
         */
+
+        my_b_seek(cur_log, (my_off_t) 0);
         if (check_binlog_magic(cur_log,&errmsg))
         {
           if (!hot_log)


Attachment: [text/bzr-bundle] bzr/luis.soares@oracle.com-20101007095456-msopu5n73avi2cui.bundle
Thread
bzr commit into mysql-5.5-bugteam branch (luis.soares:3215) Luis Soares7 Oct