List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:June 4 2010 5:09am
Subject:Re: bzr commit into mysql-5.1-rep+2 branch (Dao-Gang.Qu:3185)
Bug#50935 WL#4033
View as plain text  
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