List:Commits« Previous MessageNext Message »
From:Leonard Zhou Date:March 4 2009 6:57pm
Subject:bzr commit into mysql-5.0-bugteam branch (leonard:2767) Bug#41719
View as plain text  
#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.
      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.
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);
+flush logs;
+select * from t1;
+delete from t1;
+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;
   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
+  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';
+  }
+  else
+  {
+     row->time_zone_len = 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;
+        }
+      }
+      else
+      {
+        thd.variables.time_zone= global_system_variables.time_zone;
+      }
       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