MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Dao-Gang.Qu Date:April 23 2010 9:48am
Subject:bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185) WL#344
View as plain text  
#At file:///home/daogangqu/mysql/bzrwork/wl4033/mysql-5.1-rep%2B2/ based on revid:li-bing.song@stripped

 3185 Dao-Gang.Qu@stripped	2010-04-23
      WL#344 Support for informational log events
      
      Adding a new informational event, and its incremental sub-hierarchy,
      which have as default that if their type code are not recognized,
      these events are just ignored and replication keeps going as usual.
     @ mysql-test/suite/rpl/r/rpl_informational_event.result
        Test result for wl#4033.
     @ mysql-test/suite/rpl/t/rpl_informational_event.test
        Added test to verify if the  'query' informational event is
        written into binlog with its row event.
     @ sql/log.cc
        Added code to write informational event to binlog.
     @ sql/log_event.cc
        Added code to create 'information event' object for its sub-class
        so that SLAVE SQL THREAD can ignore an unrecognized informational
        event type.
     @ sql/log_event.h
        Added Informational event class to send over informational data
        to the slave.
     @ sql/slave.cc
        Added code to ignore the informational event after
        update the positions of the relay log.
     @ sql/sql_class.cc
        Added code to write the 'query' information even into binlog
        with its row event.

    added:
      mysql-test/suite/rpl/r/rpl_informational_event.result
      mysql-test/suite/rpl/t/rpl_informational_event.test
    modified:
      sql/log.cc
      sql/log.h
      sql/log_event.cc
      sql/log_event.h
      sql/slave.cc
      sql/sql_class.cc
=== added file 'mysql-test/suite/rpl/r/rpl_informational_event.result'
--- a/mysql-test/suite/rpl/r/rpl_informational_event.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_informational_event.result	2010-04-23 09:47:52 +0000
@@ -0,0 +1,48 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(a int, b int);
+insert into t1(a,b) values(1,1),(2,1),(3,1);
+update t1 set a = a + 5 where b = 1;
+delete from t1 where a = 6;
+insert into t1(a,b) values(1,2);
+insert into t1(a,b) values(1,3);
+insert into t1(a,b) values(1,4);
+SHOW BINLOG EVENTS;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	108	Server ver: 5.1.46-debug-log, Binlog ver: 4
+master-bin.000001	108	Query	1	200	use `test`; create table t1(a int, b int)
+master-bin.000001	200	Information	1	263	#insert into t1(a,b) values(1,1),(2,1),(3,1)
+master-bin.000001	263	Query	1	331	BEGIN
+master-bin.000001	331	Table_map	1	373	table_id: 23 (test.t1)
+master-bin.000001	373	Write_rows	1	429	table_id: 23 flags: STMT_END_F
+master-bin.000001	429	Query	1	498	COMMIT
+master-bin.000001	498	Information	1	553	#update t1 set a = a + 5 where b = 1
+master-bin.000001	553	Query	1	621	BEGIN
+master-bin.000001	621	Table_map	1	663	table_id: 23 (test.t1)
+master-bin.000001	663	Update_rows	1	747	table_id: 23 flags: STMT_END_F
+master-bin.000001	747	Query	1	816	COMMIT
+master-bin.000001	816	Information	1	862	#delete from t1 where a = 6
+master-bin.000001	862	Query	1	930	BEGIN
+master-bin.000001	930	Table_map	1	972	table_id: 23 (test.t1)
+master-bin.000001	972	Delete_rows	1	1010	table_id: 23 flags: STMT_END_F
+master-bin.000001	1010	Query	1	1079	COMMIT
+master-bin.000001	1079	Information	1	1130	#insert into t1(a,b) values(1,2)
+master-bin.000001	1130	Query	1	1198	BEGIN
+master-bin.000001	1198	Table_map	1	1240	table_id: 23 (test.t1)
+master-bin.000001	1240	Write_rows	1	1278	table_id: 23 flags: STMT_END_F
+master-bin.000001	1278	Query	1	1347	COMMIT
+master-bin.000001	1347	Information	1	1398	#insert into t1(a,b) values(1,3)
+master-bin.000001	1398	Query	1	1466	BEGIN
+master-bin.000001	1466	Table_map	1	1508	table_id: 23 (test.t1)
+master-bin.000001	1508	Write_rows	1	1546	table_id: 23 flags: STMT_END_F
+master-bin.000001	1546	Query	1	1615	COMMIT
+master-bin.000001	1615	Information	1	1666	#insert into t1(a,b) values(1,4)
+master-bin.000001	1666	Query	1	1734	BEGIN
+master-bin.000001	1734	Table_map	1	1776	table_id: 23 (test.t1)
+master-bin.000001	1776	Write_rows	1	1814	table_id: 23 flags: STMT_END_F
+master-bin.000001	1814	Query	1	1883	COMMIT
+DROP TABLE t1;

=== added file 'mysql-test/suite/rpl/t/rpl_informational_event.test'
--- a/mysql-test/suite/rpl/t/rpl_informational_event.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_informational_event.test	2010-04-23 09:47:52 +0000
@@ -0,0 +1,16 @@
+source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
+
+create table t1(a int, b int);
+
+insert into t1(a,b) values(1,1),(2,1),(3,1);
+update t1 set a = a + 5 where b = 1;
+delete from t1 where a = 6;
+insert into t1(a,b) values(1,2);
+insert into t1(a,b) values(1,3);
+insert into t1(a,b) values(1,4);
+SHOW BINLOG EVENTS;
+
+DROP TABLE t1;
+sync_slave_with_master;
+

=== modified file 'sql/log.cc'
--- a/sql/log.cc	2010-03-17 11:31:50 +0000
+++ b/sql/log.cc	2010-04-23 09:47:52 +0000
@@ -5031,6 +5031,26 @@ bool MYSQL_BIN_LOG::write_incident(THD *
   DBUG_RETURN(error);
 }
 
+bool MYSQL_BIN_LOG::write_information(THD *thd, LEX_STRING const write_msg, bool lock)
+{
+  uint error= 0;
+  DBUG_ENTER("MYSQL_BIN_LOG::write_information");
+  Informational_event ev(thd, write_msg);
+  if (lock)
+    pthread_mutex_lock(&LOCK_log);
+  error= ev.write(&log_file);
+  if (lock)
+  {
+    if (!error && !(error= flush_and_sync(0)))
+    {
+      signal_update();
+      rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+    }
+    pthread_mutex_unlock(&LOCK_log);
+  }
+  DBUG_RETURN(error);
+}
+
 /**
   Write a cached log entry to the binary log.
   - To support transaction over replication, we wrap the transaction

=== modified file 'sql/log.h'
--- a/sql/log.h	2010-02-13 09:42:41 +0000
+++ b/sql/log.h	2010-04-23 09:47:52 +0000
@@ -395,6 +395,7 @@ public:
   bool write(Log_event* event_info);
   bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event, bool incident);
   bool write_incident(THD *thd, bool lock);
+  bool write_information(THD *thd, LEX_STRING write_msg, bool lock);
 
   int  write_cache(IO_CACHE *cache, bool lock_log, bool flush_and_sync);
   void set_write_error(THD *thd);

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-03-03 14:43:35 +0000
+++ b/sql/log_event.cc	2010-04-23 09:47:52 +0000
@@ -644,6 +644,7 @@ const char* Log_event::get_type_str(Log_
   case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
   case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
   case INCIDENT_EVENT: return "Incident";
+  case INFORMATIONAL_EVENT: return "Information";
   default: return "Unknown";				/* impossible */
   }
 }
@@ -1172,6 +1173,17 @@ Log_event* Log_event::read_log_event(con
     DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
   }
 
+  /*
+    Create 'information event' object for its sub-class so that
+    SLAVE SQL THREAD can ignore an unrecognized informational
+    event type
+  */
+  if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_INFORMATIONAL_F)
+  {
+    ev= new Informational_event(buf, event_len, description_event);
+    DBUG_RETURN(ev);
+  }
+
   uint event_type= buf[EVENT_TYPE_OFFSET];
   if (event_type > description_event->number_of_event_types &&
       event_type != FORMAT_DESCRIPTION_EVENT)
@@ -3811,6 +3823,7 @@ Format_description_log_event(uint8 binlo
                       post_header_len[DELETE_ROWS_EVENT-1]= 6;);
       post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
       post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
+      post_header_len[INFORMATIONAL_EVENT-1]= INFORMATIONAL_HEADER_LEN;
 
       // Sanity-check that all post header lengths are initialized.
       IF_DBUG({
@@ -9639,6 +9652,67 @@ Incident_log_event::write_data_body(IO_C
 }
 
 
+Informational_event::Informational_event(const char *buf, uint event_len,
+                                       const Format_description_log_event *descr_event)
+  : Log_event(buf, descr_event)
+{
+  DBUG_ENTER("Informational_event::Informational_event");
+  uint8 const common_header_len=
+    descr_event->common_header_len;
+  uint8 const post_header_len=
+    descr_event->post_header_len[INFORMATIONAL_EVENT-1];
+
+  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
+                     event_len, common_header_len, post_header_len));
+
+  char const *ptr= buf + common_header_len + post_header_len;
+  char const *const str_end= buf + event_len;
+  uint8 len= 0;                   // Assignment to keep compiler happy
+  const char *str= NULL;          // Assignment to keep compiler happy
+  read_str(&ptr, str_end, &str, &len);
+  m_message.str= const_cast<char*>(str);
+  m_message.length= len;
+  DBUG_PRINT("info", ("m_message: %s", m_message.str));
+  DBUG_VOID_RETURN;
+}
+
+Informational_event::~Informational_event()
+{
+}
+
+#ifndef MYSQL_CLIENT
+void Informational_event::pack_info(Protocol *protocol)
+{
+  char buf[256];
+  size_t bytes;
+  bytes= my_snprintf(buf, sizeof(buf), "#%s", m_message.str);
+  protocol->store(buf, bytes, &my_charset_bin);
+}
+#endif
+
+#ifdef MYSQL_CLIENT
+void
+Informational_event::print(FILE *file,
+                          PRINT_EVENT_INFO *print_event_info)
+{
+  if (print_event_info->short_form)
+    return;
+
+  Write_on_release_cache cache(&print_event_info->head_cache, file);
+  print_header(&cache, print_event_info, FALSE);
+  my_b_printf(&cache, "\tInformation\n");
+  my_b_printf(&cache, "# m_message: %s\n", m_message.str);
+}
+#endif
+
+bool
+Informational_event::write_data_body(IO_CACHE *file)
+{
+  DBUG_ENTER("Informational_event::write_data_body");
+  DBUG_RETURN(write_str(file, m_message.str, (uint) m_message.length));
+}
+
+
 #ifdef MYSQL_CLIENT
 /**
   The default values for these variables should be values that are

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2010-02-14 01:14:36 +0000
+++ b/sql/log_event.h	2010-04-23 09:47:52 +0000
@@ -251,6 +251,7 @@ struct sql_ex_info
 #define EXECUTE_LOAD_QUERY_HEADER_LEN  (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
 #define INCIDENT_HEADER_LEN    2
 #define HEARTBEAT_HEADER_LEN   0
+#define INFORMATIONAL_HEADER_LEN 0
 /* 
   Max number of possible extra bytes in a replication event compared to a
   packet (i.e. a query) sent from client to master;
@@ -489,6 +490,13 @@ struct sql_ex_info
 #define LOG_EVENT_RELAY_LOG_F 0x40
 
 /**
+   @def LOG_EVENT_INFORMATIONAL_F
+
+   Events with this flag set are ignorable on slave
+*/
+#define LOG_EVENT_INFORMATIONAL_F 0x80
+
+/**
   @def OPTIONS_WRITTEN_TO_BIN_LOG
 
   OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must
@@ -585,7 +593,15 @@ enum Log_event_type
     to ensure master's online status to slave 
   */
   HEARTBEAT_LOG_EVENT= 27,
-  
+
+  /*
+    In some situations, it is necessary to send over informational
+    data to the slave: data that a slave can handle in case there
+    is code for handling it, but which can be ignored if it is not
+    recognized.
+  */
+  INFORMATIONAL_EVENT= 28,
+
   /*
     Add new events here - right above this comment!
     Existing events (except ENUM_END_EVENT) should never change their numbers
@@ -1065,6 +1081,7 @@ public:
   void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
   bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
   bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
+  bool is_informational_event() const { return flags & LOG_EVENT_INFORMATIONAL_F; }
   inline bool use_trans_cache() const
   { 
     return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE);
@@ -3994,6 +4011,59 @@ private:
   LEX_STRING m_message;
 };
 
+
+/**
+  @class Informational_event
+  Informational event to send over informational data to the slave,
+  and its incremental sub-hierarchy, which have as default that if
+  their type code are not recognized, these events are just ignored
+  and replication keeps going as usual.
+**/
+class Informational_event : public Log_event {
+public:
+#ifndef MYSQL_CLIENT
+  Informational_event(THD *thd_arg, LEX_STRING const msg)
+    : Log_event(thd_arg, 0, FALSE)
+  {
+    DBUG_ENTER("Informational_event::Informational_event");
+    DBUG_PRINT("enter", ("m_message: %s", msg.str));
+    m_message= msg;
+    set_informational_event();
+    DBUG_VOID_RETURN;
+  }
+#endif
+
+#ifndef MYSQL_CLIENT
+  void pack_info(Protocol*);
+#endif
+
+  Informational_event(const char *buf, uint event_len,
+                     const Format_description_log_event *descr_event);
+
+  virtual ~Informational_event();
+
+#ifdef MYSQL_CLIENT
+  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+  virtual bool write_data_body(IO_CACHE *file);
+
+  virtual Log_event_type get_type_code() { return INFORMATIONAL_EVENT; }
+
+  virtual bool is_valid() const { return 1; }
+
+  virtual int get_data_size() {
+    return INFORMATIONAL_HEADER_LEN + 1 + (uint) m_message.length;
+  }
+
+private:
+  /* Set flags as ignorable for informational event*/
+  void set_informational_event() { flags |= LOG_EVENT_INFORMATIONAL_F; }
+
+  LEX_STRING m_message;
+};
+
+
 static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
                                                        FILE *file)
 {

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2010-02-12 23:30:44 +0000
+++ b/sql/slave.cc	2010-04-23 09:47:52 +0000
@@ -2369,6 +2369,31 @@ static int exec_relay_log_event(THD* thd
     delete ev;
     DBUG_RETURN(1);
   }
+
+  /*
+     Ignore the informational event after update
+     the positions of the relay log.
+  */
+  if (ev && ev->is_informational_event())
+  {
+    pthread_mutex_unlock(&rli->data_lock);
+    int error= ev->update_pos(rli);
+    delete ev;
+    if (error)
+    {
+      char buf[22];
+      rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
+                  "It was not possible to update the positions"
+                  " of the relay log information: the slave may"
+                  " be in an inconsistent state."
+                  " Stopped in %s position %s",
+                  rli->group_relay_log_name,
+                  llstr(rli->group_relay_log_pos, buf));
+      DBUG_RETURN(1);
+    }
+    DBUG_RETURN(0);
+  }
+
   if (ev)
   {
     int exec_res;

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-03-03 14:43:35 +0000
+++ b/sql/sql_class.cc	2010-04-23 09:47:52 +0000
@@ -4359,7 +4359,11 @@ int THD::binlog_query(THD::enum_binlog_q
                ("is_current_stmt_binlog_format_row: %d",
                 is_current_stmt_binlog_format_row()));
     if (is_current_stmt_binlog_format_row())
-      DBUG_RETURN(0);
+    {
+      /* Write the 'query' information even into binlog with its row event */
+      LEX_STRING const query_msg= { const_cast<char*>(query_arg), query_len };
+      DBUG_RETURN(mysql_bin_log.write_information(this, query_msg, TRUE));
+    }
     /* Fall through */
 
     /*


Attachment: [text/bzr-bundle] bzr/dao-gang.qu@sun.com-20100423094752-om53admuwnyzr2x3.bundle
Thread
bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185) WL#344Dao-Gang.Qu23 Apr
  • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185) WL#344Kristian Nielsen23 Apr