List:Commits« Previous MessageNext Message »
From:Daogang Qu Date:June 10 2010 10:40am
Subject:Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)
Bug#50935 WL#4033
View as plain text  
Hi Zhenxing,
Thanks for these good comments. Most are applied.
Please review the updated patch:
http://lists.mysql.com/commits/110702

Best Regards,

Daogang

He Zhenxing wrote:
> Hi Daogang,
>
> Nice work! Patch looks good, please look for some comments!
>
> STATUS
> ------
> Not Approved!
>
> REQUIRED CHANGES
> -----------------
> RC1. The special comment will have a problem when there is also
> (special) comment in the original query, you could try the following,
> which will result in a syntax error:
>
> /*!50000 create /*!50000 table */ t1 (a int) */;
>
> Failed: 1064: You have an error in your SQL syntax; check the manual
> that corresponds to your MySQL server version for the right syntax to
> use near '*/' at line 1
>
> One suggestion is to output the query using '#' comment, and also use a
> BINLOG statement to ship the Rows_query_log_event so that it can be
> applied and relayed.
>
> # original query
> BINLOG '...'
>
> You may think of other alternatives.
>
> RC2. The handling of insert delayed is not correct, multiple insert
> delayed run in sequence or in parallel will result in wrong binlog.
>
> insert delayed into t1 values (1),(2);
> insert delayed into t1 values (3),(4),(5),(6)
>
> It seems that if multiple insert delayed are running in parallel the
> rows can be intermixed. So I think you need to have a logic to check if
> the new row is belong to the same query of the previous row, if it is
> not, then write a new Rows_query_log event before the new row.
>
> Please also look below for more comments.
>
>
> Dao-Gang.Qu@stripped wrote: 
>   
>> #At file:///home/daogangqu/mysql/bzrwork/wl4033_bug50935/mysql-5.1-rep%2B2/ based
> on revid:li-bing.song@stripped
>>
>>  3185 Dao-Gang.Qu@stripped	2010-05-28
>>       WL #4033 Support for informational log events
>>       Record original SQL statement in RBR binlog (Bug #50935)
>>       
>>       Adding a new ignorable 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.
>>       
>>     
>
> I'd suggest:
>
> Added ignorable event type, binary log events of this class or its
> subclasses will be silently ignored when applying by the slave SQL
> thread if it can not recognize them.
>
>   
>> Record original SQL statement in RBR binlog by ignorable log event,
>>       which can be displayed with its row event as comment by 
>>       "SHOW BINLOG EVENTS" and 'MYSQLBINLOG DUMP'. 
>>     
>
> This patch also added a rows query log event type, which is a subclass
> of the ignorable log event, to record the original query for the rows
> events in RBR. This event can be used to display the original query as
> comments by SHOW BINLOG EVENTS query, or mysqlbinlog client when the
> --verbose option is given twice.
>
> [snip]
>
>   
>> === added file 'mysql-test/suite/rpl/t/rpl_ignorable_event.test'
>> --- a/mysql-test/suite/rpl/t/rpl_ignorable_event.test	1970-01-01 00:00:00 +0000
>> +++ b/mysql-test/suite/rpl/t/rpl_ignorable_event.test	2010-05-28 10:19:04 +0000
>> @@ -0,0 +1,60 @@
>> +#
>> +# WL#4033
>> +# This test verifies if the query is displayed 
>> +# with its row event as comment in RBR by
>> +# SHOW BINLOG EVENTS.
>> +#
>>     
>
> ... if the query of the rows event is displayed by ...
>
> And please also test mysqlbinlog
>
>   
>> +
>> +source include/have_binlog_format_row.inc;
>> +source include/master-slave.inc;
>> +source include/have_innodb.inc;
>> +
>> +--echo # Test the binlog_comment_log_events is set to off by default
>> +select @@session.binlog_rows_query_log_events;
>> +set session binlog_rows_query_log_events= on;
>> +select @@session.binlog_rows_query_log_events;
>> +
>> +# Test non-transaction
>> +let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
>> +create table t1(i1 int not null auto_increment, a int, b int, primary key(i1));
>> +insert into t1(a,b) values(1,1),(2,1);
>> +update t1 set a = a + 5 where b = 1 LIMIT 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);
>> +insert delayed into t1(a,b) values(1,5);
>> +update t1 set a = a + 5 where b = 2;
>> +
>> +# Test transaction
>> +create table t2(a int, b int) engine=innodb;
>> +begin;
>> +insert into t2(a,b) values(2,1),(3,1);
>> +insert into t2(a,b) values(2,2);
>> +insert into t2(a,b) values(2,3);
>> +update t2 set a = a + 5 where b = 1;
>> +delete from t2 where a = 7;
>> +insert into t2(a,b) values(2,4);
>> +commit;
>> +
>> +# Test mixed transaction
>> +begin;
>> +insert into t1(a,b) values(1,5);
>> +insert into t1(a,b) values(1,6);
>> +insert into t2(a,b) values(2,4);
>> +insert into t2(a,b) values(2,5);
>> +insert into t1(a,b) values(1,7);
>> +insert delayed into t1(a,b) values(1,8);
>> +commit;
>> +
>> +# Test load data infile
>> +create table t3(a VARCHAR(60));
>> +load data infile '../../std_data/words.dat' into table t3;
>> +
>> +source include/show_binlog_events.inc;
>> +
>> +set session binlog_rows_query_log_events= off;
>> +
>> +drop table t1, t2, t3;
>> +sync_slave_with_master;
>> +
>>     
>
> [snip]
>
>   
>> === modified file 'sql/log.cc'
>> --- a/sql/log.cc	2010-03-17 11:31:50 +0000
>> +++ b/sql/log.cc	2010-05-28 10:19:04 +0000
>> @@ -4361,6 +4361,15 @@ int THD::binlog_write_table_map(TABLE *t
>>    DBUG_ASSERT(is_current_stmt_binlog_format_row() &&
> mysql_bin_log.is_open());
>>    DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
>>  
>> +  if (this->variables.binlog_rows_query_log_events &&
>> +      is_current_stmt_binlog_format_row() && this->query())
>> +  {
>> +    /* Write the Rows_query_log_event into binlog before the table map */
>> +    Rows_query_log_event* ev= new Rows_query_log_event(this, this->query(),
>> +                                                      
> this->query_length());
>> +    mysql_bin_log.write(ev);
>> +  }
>> +
>>    Table_map_log_event
>>      the_event(this, table, table->s->table_map_id, is_transactional);
>>  
>>
>> === modified file 'sql/log_event.cc'
>> --- a/sql/log_event.cc	2010-03-03 14:43:35 +0000
>> +++ b/sql/log_event.cc	2010-05-28 10:19:04 +0000
>> @@ -644,6 +644,8 @@ 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 IGNORABLE_LOG_EVENT: return "Ignorable";
>> +  case ROWS_QUERY_LOG_EVENT: return "Rows_query";
>>    default: return "Unknown";				/* impossible */
>>    }
>>  }
>> @@ -1294,7 +1296,19 @@ Log_event* Log_event::read_log_event(con
>>      case INCIDENT_EVENT:
>>        ev = new Incident_log_event(buf, event_len, description_event);
>>        break;
>> +    case ROWS_QUERY_LOG_EVENT:
>> +      ev= new Rows_query_log_event(buf, event_len, description_event);
>> +      break;
>>      default:
>> +      /*
>> +        Create an object of Ignorable_log_event for unrecognized sub-class.
>> +        So that SLAVE SQL THREAD can ignore the unrecognized one.
>>     
>
> so that SLAVE SQL THREAD will only update the position and continue.
>
>   
>> +      */
>> +      if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
>> +      {
>> +        ev= new Ignorable_log_event(buf, description_event);
>> +        DBUG_RETURN(ev);
>> +      }
>>        DBUG_PRINT("error",("Unknown event code: %d",
>>                            (int) buf[EVENT_TYPE_OFFSET]));
>>        ev= NULL;
>> @@ -3811,6 +3825,8 @@ 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[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
>> +      post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
>>  
>>        // Sanity-check that all post header lengths are initialized.
>>        IF_DBUG({
>> @@ -9639,6 +9655,107 @@ Incident_log_event::write_data_body(IO_C
>>  }
>>  
>>
>> +Ignorable_log_event::Ignorable_log_event(const char *buf,
>> +                                         const Format_description_log_event
> *descr_event)
>> +  : Log_event(buf, descr_event)
>> +{
>> +  DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
>> +  DBUG_VOID_RETURN;
>> +}
>> +
>> +Ignorable_log_event::~Ignorable_log_event()
>> +{
>> +}
>> +
>> +#ifndef MYSQL_CLIENT
>> +/* Pack info for its unrecognized ignorable event */
>> +void Ignorable_log_event::pack_info(Protocol *protocol)
>> +{
>> +  char buf[256];
>> +  size_t bytes;
>> +  bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized event");
>>     
>
> Unrecognized ignorable event
>
> And I'd suggest to also include the type number like this:
>
> Unrecognized ignorable event: TYPE_NUMBER
>
>   
>> +  protocol->store(buf, bytes, &my_charset_bin);
>> +}
>> +#endif
>> +
>> +#ifdef MYSQL_CLIENT
>> +/* Print for its unrecognized ignorable event */
>> +void
>> +Ignorable_log_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, "\tIgnorable\n");
>> +  my_b_printf(&cache, "# Unrecognized event\n");
>>     
>
> Unrecognized ignorable event
>
>   
>> +}
>> +#endif
>> +
>> +
>> +Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
>> +                                           const Format_description_log_event
> *descr_event)
>> +  : Ignorable_log_event(buf, descr_event)
>> +{
>> +  DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
>> +  uint8 const common_header_len=
>> +    descr_event->common_header_len;
>> +  uint8 const post_header_len=
>> +    descr_event->post_header_len[ROWS_QUERY_LOG_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);
>> +  if (!(m_rows_query= (char*) my_malloc(len+1, MYF(MY_WME))))
>> +    return;
>> +  my_snprintf(m_rows_query, len+1, "%s", str);
>> +  DBUG_PRINT("info", ("m_rows_query: %s", m_rows_query));
>> +  DBUG_VOID_RETURN;
>> +}
>> +
>> +Rows_query_log_event::~Rows_query_log_event()
>> +{
>> +  my_free(m_rows_query, MYF(0));
>> +}
>> +
>> +#ifndef MYSQL_CLIENT
>> +void Rows_query_log_event::pack_info(Protocol *protocol)
>> +{
>> +  protocol->store(m_rows_query, (uint) strlen(m_rows_query),
>> +                  &my_charset_bin);
>> +}
>> +#endif
>> +
>> +#ifdef MYSQL_CLIENT
>> +void
>> +Rows_query_log_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, "\tRows_query\n");
>> +  my_b_printf(&cache, "%s\n", m_rows_query);
>> +}
>> +#endif
>> +
>> +bool
>> +Rows_query_log_event::write_data_body(IO_CACHE *file)
>> +{
>> +  DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
>> +  DBUG_RETURN(write_str(file, m_rows_query, (uint) strlen(m_rows_query)));
>> +}
>> +
>> +
>>  #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-05-28 10:19:04 +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 IGNORABLE_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_IGNORABLE_F
>> +
>> +   Events with this flag set are ignorable on slave
>> +*/
>> +#define LOG_EVENT_IGNORABLE_F 0x80
>> +
>> +/**
>>    @def OPTIONS_WRITTEN_TO_BIN_LOG
>>  
>>    OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must
>> @@ -585,7 +593,16 @@ 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 ignorable
>> +    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.
>> +  */
>> +  IGNORABLE_LOG_EVENT= 28,
>> +  ROWS_QUERY_LOG_EVENT= 29,
>> +
>>    /*
>>      Add new events here - right above this comment!
>>      Existing events (except ENUM_END_EVENT) should never change their numbers
>> @@ -1065,6 +1082,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_ignorable_event() const { return flags & LOG_EVENT_IGNORABLE_F; }
>>    inline bool use_trans_cache() const
>>    { 
>>      return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE);
>> @@ -3994,6 +4012,93 @@ private:
>>    LEX_STRING m_message;
>>  };
>>  
>> +
>> +/**
>> +  @class Ignorable_log_event
>> +  Ignorable log event to send over ignorable 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 Ignorable_log_event : public Log_event {
>> +public:
>> +#ifndef MYSQL_CLIENT
>> +  Ignorable_log_event(THD *thd_arg) : Log_event(thd_arg, 0, FALSE)
>> +  {
>> +    DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
>> +    set_ignorable_event();
>> +    DBUG_VOID_RETURN;
>> +  }
>>     
>
> You can pass in the flag directly when calling the constructor of
> Log_event.
>
>   
>> +#endif
>> +
>> +  Ignorable_log_event(const char *buf,
>> +                      const Format_description_log_event *descr_event);
>> +
>> +  virtual ~Ignorable_log_event();
>> +
>> +#ifndef MYSQL_CLIENT
>> +  void pack_info(Protocol*);
>> +#endif
>> +
>> +#ifdef MYSQL_CLIENT
>> +  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
>> +#endif
>> +
>> +  virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; }
>> +
>> +  virtual bool is_valid() const { return 1; }
>> +
>> +  virtual int get_data_size() { return IGNORABLE_HEADER_LEN; }
>> +
>> +private:
>> +  void set_ignorable_event() { flags |= LOG_EVENT_IGNORABLE_F; }
>> +};
>> +
>> +
>> +class Rows_query_log_event : public Ignorable_log_event {
>> +public:
>> +#ifndef MYSQL_CLIENT
>> +  Rows_query_log_event(THD *thd_arg, const char * query, ulong query_len)
>> +    : Ignorable_log_event(thd_arg)
>> +  {
>> +    DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
>> +    ulong len= sizeof("/*!50600<COMMENT> ") + query_len + sizeof(";*/") +
> 1;
>>     
>
> I think we will have problem when there is comment in the original
> query.
>
>   
>> +    if (!(m_rows_query= (char*) my_malloc(len, MYF(MY_WME))))
>> +      return;
>> +    my_snprintf(m_rows_query, len, "/*!50600<COMMENT> %s;*/", query);
>> +    DBUG_PRINT("enter", ("%s", m_rows_query));
>> +    DBUG_VOID_RETURN;
>> +  }
>> +#endif
>> +
>> +#ifndef MYSQL_CLIENT
>> +  void pack_info(Protocol*);
>> +#endif
>> +
>> +  Rows_query_log_event(const char *buf, uint event_len,
>> +                     const Format_description_log_event *descr_event);
>> +
>> +  virtual ~Rows_query_log_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 ROWS_QUERY_LOG_EVENT; }
>> +
>> +  virtual int get_data_size()
>> +  {
>> +    return IGNORABLE_HEADER_LEN + 1 + (uint) strlen(m_rows_query);
>> +  }
>> +
>> +private:
>> +
>> +  char * m_rows_query;
>> +};
>> +
>> +
>> +
>>  static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
>>                                                         FILE *file)
>>  {
>>
>> === modified file 'sql/mysqld.cc'
>> --- a/sql/mysqld.cc	2010-03-03 14:43:35 +0000
>> +++ b/sql/mysqld.cc	2010-05-28 10:19:04 +0000
>> @@ -5739,7 +5739,8 @@ enum options_mysqld
>>    OPT_SYNC_RELAY_LOG_INFO,
>>    OPT_SYNC_MASTER_INFO,
>>    OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
>> -  OPT_DEFAULT_CHARACTER_SET_OLD
>> +  OPT_DEFAULT_CHARACTER_SET_OLD,
>> +  OPT_BINLOG_ROWS_QUERY_LOG_EVENT
>>  };
>>  
>>
>> @@ -7098,6 +7099,11 @@ The minimum value for this variable is 4
>>     "t_innodb; otherwise, slaves may diverge from the master.",
>>     (uchar**) &global_system_variables.binlog_direct_non_trans_update,
> (uchar**) &max_system_variables.binlog_direct_non_trans_update, 0, GET_BOOL, NO_ARG,
> 0,
>>      0, 0, 0, 0, 0},
>> +  {"binlog-rows-query-log-events", OPT_BINLOG_ROWS_QUERY_LOG_EVENT,
>> +   "Allow writing Rows_query_log events into binary log.",
>> +   (uchar**) &global_system_variables.binlog_rows_query_log_events,
>> +   (uchar**) &max_system_variables.binlog_rows_query_log_events,
>> +   0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
>>    {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
>>  };
>>  
>>
>> === modified file 'sql/set_var.cc'
>> --- a/sql/set_var.cc	2010-02-17 07:58:43 +0000
>> +++ b/sql/set_var.cc	2010-05-28 10:19:04 +0000
>> @@ -595,6 +595,9 @@ static sys_var_thd_enum	sys_query_cache_
>>  static sys_var_thd_bool
>>  sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
>>  				 &SV::query_cache_wlock_invalidate);
>> +static sys_var_thd_bool
>> +sys_binlog_rows_query_log_events(&vars, "binlog_rows_query_log_events",
>> +                                 &SV::binlog_rows_query_log_events);
>>  #endif /* HAVE_QUERY_CACHE */
>>  static sys_var_bool_ptr	sys_secure_auth(&vars, "secure_auth",
> &opt_secure_auth);
>>  static sys_var_const_str_ptr sys_secure_file_priv(&vars,
> "secure_file_priv",
>>
>> === modified file 'sql/slave.cc'
>> --- a/sql/slave.cc	2010-02-12 23:30:44 +0000
>> +++ b/sql/slave.cc	2010-05-28 10:19:04 +0000
>> @@ -2369,6 +2369,50 @@ static int exec_relay_log_event(THD* thd
>>      delete ev;
>>      DBUG_RETURN(1);
>>    }
>> +
>> +  /*
>> +     Every concrete sub-class of Ignorable_log_event will be handled
>> +     according to its logic if the SLAVE SQL THREAD can recognize it.
>> +     Else the unrecognized one is treated as an Ignorable_log_event
>> +     and is ignored after update the positions of the relay log.
>> +  */
>> +  if (ev && ev->is_ignorable_event())
>> +  {
>> +    int err_update_pos= 0;
>> +    pthread_mutex_unlock(&rli->data_lock);
>> +    switch(ev->get_type_code()) {
>> +    case IGNORABLE_LOG_EVENT:
>> +    case ROWS_QUERY_LOG_EVENT:
>> +      err_update_pos= ev->update_pos(rli);
>> +      break;
>> +    /*
>> +      TODO: Added new ignorable event and handle it 
>> +            according to the concrete class
>> +      case table_checksum_log_event:
>> +        ......
>> +      case lock_log_event:
>> +        ......
>> +    */
>> +    default:
>> +      rli->report(ERROR_LEVEL, ER_UNKNOWN_ERROR,
>> +                  "It should never be happened.");
>> +      DBUG_RETURN(1);
>> +    }
>> +    if (err_update_pos)
>> +    {
>> +      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);
>> +  }
>> +
>>     
>
> I think the logic of how to apply the ignorable event should be put in
> it's do_apply_event() method as what we do for normal events.0 
>
>   
>> if (ev)
>>    {
>>      int exec_res;
>>
>> === modified file 'sql/sql_class.h'
>> --- a/sql/sql_class.h	2010-03-17 11:31:50 +0000
>> +++ b/sql/sql_class.h	2010-05-28 10:19:04 +0000
>> @@ -412,6 +412,7 @@ struct system_variables
>>    DATE_TIME_FORMAT *datetime_format;
>>    DATE_TIME_FORMAT *time_format;
>>    my_bool sysdate_is_now;
>> +  my_bool binlog_rows_query_log_events;
>>  };
>>  
>>
>>
>> === modified file 'sql/sql_insert.cc'
>> --- a/sql/sql_insert.cc	2010-03-03 14:43:35 +0000
>> +++ b/sql/sql_insert.cc	2010-05-28 10:19:04 +0000
>> @@ -1701,7 +1701,7 @@ public:
>>    time_t start_time;
>>    ulong sql_mode;
>>    bool auto_increment_field_not_null;
>> -  bool query_start_used, ignore, log_query;
>> +  bool query_start_used, ignore, log_query, binlog_rows_query_log_events;
>>    bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
>>    ulonglong first_successful_insert_id_in_prev_stmt;
>>    ulonglong forced_insert_id;
>> @@ -1712,9 +1712,11 @@ public:
>>    Time_zone *time_zone;
>>  
>>    delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
>> -              bool ignore_arg, bool log_query_arg)
>> +              bool ignore_arg, bool log_query_arg,
>> +              bool binlog_rows_query_log_events_arg)
>>      : record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
>> -      forced_insert_id(0), query(query_arg), time_zone(0)
>> +      forced_insert_id(0), query(query_arg), time_zone(0),
>> +      binlog_rows_query_log_events(binlog_rows_query_log_events_arg)
>>      {}
>>    ~delayed_row()
>>    {
>> @@ -2191,7 +2193,8 @@ int write_delayed(THD *thd, TABLE *table
>>        goto err;
>>      query.str= str;
>>    }
>> -  row= new delayed_row(query, duplic, ignore, log_on);
>> +  row= new delayed_row(query, duplic, ignore, log_on,
>> +                       thd->variables.binlog_rows_query_log_events);
>>    if (row == NULL)
>>    {
>>      my_free(query.str, MYF(MY_WME));
>> @@ -2671,6 +2674,14 @@ bool Delayed_insert::handle_inserts(void
>>        */
>>        table->file->ha_release_auto_increment();
>>        thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty();
>> +
>> +      if (row->binlog_rows_query_log_events &&
>> +          thd.is_current_stmt_binlog_format_row())
>> +      {
>> +        /* Write the Rows_query_log_event into binlog with its row event for
> 'insert delayed ...'*/
>> +        Rows_query_log_event* ev= new Rows_query_log_event(&thd,
> row->query.str, row->query.length);
>> +        mysql_bin_log.write(ev);
>> +      }
>>      }
>>      thd.first_successful_insert_id_in_prev_stmt= 
>>        row->first_successful_insert_id_in_prev_stmt;
>>     
>
>
>
>
>   

Thread
bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185) Bug#50935 WL#4033Dao-Gang.Qu28 May
  • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033He Zhenxing4 Jun
    • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu6 Jun
    • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu7 Jun
      • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Luís Soares8 Jun
        • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu9 Jun
    • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu10 Jun
  • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Luís Soares8 Jun
    • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu10 Jun
    • Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)Bug#50935 WL#4033Daogang Qu11 Jun