mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.0
into production.mysql.com:/nfstmp1/guilhem/mysql-5.0-prod
This commit is contained in:
commit
56495a3691
16 changed files with 322 additions and 200 deletions
|
@ -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;
|
||||
|
|
|
@ -1 +1 @@
|
|||
--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) {
|
||||
|
|
51
sql/log.cc
51
sql/log.cc
|
@ -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,
|
||||
|
|
165
sql/log_event.cc
165
sql/log_event.cc
|
@ -506,8 +506,6 @@ void Log_event::init_show_field_list(List<Item>* field_list)
|
|||
field_list->push_back(new Item_empty_string("Info", 20));
|
||||
}
|
||||
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
Log_event::write()
|
||||
|
@ -592,7 +590,6 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
|
|||
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||
pthread_mutex_t* log_lock)
|
||||
{
|
||||
|
@ -956,6 +953,7 @@ void Query_log_event::pack_info(Protocol *protocol)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
Query_log_event::write()
|
||||
|
@ -973,7 +971,8 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||
1+8+ // code of sql_mode and sql_mode
|
||||
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
|
||||
1+4+ // code of autoinc and the 2 autoinc variables
|
||||
1+6 // code of charset and charset
|
||||
1+6+ // code of charset and charset
|
||||
1+1+MAX_TIME_ZONE_NAME_LENGTH // code of tz and tz length and tz name
|
||||
], *start, *start_of_status;
|
||||
ulong event_length;
|
||||
|
||||
|
@ -1030,20 +1029,20 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||
start_of_status= start= buf+QUERY_HEADER_LEN;
|
||||
if (flags2_inited)
|
||||
{
|
||||
*(start++)= Q_FLAGS2_CODE;
|
||||
*start++= Q_FLAGS2_CODE;
|
||||
int4store(start, flags2);
|
||||
start+= 4;
|
||||
}
|
||||
if (sql_mode_inited)
|
||||
{
|
||||
*(start++)= Q_SQL_MODE_CODE;
|
||||
*start++= Q_SQL_MODE_CODE;
|
||||
int8store(start, (ulonglong)sql_mode);
|
||||
start+= 8;
|
||||
}
|
||||
if (catalog_len >= 0) // i.e. "catalog inited" (false for 4.0 events)
|
||||
if (catalog_len) // i.e. "catalog inited" (false for 4.0 events)
|
||||
{
|
||||
*(start++)= Q_CATALOG_CODE;
|
||||
*(start++)= (uchar) catalog_len;
|
||||
*start++= Q_CATALOG_CODE;
|
||||
*start++= (uchar) catalog_len;
|
||||
bmove(start, catalog, catalog_len);
|
||||
start+= catalog_len;
|
||||
/*
|
||||
|
@ -1071,15 +1070,24 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||
}
|
||||
if (charset_inited)
|
||||
{
|
||||
*(start++)= Q_CHARSET_CODE;
|
||||
*start++= Q_CHARSET_CODE;
|
||||
memcpy(start, charset, 6);
|
||||
start+= 6;
|
||||
}
|
||||
if (time_zone_len)
|
||||
{
|
||||
/* In the TZ sys table, column Name is of length 64 so this should be ok */
|
||||
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
|
||||
*start++= Q_TIME_ZONE_CODE;
|
||||
*start++= time_zone_len;
|
||||
memcpy(start, time_zone_str, time_zone_len);
|
||||
start+= time_zone_len;
|
||||
}
|
||||
/*
|
||||
Here there could be code like
|
||||
if (command-line-option-which-says-"log_this_variable" && inited)
|
||||
{
|
||||
*(start++)= Q_THIS_VARIABLE_CODE;
|
||||
*start++= Q_THIS_VARIABLE_CODE;
|
||||
int4store(start, this_variable);
|
||||
start+= 4;
|
||||
}
|
||||
|
@ -1108,8 +1116,6 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||
/*
|
||||
Query_log_event::Query_log_event()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
ulong query_length, bool using_trans,
|
||||
bool suppress_use)
|
||||
|
@ -1150,6 +1156,18 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
|||
int2store(charset, thd_arg->variables.character_set_client->number);
|
||||
int2store(charset+2, thd_arg->variables.collation_connection->number);
|
||||
int2store(charset+4, thd_arg->variables.collation_server->number);
|
||||
if (thd_arg->time_zone_used)
|
||||
{
|
||||
/*
|
||||
Note that our event becomes dependent on the Time_zone object
|
||||
representing the time zone. Fortunately such objects are never deleted
|
||||
or changed during mysqld's lifetime.
|
||||
*/
|
||||
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
|
||||
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
|
||||
}
|
||||
else
|
||||
time_zone_len= 0;
|
||||
DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
|
||||
}
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
@ -1163,15 +1181,17 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
|||
Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||
const Format_description_log_event *description_event,
|
||||
Log_event_type event_type)
|
||||
:Log_event(buf, description_event), data_buf(0), query(NullS), catalog(NullS),
|
||||
:Log_event(buf, description_event), data_buf(0), query(NullS),
|
||||
db(NullS), catalog_len(0), status_vars_len(0),
|
||||
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
|
||||
auto_increment_increment(1), auto_increment_offset(1)
|
||||
auto_increment_increment(1), auto_increment_offset(1),
|
||||
time_zone_len(0)
|
||||
{
|
||||
ulong data_len;
|
||||
uint32 tmp;
|
||||
uint8 common_header_len, post_header_len;
|
||||
const char *start, *end;
|
||||
char *start;
|
||||
const char *end;
|
||||
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
|
||||
|
||||
common_header_len= description_event->common_header_len;
|
||||
|
@ -1191,7 +1211,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||
|
||||
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
|
||||
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
|
||||
db_len = (uint)buf[Q_DB_LEN_OFFSET];
|
||||
db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
|
||||
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
|
||||
|
||||
/*
|
||||
|
@ -1217,7 +1237,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||
/* variable-part: the status vars; only in MySQL 5.0 */
|
||||
|
||||
start= (char*) (buf+post_header_len);
|
||||
end= (char*) (start+status_vars_len);
|
||||
end= (const char*) (start+status_vars_len);
|
||||
for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
|
||||
{
|
||||
switch (*pos++) {
|
||||
|
@ -1240,8 +1260,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||
break;
|
||||
}
|
||||
case Q_CATALOG_CODE:
|
||||
catalog_len= *pos;
|
||||
if (catalog_len)
|
||||
if ((catalog_len= *pos))
|
||||
catalog= (char*) pos+1; // Will be copied later
|
||||
pos+= catalog_len+2;
|
||||
break;
|
||||
|
@ -1257,6 +1276,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||
pos+= 6;
|
||||
break;
|
||||
}
|
||||
case Q_TIME_ZONE_CODE:
|
||||
{
|
||||
if ((time_zone_len= *pos))
|
||||
time_zone_str= (char *)(pos+1);
|
||||
pos+= time_zone_len+1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/* That's why you must write status vars in growing order of code */
|
||||
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
|
||||
|
@ -1265,24 +1291,29 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||
}
|
||||
}
|
||||
|
||||
/* A 2nd variable part; this is common to all versions */
|
||||
|
||||
if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME))))
|
||||
if (!(start= data_buf = (char*) my_malloc(catalog_len + 1 +
|
||||
time_zone_len + 1 +
|
||||
data_len + 1, MYF(MY_WME))))
|
||||
DBUG_VOID_RETURN;
|
||||
if (catalog) // If catalog is given
|
||||
if (catalog_len) // If catalog is given
|
||||
{
|
||||
memcpy((char*) start, catalog, catalog_len+1); // Copy name and end \0
|
||||
memcpy(start, catalog, catalog_len+1); // Copy name and end \0
|
||||
catalog= start;
|
||||
start+= catalog_len+1;
|
||||
}
|
||||
if (time_zone_len)
|
||||
{
|
||||
memcpy(start, time_zone_str, time_zone_len);
|
||||
time_zone_str= start;
|
||||
start+= time_zone_len;
|
||||
*start++= 0;
|
||||
}
|
||||
/* A 2nd variable part; this is common to all versions */
|
||||
memcpy((char*) start, end, data_len); // Copy db and query
|
||||
((char*) start)[data_len]= '\0'; // End query with \0 (For safetly)
|
||||
start[data_len]= '\0'; // End query with \0 (For safetly)
|
||||
db= start;
|
||||
query= start + db_len + 1;
|
||||
q_len= data_len - db_len -1;
|
||||
/* This is used to detect wrong parsing. Could be removed in the future. */
|
||||
DBUG_PRINT("info", ("catalog: '%s' len: %u db: '%s' len: %u q_len: %lu",
|
||||
catalog, (uint) catalog_len, db, (uint) db_len,q_len));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -1390,6 +1421,8 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
|
|||
last_event_info->auto_increment_offset= auto_increment_offset;
|
||||
}
|
||||
|
||||
/* TODO: print the catalog when we feature SET CATALOG */
|
||||
|
||||
if (likely(charset_inited))
|
||||
{
|
||||
if (unlikely(!last_event_info->charset_inited)) /* first Query event */
|
||||
|
@ -1410,6 +1443,14 @@ void Query_log_event::print_query_header(FILE* file, bool short_form,
|
|||
memcpy(last_event_info->charset, charset, 6);
|
||||
}
|
||||
}
|
||||
if (time_zone_len)
|
||||
{
|
||||
if (bcmp(last_event_info->time_zone_str, time_zone_str, time_zone_len+1))
|
||||
{
|
||||
fprintf(file,"SET @@session.time_zone='%s';\n", time_zone_str);
|
||||
memcpy(last_event_info->time_zone_str, time_zone_str, time_zone_len+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1443,7 +1484,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
|
|||
alloced block (see Query_log_event::exec_event()). Same for thd->db.
|
||||
Thank you.
|
||||
*/
|
||||
thd->catalog= (char*) catalog;
|
||||
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
|
||||
thd->db_length= db_len;
|
||||
thd->db= (char*) rewrite_db(db, &thd->db_length);
|
||||
thd->variables.auto_increment_increment= auto_increment_increment;
|
||||
|
@ -1513,20 +1554,28 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
|
|||
get_charset(uint2korr(charset+4), MYF(MY_WME))))
|
||||
{
|
||||
/*
|
||||
We updated the thd->variables with nonsensical values (0), and the
|
||||
thread is not guaranteed to terminate now (as it may be configured
|
||||
to ignore EE_UNKNOWN_CHARSET);if we're going to execute a next
|
||||
statement we'll have a new charset info with it, so no problem to
|
||||
have stored 0 in thd->variables. But we invalidate cached
|
||||
charset to force a check next time (otherwise if next time
|
||||
charset is unknown again we won't detect it).
|
||||
We updated the thd->variables with nonsensical values (0). Let's
|
||||
set them to something safe (i.e. which avoids crash), and we'll
|
||||
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
|
||||
ignore this error).
|
||||
*/
|
||||
rli->cached_charset_invalidate();
|
||||
set_slave_thread_default_charset(thd, rli);
|
||||
goto compare_errors;
|
||||
}
|
||||
thd->update_charset(); // for the charset change to take effect
|
||||
}
|
||||
}
|
||||
if (time_zone_len)
|
||||
{
|
||||
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
|
||||
if (!(thd->variables.time_zone=
|
||||
my_tz_find_with_opening_tz_tables(thd, &tmp)))
|
||||
{
|
||||
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
|
||||
thd->variables.time_zone= global_system_variables.time_zone;
|
||||
goto compare_errors;
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute the query (note that we bypass dispatch_command()) */
|
||||
mysql_parse(thd, thd->query, thd->query_length);
|
||||
|
@ -1751,6 +1800,7 @@ Start_log_event_v3::Start_log_event_v3(const char* buf,
|
|||
Start_log_event_v3::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Start_log_event_v3::write(IO_CACHE* file)
|
||||
{
|
||||
char buff[START_V3_HEADER_LEN];
|
||||
|
@ -1760,6 +1810,7 @@ bool Start_log_event_v3::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buff)) ||
|
||||
my_b_safe_write(file, (byte*) buff, sizeof(buff)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1975,7 +2026,7 @@ Format_description_log_event(const char* buf,
|
|||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Format_description_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
/*
|
||||
|
@ -1992,6 +2043,7 @@ bool Format_description_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buff)) ||
|
||||
my_b_safe_write(file, buff, sizeof(buff)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
|
@ -2208,6 +2260,8 @@ void Load_log_event::pack_info(Protocol *protocol)
|
|||
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
|
||||
/*
|
||||
Load_log_event::write_data_header()
|
||||
*/
|
||||
|
@ -2249,7 +2303,6 @@ bool Load_log_event::write_data_body(IO_CACHE* file)
|
|||
Load_log_event::Load_log_event()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
||||
const char *db_arg, const char *table_name_arg,
|
||||
List<Item> &fields_arg,
|
||||
|
@ -2863,6 +2916,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
|
|||
Rotate_log_event::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Rotate_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
char buf[ROTATE_HEADER_LEN];
|
||||
|
@ -2871,7 +2925,7 @@ bool Rotate_log_event::write(IO_CACHE* file)
|
|||
my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) ||
|
||||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Rotate_log_event::exec_event()
|
||||
|
@ -2929,17 +2983,10 @@ int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
|
|||
master is 4.0 then the events are in the slave's format (conversion).
|
||||
*/
|
||||
set_slave_thread_options(thd);
|
||||
set_slave_thread_default_charset(thd, rli);
|
||||
thd->variables.sql_mode= global_system_variables.sql_mode;
|
||||
thd->variables.auto_increment_increment=
|
||||
thd->variables.auto_increment_offset= 1;
|
||||
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();
|
||||
}
|
||||
pthread_mutex_unlock(&rli->data_lock);
|
||||
pthread_cond_broadcast(&rli->data_cond);
|
||||
|
@ -3001,6 +3048,7 @@ const char* Intvar_log_event::get_var_type_name()
|
|||
Intvar_log_event::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Intvar_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
byte buf[9];
|
||||
|
@ -3009,6 +3057,7 @@ bool Intvar_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buf)) ||
|
||||
my_b_safe_write(file, buf, sizeof(buf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -3093,6 +3142,7 @@ Rand_log_event::Rand_log_event(const char* buf,
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Rand_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
byte buf[16];
|
||||
|
@ -3101,6 +3151,7 @@ bool Rand_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buf)) ||
|
||||
my_b_safe_write(file, buf, sizeof(buf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
|
@ -3164,11 +3215,13 @@ Xid_log_event(const char* buf,
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Xid_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
return write_header(file, sizeof(xid)) ||
|
||||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
|
@ -3302,6 +3355,7 @@ User_var_log_event(const char* buf,
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool User_var_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
char buf[UV_NAME_LEN_SIZE];
|
||||
|
@ -3361,6 +3415,7 @@ bool User_var_log_event::write(IO_CACHE* file)
|
|||
my_b_safe_write(file, (byte*) buf1, buf1_length) ||
|
||||
my_b_safe_write(file, (byte*) pos, val_len));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -3634,6 +3689,7 @@ int Slave_log_event::get_data_size()
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Slave_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
ulong event_length= get_data_size();
|
||||
|
@ -3644,6 +3700,7 @@ bool Slave_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, event_length) ||
|
||||
my_b_safe_write(file, (byte*) mem_pool, event_length));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Slave_log_event::init_from_mem_pool(int data_size)
|
||||
|
@ -3770,7 +3827,6 @@ Create_file_log_event(THD* thd_arg, sql_exchange* ex,
|
|||
sql_ex.force_new_format();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -3815,6 +3871,7 @@ bool Create_file_log_event::write_base(IO_CACHE* file)
|
|||
return res;
|
||||
}
|
||||
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
/*
|
||||
Create_file_log_event ctor
|
||||
|
@ -4042,6 +4099,7 @@ Append_block_log_event::Append_block_log_event(const char* buf, uint len,
|
|||
Append_block_log_event::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Append_block_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
byte buf[APPEND_BLOCK_HEADER_LEN];
|
||||
|
@ -4050,6 +4108,7 @@ bool Append_block_log_event::write(IO_CACHE* file)
|
|||
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
|
||||
my_b_safe_write(file, (byte*) block, block_len));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -4171,6 +4230,7 @@ Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
|
|||
Delete_file_log_event::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Delete_file_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
byte buf[DELETE_FILE_HEADER_LEN];
|
||||
|
@ -4178,6 +4238,7 @@ bool Delete_file_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buf)) ||
|
||||
my_b_safe_write(file, buf, sizeof(buf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -4265,6 +4326,7 @@ Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
|
|||
Execute_load_log_event::write()
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool Execute_load_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
byte buf[EXEC_LOAD_HEADER_LEN];
|
||||
|
@ -4272,6 +4334,7 @@ bool Execute_load_log_event::write(IO_CACHE* file)
|
|||
return (write_header(file, sizeof(buf)) ||
|
||||
my_b_safe_write(file, buf, sizeof(buf)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -4475,6 +4538,7 @@ ulong Execute_load_query_log_event::get_post_header_size_for_derived()
|
|||
}
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
bool
|
||||
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
|
||||
{
|
||||
|
@ -4485,6 +4549,7 @@ Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
|
|||
*(buf + 4 + 4 + 4)= (char)dup_handling;
|
||||
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
|
|
|
@ -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);
|
||||
|
|
21
sql/slave.cc
21
sql/slave.cc
|
@ -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) */
|
||||
|
|
Loading…
Reference in a new issue