List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:March 9 2012 3:26pm
Subject:bzr push into mysql-trunk branch (frazer.clement:3744 to 3745) Bug#54854
View as plain text  
 3745 Frazer Clement	2012-03-09
      Bug#54854 Can't find good position for replication break between DDL statements
      
      Commit of mysql-trunk patches for PB2 test-build

    modified:
      sql/binlog.cc
      sql/binlog.h
      sql/log.h
      sql/log_event.h
      sql/rpl_injector.cc
      sql/rpl_injector.h
      sql/sql_class.cc
      sql/sql_class.h
 3744 Jorgen Loland	2012-03-09
      Bug#13810145: FIX WARNINGS BY FORTIFY
     @ sql/opt_range.cc
        Fix Fortify warning

    modified:
      sql/opt_range.cc
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2012-03-06 14:29:42 +0000
+++ b/sql/binlog.cc	2012-03-09 15:24:52 +0000
@@ -4160,6 +4160,19 @@ MYSQL_BIN_LOG::remove_pending_rows_event
 }
 
 /*
+  Updates thd's position-of-next-event variables
+  after a *real* write a file.
+ */
+void MYSQL_BIN_LOG::update_thd_next_event_pos(THD* thd)
+{
+  if (likely(thd != NULL))
+  {
+    thd->set_next_event_pos(log_file_name,
+                            my_b_tell(&log_file));
+  }
+}
+
+/*
   Moves the last bunch of rows from the pending Rows event to a cache (either
   transactional cache if is_transaction is @c true, or the non-transactional
   cache otherwise. Sets a new pending event.
@@ -4924,12 +4937,14 @@ bool MYSQL_BIN_LOG::write_cache(THD *thd
       mysql_mutex_lock(&LOCK_prep_xids);
       prepared_xids++;
       mysql_mutex_unlock(&LOCK_prep_xids);
+      update_thd_next_event_pos(thd);
       mysql_mutex_unlock(&LOCK_log);
     }
     else
     {
       if (rotate(false, &check_purge))
         goto err;
+      update_thd_next_event_pos(thd);
       mysql_mutex_unlock(&LOCK_log);
       if (check_purge) 
         purge();

=== modified file 'sql/binlog.h'
--- a/sql/binlog.h	2012-01-26 10:53:34 +0000
+++ b/sql/binlog.h	2012-03-09 15:24:52 +0000
@@ -213,6 +213,7 @@ public:
   int recover(IO_CACHE *log, Format_description_log_event *fdle);
 #if !defined(MYSQL_CLIENT)
 
+  void update_thd_next_event_pos(THD *thd);
   int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event,
                                        bool is_transactional);
   int remove_pending_rows_event(THD *thd, bool is_transactional);

=== modified file 'sql/log.h'
--- a/sql/log.h	2011-12-09 21:08:37 +0000
+++ b/sql/log.h	2012-03-09 15:24:52 +0000
@@ -19,6 +19,21 @@
 #include "unireg.h"                    // REQUIRED: for other includes
 #include "handler.h"                            /* my_xid */
 
+/**
+  the struct aggregates two paramenters that identify an event
+  uniquely in scope of communication of a particular master and slave couple.
+  I.e there can not be 2 events from the same staying connected master which
+  have the same coordinates.
+  @note
+  Such identifier is not yet unique generally as the event originating master
+  is resetable. Also the crashed master can be replaced with some other.
+*/
+typedef struct event_coordinates
+{
+  char * file_name; // binlog file name (directories stripped)
+  my_off_t  pos;       // event's position in the binlog file
+} LOG_POS_COORD;
+
 /*
   Transaction Coordinator log - a base abstract class
   for two different implementations

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2012-03-06 14:29:42 +0000
+++ b/sql/log_event.h	2012-03-09 15:24:52 +0000
@@ -812,21 +812,6 @@ typedef struct st_print_event_info
 #endif
 
 /**
-  the struct aggregates two paramenters that identify an event
-  uniquely in scope of communication of a particular master and slave couple.
-  I.e there can not be 2 events from the same staying connected master which
-  have the same coordinates.
-  @note
-  Such identifier is not yet unique generally as the event originating master
-  is resetable. Also the crashed master can be replaced with some other.
-*/
-typedef struct event_coordinates
-{
-  char * file_name; // binlog file name (directories stripped)
-  my_off_t  pos;       // event's position in the binlog file
-} LOG_POS_COORD;
-
-/**
   @class Log_event
 
   This is the abstract base class for binary log events.

=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc	2012-03-06 14:29:42 +0000
+++ b/sql/rpl_injector.cc	2012-03-09 15:24:52 +0000
@@ -41,6 +41,28 @@ injector::transaction::transaction(MYSQL
   m_start_pos.m_file_name= my_strdup(log_info.log_file_name, MYF(0));
   m_start_pos.m_file_pos= log_info.pos;
 
+  if (unlikely(m_start_pos.m_file_name == NULL))
+  {
+    m_thd= NULL;
+    return;
+  }
+
+  /*
+     Next pos is unknown until after commit of the Binlog transaction
+  */
+  m_next_pos.m_file_name= 0;
+  m_next_pos.m_file_pos= 0;
+
+  /*
+    Ensure we don't pick up this thd's last written Binlog pos in
+    empty-transaction-commit cases.
+    This is not ideal, as it zaps this information for any other
+    usage (e.g. WL4047)
+    Potential improvement : save the 'old' next pos prior to
+    commit, and restore on error.
+  */
+  m_thd->clear_next_event_pos();
+
   trans_begin(m_thd);
 }
 
@@ -50,16 +72,18 @@ injector::transaction::~transaction()
     return;
 
   /* Needed since my_free expects a 'char*' (instead of 'void*'). */
-  char* const the_memory= const_cast<char*>(m_start_pos.m_file_name);
+  char* const start_pos_memory= const_cast<char*>(m_start_pos.m_file_name);
 
-  /*
-    We set the first character to null just to give all the copies of the
-    start position a (minimal) chance of seening that the memory is lost.
-    All assuming the my_free does not step over the memory, of course.
-  */
-  *the_memory= '\0';
-
-  my_free(the_memory);
+  if (start_pos_memory)
+  {
+    my_free(start_pos_memory);
+  }
+
+  char* const next_pos_memory= const_cast<char*>(m_next_pos.m_file_name);
+  if (next_pos_memory)
+  {
+    my_free(next_pos_memory);
+  }
 }
 
 /**
@@ -95,6 +119,22 @@ int injector::transaction::commit()
      close_thread_tables(m_thd);
      m_thd->mdl_context.release_transactional_locks();
    }
+
+   /* Copy next position out into our next pos member */
+   if ((error == 0) &&
+       (m_thd->binlog_next_event_pos.file_name != NULL) &&
+       ((m_next_pos.m_file_name=
+         my_strdup(m_thd->binlog_next_event_pos.file_name, MYF(0))) != NULL))
+   {
+     m_next_pos.m_file_pos= m_thd->binlog_next_event_pos.pos;
+   }
+   else
+   {
+     /* Error, problem copying etc. */
+     m_next_pos.m_file_name= NULL;
+     m_next_pos.m_file_pos= 0;
+   }
+
    DBUG_RETURN(error);
 }
 
@@ -199,6 +239,10 @@ injector::transaction::binlog_pos inject
    return m_start_pos;			
 }
 
+injector::transaction::binlog_pos injector::transaction::next_pos() const
+{
+   return m_next_pos;
+}
 
 /*
   injector - member definitions

=== modified file 'sql/rpl_injector.h'
--- a/sql/rpl_injector.h	2011-09-28 09:12:47 +0000
+++ b/sql/rpl_injector.h	2012-03-09 15:24:52 +0000
@@ -241,14 +241,30 @@ public:
       /*
         Get the position for the start of the transaction.
 
-        Returns the position in the binary log of the first event in this
-        transaction. If no event is yet written, the position where the event
-        *will* be written is returned. This position is known, since a
-        new_transaction() will lock the binary log and prevent any other
-        writes to the binary log.
+        This is the current 'tail of Binlog' at the time the transaction
+        was started.  The first event recorded by the transaction may
+        be at this, or some subsequent position.  The first event recorded
+        by the transaction will not be before this position.
       */
       binlog_pos start_pos() const;
 
+      /*
+        Get the next position after the end of the transaction
+
+        This call is only valid after a transaction has been committed.
+        It returns the next Binlog position after the committed transaction.
+        It is guaranteed that no other events will be recorded between the
+        COMMIT event of the Binlog transaction, and this position.
+        Note that this position may be in a different log file to the COMMIT
+        event.
+
+        If the commit had an error, or the transaction was empty and nothing
+        was binlogged then the next_pos will have a NULL file_name(), and
+        0 file_pos().
+
+      */
+      binlog_pos next_pos() const;
+
     private:
       /* Only the injector may construct these object */
       transaction(MYSQL_BIN_LOG *, THD *);
@@ -261,6 +277,13 @@ public:
           o.m_start_pos= tmp;
         }
 
+        /* std::swap(m_end_pos, o.m_end_pos); */
+        {
+          binlog_pos const tmp= m_next_pos;
+          m_next_pos= o.m_next_pos;
+          o.m_next_pos= tmp;
+        }
+
         /* std::swap(m_thd, o.m_thd); */
         {
           THD* const tmp= m_thd;
@@ -333,6 +356,7 @@ public:
 
 
       binlog_pos m_start_pos;
+      binlog_pos m_next_pos;
       THD *m_thd;
     };
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2012-03-06 14:29:42 +0000
+++ b/sql/sql_class.cc	2012-03-09 15:24:52 +0000
@@ -930,6 +930,9 @@ THD::THD(bool enable_plugins)
   m_binlog_invoker= FALSE;
   memset(&invoker_user, 0, sizeof(invoker_user));
   memset(&invoker_host, 0, sizeof(invoker_host));
+
+  binlog_next_event_pos.file_name= NULL;
+  binlog_next_event_pos.pos= 0;
 }
 
 
@@ -1418,6 +1421,8 @@ THD::~THD()
   if (m_enable_plugins)
     plugin_thdvar_cleanup(this);
 
+  clear_next_event_pos();
+
   DBUG_PRINT("info", ("freeing security context"));
   main_security_ctx.destroy();
   my_free(db);
@@ -4538,3 +4543,30 @@ void COPY_INFO::set_function_defaults(TA
     }
   DBUG_VOID_RETURN;
 }
+
+void THD::set_next_event_pos(const char* _filename, ulonglong _pos)
+{
+  char*& filename= binlog_next_event_pos.file_name;
+  if (filename == NULL)
+  {
+    /* First time, allocate maximal buffer */
+    filename= (char*) my_malloc(FN_REFLEN+1, MYF(MY_WME));
+    if (filename == NULL) return;
+  }
+
+  assert(strlen(_filename) <= FN_REFLEN);
+  strcpy(filename, _filename);
+  filename[ FN_REFLEN ]= 0;
+
+  binlog_next_event_pos.pos= _pos;
+};
+
+void THD::clear_next_event_pos()
+{
+  if (binlog_next_event_pos.file_name != NULL)
+  {
+    my_free(binlog_next_event_pos.file_name);
+  }
+  binlog_next_event_pos.file_name= NULL;
+  binlog_next_event_pos.pos= 0;
+};

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-03-06 14:29:42 +0000
+++ b/sql/sql_class.h	2012-03-09 15:24:52 +0000
@@ -2348,6 +2348,15 @@ public:
   /* container for handler's private per-connection data */
   Ha_data ha_data[MAX_HA];
 
+  /*
+    Position of first event in Binlog
+    *after* last event written by this
+    thread.
+  */
+  event_coordinates binlog_next_event_pos;
+  void set_next_event_pos(const char* _filename, ulonglong _pos);
+  void clear_next_event_pos();
+
 #ifndef MYSQL_CLIENT
   int binlog_setup_trx_data();
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (frazer.clement:3744 to 3745) Bug#54854Frazer Clement12 Mar