Commit 56495a36 authored by gbichot@production.mysql.com's avatar gbichot@production.mysql.com

Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.0

into production.mysql.com:/nfstmp1/guilhem/mysql-5.0-prod
parents d8b078e4 c766efdc
......@@ -48,6 +48,7 @@ dlenev@build.mysql.com
dlenev@jabberwock.localdomain
dlenev@mysql.com
ejonore@mc03.ndb.mysql.com
gbichot@production.mysql.com
gbichot@quadita2.mysql.com
gbichot@quadxeon.mysql.com
georg@beethoven.local
......
......@@ -33,9 +33,9 @@
#undef MYSQL_SERVER
#include "client_priv.h"
#include <my_time.h>
#include "log_event.h"
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
#include "mysql_priv.h"
#include "log_event.h"
#define BIN_LOG_HEADER_SIZE 4
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
......
......@@ -4,21 +4,31 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set timestamp=100000000;
create table t1 (t timestamp);
create table t2 (t char(32));
select @@time_zone;
@@time_zone
Japan
select @@time_zone;
@@time_zone
Europe/Moscow
insert into t1 values ('20050101000000'), ('20050611093902');
set time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
t
2004-12-31 21:00:00
2005-06-11 05:39:02
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='UTC';
select * from t1;
t
2004-01-01 03:00:00
2004-06-11 13:39:02
2004-12-31 21:00:00
2005-06-11 05:39:02
2004-01-01 00:00:00
2004-06-11 09:39:02
delete from t1;
set time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
......@@ -26,19 +36,35 @@ select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='Europe/Moscow';
select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
master-bin.000001 # Query 1 # use `test`; create table t1 (t timestamp)
master-bin.000001 # Query 1 # use `test`; create table t2 (t char(32))
master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT TIME_ZONE='UTC'
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
master-bin.000001 # Query 1 # use `test`; delete from t1
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
use test;
SET TIMESTAMP=100000000;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
SET @@session.sql_mode=0;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
create table t1 (t timestamp);
SET TIMESTAMP=100000000;
create table t2 (t char(32));
SET TIMESTAMP=100000000;
SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20050101000000'), ('20050611093902');
SET TIMESTAMP=100000000;
SET @@session.time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
SET TIMESTAMP=100000000;
delete from t1;
SET TIMESTAMP=100000000;
SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
ROLLBACK;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
set time_zone='MET';
insert into t2 (select t from t1);
select * from t1;
......@@ -52,10 +78,6 @@ t
delete from t2;
set timestamp=1000072000;
insert into t2 values (current_timestamp), (current_date), (current_time);
set timestamp=1000072000;
select current_timestamp, current_date, current_time;
current_timestamp current_date current_time
2001-09-10 01:46:40 2001-09-10 01:46:40
select * from t2;
t
2001-09-09 23:46:40
......@@ -73,5 +95,16 @@ t
2001-09-09 03:46:40
1000000000
set global time_zone='MET';
ERROR HY000: Binary logging and replication forbid changing the global server time zone
delete from t2;
set time_zone='UTC';
insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone));
insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'));
select * from t2;
t
2003-12-31 23:00:00
2005-01-01 08:00:00
select * from t2;
t
2003-12-31 23:00:00
2005-01-01 08:00:00
drop table t1, t2;
--default-time-zone=Europe/Moscow
--default-time-zone=Japan
......@@ -3,21 +3,25 @@ source include/master-slave.inc;
# Some preparations
let $VERSION=`select version()`;
set timestamp=100000000; # for fixed output of mysqlbinlog
create table t1 (t timestamp);
create table t2 (t char(32));
connection slave;
select @@time_zone;
#
# Let us check how well replication works when we are saving datetime
# value in TIMESTAMP field.
#
connection master;
select @@time_zone;
insert into t1 values ('20050101000000'), ('20050611093902');
set time_zone='UTC';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
# On slave we still in 'Europe/Moscow' so we should see equivalent but
# textually different values.
sync_slave_with_master;
set time_zone='UTC';
select * from t1;
# Let us check also that setting of time_zone back to default also works
......@@ -28,12 +32,11 @@ set time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
select * from t1;
sync_slave_with_master;
set time_zone='Europe/Moscow';
select * from t1;
connection master;
# We should not see SET ONE_SHOT time_zone before second insert
--replace_result $VERSION VERSION
--replace_column 2 # 5 #
show binlog events;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
#
# Now let us check how well we replicate statments reading TIMESTAMP fields
......@@ -54,10 +57,6 @@ delete from t2;
set timestamp=1000072000;
insert into t2 values (current_timestamp), (current_date), (current_time);
sync_slave_with_master;
# Values in ouput of these to queries should differ because we are in
# in 'MET' on master and in 'Europe/Moscow on slave...
set timestamp=1000072000;
select current_timestamp, current_date, current_time;
select * from t2;
#
......@@ -73,13 +72,24 @@ sync_slave_with_master;
select * from t2;
#
# Let us check that we are not allowing to set global time_zone with
# Let us check that we are allowing to set global time_zone with
# replication
#
connection master;
--error 1387
set global time_zone='MET';
#
# Let us see if CONVERT_TZ(@@time_zone) replicates
#
delete from t2;
set time_zone='UTC';
insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone));
insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'));
select * from t2;
sync_slave_with_master;
select * from t2;
# Clean up
connection master;
drop table t1, t2;
sync_slave_with_master;
......@@ -1307,6 +1307,9 @@ innobase_end(void)
}
#endif
if (innodb_inited) {
#ifndef __NETWARE__ /* NetWare can't close unclosed files, kill remaining
threads, etc, so we disable the very fast shutdown */
if (innobase_very_fast_shutdown) {
srv_very_fast_shutdown = TRUE;
fprintf(stderr,
......@@ -1314,6 +1317,7 @@ innobase_end(void)
"InnoDB: the InnoDB buffer pool to data files. At the next mysqld startup\n"
"InnoDB: InnoDB will do a crash recovery!\n");
}
#endif
innodb_inited = 0;
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
......
......@@ -1638,57 +1638,6 @@ bool MYSQL_LOG::write(Log_event *event_info)
if (thd)
{
#if MYSQL_VERSION_ID < 50003
/*
To make replication of charsets working in 4.1 we are writing values
of charset related variables before every statement in the binlog,
if values of those variables differ from global server-wide defaults.
We are using SET ONE_SHOT command so that the charset vars get reset
to default after the first non-SET statement.
In the next 5.0 this won't be needed as we will use the new binlog
format to store charset info.
*/
if ((thd->variables.character_set_client->number !=
global_system_variables.collation_server->number) ||
(thd->variables.character_set_client->number !=
thd->variables.collation_connection->number) ||
(thd->variables.collation_server->number !=
thd->variables.collation_connection->number))
{
char buf[200];
int written= my_snprintf(buf, sizeof(buf)-1,
"SET ONE_SHOT CHARACTER_SET_CLIENT=%u,\
COLLATION_CONNECTION=%u,COLLATION_DATABASE=%u,COLLATION_SERVER=%u",
(uint) thd->variables.character_set_client->number,
(uint) thd->variables.collation_connection->number,
(uint) thd->variables.collation_database->number,
(uint) thd->variables.collation_server->number);
Query_log_event e(thd, buf, written, 0, FALSE);
if (e.write(file))
goto err;
}
#endif
/*
We use the same ONE_SHOT trick for making replication of time zones
working in 4.1. Again in 5.0 we have better means for doing this.
TODO: we should do like we now do with charsets (no more ONE_SHOT;
logging in each event in a compact format). Dmitri says we can do:
if (time_zone_used) write the timezone to binlog (in a format to be
defined).
*/
if (thd->time_zone_used &&
thd->variables.time_zone != global_system_variables.time_zone)
{
char buf[MAX_TIME_ZONE_NAME_LENGTH + 26];
char *buf_end= strxmov(buf, "SET ONE_SHOT TIME_ZONE='",
thd->variables.time_zone->get_name()->ptr(),
"'", NullS);
Query_log_event e(thd, buf, buf_end - buf, 0, FALSE);
if (e.write(file))
goto err;
}
if (thd->last_insert_id_used)
{
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
......
This diff is collapsed.
......@@ -237,6 +237,7 @@ struct sql_ex_info
#define Q_CATALOG_CODE 2
#define Q_AUTO_INCREMENT 3
#define Q_CHARSET_CODE 4
#define Q_TIME_ZONE_CODE 5
/* Intvar event post-header */
......@@ -448,6 +449,7 @@ typedef struct st_last_event_info
ulong auto_increment_increment, auto_increment_offset;
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
st_last_event_info()
:flags2_inited(0), sql_mode_inited(0),
auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
......@@ -459,6 +461,7 @@ typedef struct st_last_event_info
*/
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
}
} LAST_EVENT_INFO;
#endif
......@@ -583,6 +586,7 @@ public:
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
}
#ifndef MYSQL_CLIENT
bool write_header(IO_CACHE* file, ulong data_length);
virtual bool write(IO_CACHE* file)
{
......@@ -590,13 +594,14 @@ public:
write_data_header(file) ||
write_data_body(file));
}
virtual bool is_artificial_event() { return 0; }
virtual bool write_data_header(IO_CACHE* file)
{ return 0; }
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
{ return 0; }
#endif
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
virtual bool is_artificial_event() { return 0; }
inline bool get_cache_stmt() { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event* description_event);
virtual ~Log_event() { free_temp_buf();}
......@@ -672,7 +677,7 @@ public:
concerned) from here.
*/
int catalog_len; // <= 255 char; -1 means uninited
uint catalog_len; // <= 255 char; 0 means uninited
/*
We want to be able to store a variable number of N-bit status vars:
......@@ -714,6 +719,8 @@ public:
ulong sql_mode;
ulong auto_increment_increment, auto_increment_offset;
char charset[6];
uint time_zone_len; /* 0 means uninited */
const char *time_zone_str;
#ifndef MYSQL_CLIENT
......@@ -737,12 +744,13 @@ public:
~Query_log_event()
{
if (data_buf)
{
my_free((gptr) data_buf, MYF(0));
}
}
Log_event_type get_type_code() { return QUERY_EVENT; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
#endif
bool is_valid() const { return query != 0; }
/*
......@@ -751,7 +759,6 @@ public:
*/
virtual ulong get_post_header_size_for_derived() { return 0; }
/* Writes derived event-specific part of post header. */
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
};
#ifdef HAVE_REPLICATION
......@@ -790,7 +797,9 @@ public:
int get_data_size();
bool is_valid() const { return master_host != 0; }
Log_event_type get_type_code() { return SLAVE_EVENT; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
};
#endif /* HAVE_REPLICATION */
......@@ -885,8 +894,10 @@ public:
{
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
}
#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
#endif
bool is_valid() const { return table_name != 0; }
int get_data_size()
{
......@@ -962,7 +973,9 @@ public:
const Format_description_log_event* description_event);
~Start_log_event_v3() {}
Log_event_type get_type_code() { return START_EVENT_V3;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
int get_data_size()
{
......@@ -1004,7 +1017,9 @@ public:
const Format_description_log_event* description_event);
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
......@@ -1054,7 +1069,9 @@ public:
Log_event_type get_type_code() { return INTVAR_EVENT;}
const char* get_var_type_name();
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
......@@ -1092,7 +1109,9 @@ class Rand_log_event: public Log_event
~Rand_log_event() {}
Log_event_type get_type_code() { return RAND_EVENT;}
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
......@@ -1127,7 +1146,9 @@ class Xid_log_event: public Log_event
~Xid_log_event() {}
Log_event_type get_type_code() { return XID_EVENT;}
int get_data_size() { return sizeof(xid); }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
......@@ -1169,7 +1190,9 @@ public:
User_var_log_event(const char* buf, const Format_description_log_event* description_event);
~User_var_log_event() {}
Log_event_type get_type_code() { return USER_VAR_EVENT;}
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
};
......@@ -1239,7 +1262,9 @@ public:
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
bool is_valid() const { return new_log_ident != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
};
......@@ -1299,6 +1324,7 @@ public:
4 + 1 + block_len);
}
bool is_valid() const { return inited_from_old || block != 0; }
#ifndef MYSQL_CLIENT
bool write_data_header(IO_CACHE* file);
bool write_data_body(IO_CACHE* file);
/*
......@@ -1306,6 +1332,7 @@ public:
write it as Load event - used on the slave
*/
bool write_base(IO_CACHE* file);
#endif
};
......@@ -1352,7 +1379,9 @@ public:
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
bool is_valid() const { return block != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
......@@ -1386,7 +1415,9 @@ public:
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
......@@ -1419,7 +1450,9 @@ public:
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
#endif
const char* get_db() { return db; }
};
......@@ -1507,7 +1540,9 @@ public:
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
ulong get_post_header_size_for_derived();
#ifndef MYSQL_CLIENT
bool write_post_header_for_derived(IO_CACHE* file);
#endif
};
......
......@@ -264,6 +264,12 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
/* Flag set if setup_tables already done */
#define OPTION_SETUP_TABLES_DONE (1L << 30)
/*
Maximum length of time zone name that we support
(Time zone name is char(64) in db). mysqlbinlog needs it.
*/
#define MAX_TIME_ZONE_NAME_LENGTH 72
/* The rest of the file is included in the server only */
#ifndef MYSQL_CLIENT
......
......@@ -2095,27 +2095,6 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type)
}
}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool sys_var_character_set_server::check(THD *thd, set_var *var)
{
/*
To be perfect we should fail even if we are a 5.0.3 slave, a 4.1 master,
and user wants to change our global character set variables. Because
replicating a 4.1 assumes those are not changed. But that's not easy to
do.
*/
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
return sys_var_character_set::check(thd,var);
}
#endif
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
enum_var_type type)
{
......@@ -2208,20 +2187,6 @@ void sys_var_collation_database::set_default(THD *thd, enum_var_type type)
}
}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool sys_var_collation_server::check(THD *thd, set_var *var)
{
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0),
"character set, collation");
return 1;
}
return sys_var_collation::check(thd,var);
}
#endif
bool sys_var_collation_server::update(THD *thd, set_var *var)
{
......@@ -2560,16 +2525,6 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
String str(buff, sizeof(buff), &my_charset_latin1);
String *res= var->value->val_str(&str);
#if defined(HAVE_REPLICATION)
if ((var->type == OPT_GLOBAL) &&
(mysql_bin_log.is_open() ||
active_mi->slave_running || active_mi->rli.slave_running))
{
my_error(ER_LOGGING_PROHIBIT_CHANGING_OF, MYF(0), "time zone");
return 1;
}
#endif
if (!(var->save_result.time_zone=
my_tz_find(res, thd->lex->time_zone_tables_used)))
{
......@@ -2605,7 +2560,18 @@ byte *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
if (type == OPT_GLOBAL)
return (byte *)(global_system_variables.time_zone->get_name()->ptr());
else
{
/*
This is an ugly fix for replication: we don't replicate properly queries
invoking system variables' values to update tables; but
CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
replicable (i.e. we tell the binlog code to store the session
timezone). If it's the global value which was used we can't replicate
(binlog code stores session value only).
*/
thd->time_zone_used= 1;
return (byte *)(thd->variables.time_zone->get_name()->ptr());
}
}
......
......@@ -565,9 +565,6 @@ class sys_var_character_set_server :public sys_var_character_set
public:
sys_var_character_set_server(const char *name_arg) :
sys_var_character_set(name_arg) {}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool check(THD *thd, set_var *var);
#endif
void set_default(THD *thd, enum_var_type type);
CHARSET_INFO **ci_ptr(THD *thd, enum_var_type type);
};
......@@ -603,9 +600,6 @@ class sys_var_collation_server :public sys_var_collation
{
public:
sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
#if defined(HAVE_REPLICATION) && (MYSQL_VERSION_ID < 50003)
bool check(THD *thd, set_var *var);
#endif
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
......
......@@ -1421,7 +1421,7 @@ not always make sense; please check the manual before using it).";
We don't test equality of global collation_database either as it's is
going to be deprecated (made read-only) in 4.1 very soon.
The test is only relevant if master < 5.0.3 (we'll test only if it's older
than the 5 branch; < 5.0.3 was alpha...), as >= 5.0.3 master stores
than the 5 branch; < 5.0.4 were alpha...), as >= 5.0.4 master stores
charset info in each binlog event.
We don't do it for 3.23 because masters <3.23.50 hang on
SELECT @@unknown_var (BUG#7965 - see changelog of 3.23.50). So finally we
......@@ -1456,11 +1456,10 @@ be equal for replication to work";
such check will broke everything for them. (And now everything will
work for them because by default both their master and slave will have
'SYSTEM' time zone).
TODO: when the new replication of timezones is sorted out with Dmitri,
change >= '4' to == '4'.
This check is only necessary for 4.x masters (and < 5.0.4 masters but
those were alpha).
*/
if ((*mysql->server_version >= '4') &&
if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
(master_res= mysql_store_result(mysql)))
{
......@@ -2770,6 +2769,18 @@ void set_slave_thread_options(THD* thd)
thd->variables.completion_type= 0;
}
void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli)
{
thd->variables.character_set_client=
global_system_variables.character_set_client;
thd->variables.collation_connection=
global_system_variables.collation_connection;
thd->variables.collation_server=
global_system_variables.collation_server;
thd->update_charset();
rli->cached_charset_invalidate();
}
/*
init_slave_thread()
*/
......
......@@ -562,6 +562,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos,
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
const char** errmsg);
void set_slave_thread_options(THD* thd);
void set_slave_thread_default_charset(THD* thd, RELAY_LOG_INFO *rli);
void rotate_relay_log(MASTER_INFO* mi);
extern "C" pthread_handler_decl(handle_slave_io,arg);
......
......@@ -2178,7 +2178,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_PRINT("enter", ("time zone name='%s'",
name ? ((String *)name)->c_ptr() : "NULL"));
DBUG_ASSERT(!time_zone_tables_exist || tz_tables);
DBUG_ASSERT(!time_zone_tables_exist || tz_tables || current_thd->slave_thread);
if (!name)
DBUG_RETURN(0);
......@@ -2210,7 +2210,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
(const byte *)name->ptr(),
name->length())))
result_tz= tmp_tzname->tz;
else if (time_zone_tables_exist)
else if (time_zone_tables_exist && tz_tables)
result_tz= tz_load_from_open_tables(name, tz_tables);
}
......@@ -2219,6 +2219,58 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
DBUG_RETURN(result_tz);
}
/*
A more standalone version of my_tz_find(): will open tz tables if needed.
This is so far only used by replication, where time zone setting does not
happen in the usual query context.
SYNOPSIS
my_tz_find_with_opening_tz_tables()
thd - pointer to thread's THD structure
name - time zone specification
DESCRIPTION
This function tries to find a time zone which matches the named passed in
argument. If it fails, it will open time zone tables and re-try the
search.
This function is needed for the slave SQL thread, which does not do the
addition of time zone tables which is usually done during query parsing
(as time zone setting by slave does not happen in mysql_parse() but
before). So it needs to open tz tables by itself if needed.
See notes of my_tz_find() as they also apply here.
RETURN VALUE
Pointer to corresponding Time_zone object. 0 - in case of bad time zone
specification or other error.
*/
Time_zone *my_tz_find_with_opening_tz_tables(THD *thd, const String *name)
{
Time_zone *tz;
DBUG_ENTER("my_tz_find_with_opening_tables");
DBUG_ASSERT(thd);
DBUG_ASSERT(thd->slave_thread); // intended for use with slave thread only
if (!(tz= my_tz_find(name, 0)) && time_zone_tables_exist)
{
/*
Probably we have not loaded this time zone yet so let us look it up in
our time zone tables. Note that if we don't have tz tables on this
slave, we don't even try.
*/
TABLE_LIST tables[4];
TABLE_LIST *dummy;
TABLE_LIST **dummyp= &dummy;
tz_init_table_list(tables, &dummyp);
if (simple_open_n_lock_tables(thd, tables))
DBUG_RETURN(0);
tz= my_tz_find(name, tables);
/* We need to close tables _now_ to not pollute coming query */
close_thread_tables(thd);
}
DBUG_RETURN(tz);
}
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
......
......@@ -61,6 +61,7 @@ extern Time_zone * my_tz_UTC;
extern Time_zone * my_tz_SYSTEM;
extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr);
extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables);
extern Time_zone * my_tz_find_with_opening_tz_tables(THD *thd, const String *name);
extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
extern void my_tz_free();
......@@ -96,10 +97,4 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
return FALSE;
}
/*
Maximum length of time zone name that we support
(Time zone name is char(64) in db)
*/
#define MAX_TIME_ZONE_NAME_LENGTH 72
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment