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 be keeped in 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. 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.
This commit is contained in:
parent
b4fdb8aec1
commit
5fdc5510ec
@ -153,4 +153,22 @@ a b
|
|||||||
SET @@session.time_zone = default;
|
SET @@session.time_zone = default;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET @@session.time_zone = default;
|
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 ('2008-12-23 19:39:39',2);
|
||||||
|
flush table t1;
|
||||||
|
flush logs;
|
||||||
|
select * from t1;
|
||||||
|
date a
|
||||||
|
2008-12-23 20:39:39 1
|
||||||
|
2008-12-23 19:39:39 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
select * from t1 order by a;
|
||||||
|
date a
|
||||||
|
2008-12-23 20:39:39 1
|
||||||
|
2008-12-23 19:39:39 2
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@session.time_zone = default;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@ -154,5 +154,30 @@ connection master;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
SET @@session.time_zone = default;
|
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 ('2008-12-23 19:39:39',2);
|
||||||
|
# Forces table t1 to be closed and flushes the query cache.
|
||||||
|
# This makes sure that 'delayed insert' is executed before next statement.
|
||||||
|
flush table t1;
|
||||||
|
flush logs;
|
||||||
|
select * from t1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000001 | $MYSQL
|
||||||
|
--connection master1
|
||||||
|
select * from t1 order by a;
|
||||||
|
DROP TABLE t1;
|
||||||
|
SET @@session.time_zone = default;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@ -1605,10 +1605,11 @@ public:
|
|||||||
ulong auto_increment_increment;
|
ulong auto_increment_increment;
|
||||||
ulong auto_increment_offset;
|
ulong auto_increment_offset;
|
||||||
timestamp_auto_set_type timestamp_field_type;
|
timestamp_auto_set_type timestamp_field_type;
|
||||||
|
Time_zone *time_zone;
|
||||||
uint query_length;
|
uint query_length;
|
||||||
|
|
||||||
delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
|
delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
|
||||||
:record(0), query(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
|
:record(0), query(0), time_zone(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
|
||||||
~delayed_row()
|
~delayed_row()
|
||||||
{
|
{
|
||||||
x_free(record);
|
x_free(record);
|
||||||
@ -2062,6 +2063,19 @@ int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore,
|
|||||||
row->last_insert_id= thd->last_insert_id;
|
row->last_insert_id= thd->last_insert_id;
|
||||||
row->timestamp_field_type= table->timestamp_field_type;
|
row->timestamp_field_type= table->timestamp_field_type;
|
||||||
|
|
||||||
|
/* Add session variable timezone
|
||||||
|
Time_zone object will not be freed even the thread is ended.
|
||||||
|
So we can get time_zone object from thread which handling delayed statement.
|
||||||
|
See the comment of my_tz_find() for detail.
|
||||||
|
*/
|
||||||
|
if (thd->time_zone_used)
|
||||||
|
{
|
||||||
|
row->time_zone = thd->variables.time_zone;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row->time_zone = NULL;
|
||||||
|
}
|
||||||
/* The session variable settings can always be copied. */
|
/* The session variable settings can always be copied. */
|
||||||
row->auto_increment_increment= thd->variables.auto_increment_increment;
|
row->auto_increment_increment= thd->variables.auto_increment_increment;
|
||||||
row->auto_increment_offset= thd->variables.auto_increment_offset;
|
row->auto_increment_offset= thd->variables.auto_increment_offset;
|
||||||
@ -2515,8 +2529,19 @@ bool Delayed_insert::handle_inserts(void)
|
|||||||
}
|
}
|
||||||
if (row->query && row->log_query && using_bin_log)
|
if (row->query && row->log_query && using_bin_log)
|
||||||
{
|
{
|
||||||
|
bool backup_time_zone_used = thd.time_zone_used;
|
||||||
|
Time_zone *backup_time_zone = thd.variables.time_zone;
|
||||||
|
if (row->time_zone != NULL)
|
||||||
|
{
|
||||||
|
thd.time_zone_used = true;
|
||||||
|
thd.variables.time_zone = row->time_zone;
|
||||||
|
}
|
||||||
|
|
||||||
Query_log_event qinfo(&thd, row->query, row->query_length, 0, FALSE);
|
Query_log_event qinfo(&thd, row->query, row->query_length, 0, FALSE);
|
||||||
mysql_bin_log.write(&qinfo);
|
mysql_bin_log.write(&qinfo);
|
||||||
|
|
||||||
|
thd.time_zone_used = backup_time_zone_used;
|
||||||
|
thd.variables.time_zone = backup_time_zone;
|
||||||
}
|
}
|
||||||
if (table->s->blob_fields)
|
if (table->s->blob_fields)
|
||||||
free_delayed_insert_blobs(table);
|
free_delayed_insert_blobs(table);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user