List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:March 12 2009 4:48am
Subject:Re: bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719
View as plain text  
Leonard zhou wrote:
> He Zhenxing 写道:
> > Hi Leonard,
> > 
> > Leonard Zhou wrote:
> >> #At file:///home/zhl/mysql/rep/5.0/bug41719/
> >>
> >>  2767 Leonard Zhou	2009-03-05
> >>       BUG#41719 delayed INSERT into timestamp col needs set time_zone for
> concurrent binlogging
> >>       
> >>       When do 'insert delayed' operation, the time_zone info doesn't follow
> with the row info.
> > 
> > doesn't follow with => is not saved in
> > 
> >>       So when we do insert sometime later, time_zone didn't write into
> binlog.
> >>       This will cause wrong result for timestamp column in slave.
> >>       
> >>       Our solution is that adding time_zone info with the delayed-row and
> >>       restoring time_zone from row-info when execute that row in the furture
> by another thread.
> >>       So we can write correct time_zone info into binlog and got correct
> result in slave.
> > 
> > Very good.
> > 
> >> modified:
> >>   mysql-test/r/rpl_timezone.result
> >>   mysql-test/t/rpl_timezone.test
> >>   sql/sql_insert.cc
> >>
> >> per-file messages:
> >>   mysql-test/r/rpl_timezone.result
> >>     Test result
> >>   mysql-test/t/rpl_timezone.test
> >>     Add test for bug#41719
> >>   sql/sql_insert.cc
> >>     Add time_zone info in the delayed-row and restore time_zone when execute
> the row in the furture by another thread.
> >> === modified file 'mysql-test/r/rpl_timezone.result'
> >> --- a/mysql-test/r/rpl_timezone.result	2007-12-15 11:50:23 +0000
> >> +++ b/mysql-test/r/rpl_timezone.result	2009-03-04 18:56:35 +0000
> >> @@ -153,4 +153,22 @@ a	b
> >>  SET @@session.time_zone = default;
> >>  DROP TABLE t1;
> >>  SET @@session.time_zone = default;
> >> +CREATE TABLE t1 (date timestamp NOT NULL default CURRENT_TIMESTAMP on
> update CURRENT_TIMESTAMP, a int(11) default NULL);
> >> +SET @@session.time_zone='+01:00';
> >> +insert into t1 values('2008-12-23 19:39:39',1);
> >> +SET @@session.time_zone='+02:00';
> >> +insert delayed into t1 values ('2002-12-23 19:39:39',2);
> >> +flush logs;
> >> +select * from t1;
> >> +date	a
> >> +2008-12-23 20:39:39	1
> >> +2002-12-23 19:39:39	2
> >> +delete from t1;
> >> +DROP TABLE t1;
> >> +select * from t1;
> >> +date	a
> >> +2008-12-23 20:39:39	1
> >> +2002-12-23 19:39:39	2
> >> +DROP TABLE t1;
> >> +SET @@session.time_zone = default;
> >>  End of 5.0 tests
> >>
> >> === modified file 'mysql-test/t/rpl_timezone.test'
> >> --- a/mysql-test/t/rpl_timezone.test	2007-08-06 11:57:28 +0000
> >> +++ b/mysql-test/t/rpl_timezone.test	2009-03-04 18:56:35 +0000
> >> @@ -154,5 +154,28 @@ connection master;
> >>  DROP TABLE t1;
> >>  SET @@session.time_zone = default;
> >>  
> >> +# Bug#41719 delayed INSERT into timestamp col needs set time_zone for
> concurrent binlogging
> >> +# To test that time_zone is correctly binloging for 'insert delayed'
> statement
> >> +# Insert 2 values into timestamp col with different time_zone. Check
> result.
> >> +
> >> +--connection master
> >> +CREATE TABLE t1 (date timestamp NOT NULL default CURRENT_TIMESTAMP on
> update CURRENT_TIMESTAMP, a int(11) default NULL);
> >> +
> >> +SET @@session.time_zone='+01:00';
> >> +insert into t1 values('2008-12-23 19:39:39',1);
> >> +
> >> +--connection master1
> >> +SET @@session.time_zone='+02:00';
> >> +insert delayed into t1 values ('2002-12-23 19:39:39',2);
> > 
> > use 'FLUSH TABLES t1' to wait for the delay insert finish.
> > 
> >> +flush logs;
> >> +select * from t1;
> >> +delete from t1;
> > 
> > the delete can be removed
> > 
> >> +DROP TABLE t1;
> >> +
> >> +--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 | $MYSQL
> >> +--connection master1
> >> +select * from t1;
> >> +DROP TABLE t1;
> >> +SET @@session.time_zone = default;
> >>  
> >>  --echo End of 5.0 tests
> >>
> >> === modified file 'sql/sql_insert.cc'
> >> --- a/sql/sql_insert.cc	2008-10-15 13:55:52 +0000
> >> +++ b/sql/sql_insert.cc	2009-03-04 18:56:35 +0000
> >> @@ -1605,6 +1605,8 @@ public:
> >>    ulong auto_increment_increment;
> >>    ulong auto_increment_offset;
> >>    timestamp_auto_set_type timestamp_field_type;
> >> +  char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
> >> +  uint time_zone_len;
> > 
> > Use 
> > 
> > Time_zone *time_zone;
> > 
> > to replace above two members, so that you do can avoid searching for the
> > timezone object later.
> > 
> > Please also change the constructor to initialize this member to 0;
> > 
> >>    uint query_length;
> >>  
> >>    delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool
> log_query_arg)
> >> @@ -2062,6 +2064,19 @@ int write_delayed(THD *thd,TABLE *table,
> >>    row->last_insert_id=		thd->last_insert_id;
> >>    row->timestamp_field_type=    table->timestamp_field_type;
> >>  
> >> +  // add session variable timezone
> > 
> > Please use /* */ for comments, this is required by the code guidelines
> > for server.
> > 
> >> +  if (thd->time_zone_used)
> >> +  {
> >> +    row->time_zone_len=
> thd->variables.time_zone->get_name()->length();
> >> +    memcpy(row->time_zone_str,
> >> +	   thd->variables.time_zone->get_name()->ptr(),
> >> +           row->time_zone_len);
> >> +    row->time_zone_str[row->time_zone_len+1] = '\0';
> > 
> > If you use Time_zone *time_zone, these lines can be:
> >   row->time_zone= thd->variables.time_zone
> 
> That's wrong.
> Row->time_zone is a pointer, and thd->variable.time_zone will be
> released after the thread finish.
> A new thread will execute the delayed-insert. So if we use a Time_zone
> pointer, we should allocate memory for it.
> 

No, the time_zone object will not be freed even switched to another
thread, please check the comment of my_tz_find() function.

> And i don't know if Time_zone have a 	
> assignment functions. I will check it later.
> 

Not necessary, just use the pointer.

> BTW. I searched almost all the cpp files and seems nobody deal with
> Time_zone using a pointer.
> 

thd->varable.time_zone is also a pointer.

> > 
> >> +  }
> >> +  else
> >> +  {
> >> +     row->time_zone_len = 0;
> >> +  }
> > 
> > and this will be: 
> >   row->time_zone= 0;
> > 
> >>    /* The session variable settings can always be copied. */
> >>    row->auto_increment_increment=
> thd->variables.auto_increment_increment;
> >>    row->auto_increment_offset=   
> thd->variables.auto_increment_offset;
> >> @@ -2515,6 +2530,22 @@ bool Delayed_insert::handle_inserts(void
> >>      }
> >>      if (row->query && row->log_query &&
> using_bin_log)
> >>      {
> >> +      if (row->time_zone_len)
> >> +      {
> >> +        thd.time_zone_used = true;
> >> +        String tmp(row->time_zone_str, row->time_zone_len,
> &my_charset_bin);
> >> +        if (!(thd.variables.time_zone=my_tz_find(&tmp,
> thd.lex->time_zone_tables_used)))
> >> +        {
> >> +          thd.variables.time_zone= global_system_variables.time_zone;
> >> +          sql_print_error("%s",thd.net.last_error);
> >> +          DBUG_PRINT("error", ("Unknow time zone"));
> >> +          goto err;
> >> +        }
> > 
> > And you can avoid searching for the time zone object by name here.
> > 
> >> +      }
> >> +      else
> >> +      {
> >> +        thd.variables.time_zone= global_system_variables.time_zone;
> > 
> > Could you explain why you need this? I think this is not necessary.
> > 
> >> +      }
> >>        Query_log_event qinfo(&thd, row->query, row->query_length,
> 0, FALSE);
> >>        mysql_bin_log.write(&qinfo);
> >>      }
> >>
> >>
> > 
> > 
> 
> 

Thread
bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719Leonard Zhou7 Mar
  • Re: bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719Andrei Elkin9 Mar
  • Re: bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719He Zhenxing11 Mar
    • Re: bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719Leonard zhou12 Mar
      • Re: bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719He Zhenxing12 Mar