mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Last part of WL#1062: better replication of timezones: no more use
of SET ONE_SHOT; storing tz info directly in event (if this info is needed), it's now allowed to have different global tz on master and slave. client/mysqlbinlog.cc: we need MAX_TIME_ZONE_NAME_LENGTH when processing log_event.h, and it's declared in mysql_priv.h mysql-test/r/rpl_timezone.result: result update mysql-test/t/rpl_timezone-slave.opt: Now that we can have different global value of timezone on master and slave, let's test it. mysql-test/t/rpl_timezone.test: Tests of the new replication of timezones: checking the output of mysqlbinlog, replication of CONVERT_TZ(). sql/ha_innodb.cc: No very fast shutdown on Netware (anyway it's disabled on all platforms, but this is so that we don't forget to keep it disabled on Netware in the future). sql/log.cc: No more need to write SET ONE_SHOT to binlog for character set and timezone (as we store this info directly nin the Query_log_event now). sql/log_event.cc: Exclude ::write() methods if MYSQL_CLIENT. Storing timezone info in the Query_log_event in master. Re-reading it in slave. Small code cleanups. I plan to not store the end 0 of catalog in binlog events soon. sql/log_event.h: replication of time zones: a place for tz info in Query_log_event, in LAST_EVENT_INFO. Plus if we are compiling a client, we don't need the ::write() methods, so keeping them out (of mysqlbinlog.cc; keeping them in, resulted in problem that mysqlbinlog does not know Timezone structure). sql/mysql_priv.h: moving this define from tztime.h (tztime.h has things which are too much for a client like mysqlbinlog). sql/set_var.cc: It's now allowed to change global value of charset or timezone even if using binlogging or if being a slave. Making CONVERT_TZ(,,@@session.time_zone) replicate. sql/set_var.h: these ::check()s are not needed anymore (changing global charset or timezone is now allowed even if binlogging or slave) sql/slave.cc: No more need to check for same global timezone if master is 5.x (ok, strictly speaking if it is > 5.0.3 but this is alpha). sql/slave.h: a function to wrap settings of charset to default. sql/tztime.cc: Adaptation of my_tz_find() to the case where it's not called from inside a query (i.e. cannot join its tz tables to the query's ones): this variant opens the tz tables itself, reads from them, and closes them. This is presently only used by the slave SQL thread (when it sets the tz before executing a query). sql/tztime.h: declaration of new function, plus moving symbol to mysql_priv.h for easier usage in mysqlbinlog (Dmitri, pardon me). BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
This commit is contained in:
@ -48,6 +48,7 @@ dlenev@build.mysql.com
|
|||||||
dlenev@jabberwock.localdomain
|
dlenev@jabberwock.localdomain
|
||||||
dlenev@mysql.com
|
dlenev@mysql.com
|
||||||
ejonore@mc03.ndb.mysql.com
|
ejonore@mc03.ndb.mysql.com
|
||||||
|
gbichot@production.mysql.com
|
||||||
gbichot@quadita2.mysql.com
|
gbichot@quadita2.mysql.com
|
||||||
georg@beethoven.local
|
georg@beethoven.local
|
||||||
georg@beethoven.site
|
georg@beethoven.site
|
||||||
|
@ -33,9 +33,9 @@
|
|||||||
#undef MYSQL_SERVER
|
#undef MYSQL_SERVER
|
||||||
#include "client_priv.h"
|
#include "client_priv.h"
|
||||||
#include <my_time.h>
|
#include <my_time.h>
|
||||||
#include "log_event.h"
|
|
||||||
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
|
/* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
#include "log_event.h"
|
||||||
|
|
||||||
#define BIN_LOG_HEADER_SIZE 4
|
#define BIN_LOG_HEADER_SIZE 4
|
||||||
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
|
#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4)
|
||||||
|
@ -4,21 +4,31 @@ reset master;
|
|||||||
reset slave;
|
reset slave;
|
||||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
start slave;
|
start slave;
|
||||||
|
set timestamp=100000000;
|
||||||
create table t1 (t timestamp);
|
create table t1 (t timestamp);
|
||||||
create table t2 (t char(32));
|
create table t2 (t char(32));
|
||||||
select @@time_zone;
|
select @@time_zone;
|
||||||
@@time_zone
|
@@time_zone
|
||||||
|
Japan
|
||||||
|
select @@time_zone;
|
||||||
|
@@time_zone
|
||||||
Europe/Moscow
|
Europe/Moscow
|
||||||
|
insert into t1 values ('20050101000000'), ('20050611093902');
|
||||||
set time_zone='UTC';
|
set time_zone='UTC';
|
||||||
insert into t1 values ('20040101000000'), ('20040611093902');
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
select * from t1;
|
select * from t1;
|
||||||
t
|
t
|
||||||
|
2004-12-31 21:00:00
|
||||||
|
2005-06-11 05:39:02
|
||||||
2004-01-01 00:00:00
|
2004-01-01 00:00:00
|
||||||
2004-06-11 09:39:02
|
2004-06-11 09:39:02
|
||||||
|
set time_zone='UTC';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
t
|
t
|
||||||
2004-01-01 03:00:00
|
2004-12-31 21:00:00
|
||||||
2004-06-11 13:39:02
|
2005-06-11 05:39:02
|
||||||
|
2004-01-01 00:00:00
|
||||||
|
2004-06-11 09:39:02
|
||||||
delete from t1;
|
delete from t1;
|
||||||
set time_zone='Europe/Moscow';
|
set time_zone='Europe/Moscow';
|
||||||
insert into t1 values ('20040101000000'), ('20040611093902');
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
@ -26,19 +36,35 @@ select * from t1;
|
|||||||
t
|
t
|
||||||
2004-01-01 00:00:00
|
2004-01-01 00:00:00
|
||||||
2004-06-11 09:39:02
|
2004-06-11 09:39:02
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
t
|
t
|
||||||
2004-01-01 00:00:00
|
2004-01-01 00:00:00
|
||||||
2004-06-11 09:39:02
|
2004-06-11 09:39:02
|
||||||
show binlog events;
|
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
|
||||||
Log_name Pos Event_type Server_id End_log_pos Info
|
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
|
||||||
master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
|
ROLLBACK;
|
||||||
master-bin.000001 # Query 1 # use `test`; create table t1 (t timestamp)
|
use test;
|
||||||
master-bin.000001 # Query 1 # use `test`; create table t2 (t char(32))
|
SET TIMESTAMP=100000000;
|
||||||
master-bin.000001 # Query 1 # use `test`; SET ONE_SHOT TIME_ZONE='UTC'
|
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
|
||||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
|
SET @@session.sql_mode=0;
|
||||||
master-bin.000001 # Query 1 # use `test`; delete from t1
|
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
|
||||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values ('20040101000000'), ('20040611093902')
|
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';
|
set time_zone='MET';
|
||||||
insert into t2 (select t from t1);
|
insert into t2 (select t from t1);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
@ -52,10 +78,6 @@ t
|
|||||||
delete from t2;
|
delete from t2;
|
||||||
set timestamp=1000072000;
|
set timestamp=1000072000;
|
||||||
insert into t2 values (current_timestamp), (current_date), (current_time);
|
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;
|
select * from t2;
|
||||||
t
|
t
|
||||||
2001-09-09 23:46:40
|
2001-09-09 23:46:40
|
||||||
@ -73,5 +95,16 @@ t
|
|||||||
2001-09-09 03:46:40
|
2001-09-09 03:46:40
|
||||||
1000000000
|
1000000000
|
||||||
set global time_zone='MET';
|
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;
|
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
|
# Some preparations
|
||||||
let $VERSION=`select version()`;
|
let $VERSION=`select version()`;
|
||||||
|
set timestamp=100000000; # for fixed output of mysqlbinlog
|
||||||
create table t1 (t timestamp);
|
create table t1 (t timestamp);
|
||||||
create table t2 (t char(32));
|
create table t2 (t char(32));
|
||||||
|
|
||||||
|
connection slave;
|
||||||
|
select @@time_zone;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Let us check how well replication works when we are saving datetime
|
# Let us check how well replication works when we are saving datetime
|
||||||
# value in TIMESTAMP field.
|
# value in TIMESTAMP field.
|
||||||
#
|
#
|
||||||
connection master;
|
connection master;
|
||||||
select @@time_zone;
|
select @@time_zone;
|
||||||
|
insert into t1 values ('20050101000000'), ('20050611093902');
|
||||||
set time_zone='UTC';
|
set time_zone='UTC';
|
||||||
insert into t1 values ('20040101000000'), ('20040611093902');
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
select * from t1;
|
select * from t1;
|
||||||
# On slave we still in 'Europe/Moscow' so we should see equivalent but
|
|
||||||
# textually different values.
|
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
set time_zone='UTC';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
|
||||||
# Let us check also that setting of time_zone back to default also works
|
# 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');
|
insert into t1 values ('20040101000000'), ('20040611093902');
|
||||||
select * from t1;
|
select * from t1;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
set time_zone='Europe/Moscow';
|
||||||
select * from t1;
|
select * from t1;
|
||||||
connection master;
|
connection master;
|
||||||
# We should not see SET ONE_SHOT time_zone before second insert
|
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
|
||||||
--replace_result $VERSION VERSION
|
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
|
||||||
--replace_column 2 # 5 #
|
|
||||||
show binlog events;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Now let us check how well we replicate statments reading TIMESTAMP fields
|
# Now let us check how well we replicate statments reading TIMESTAMP fields
|
||||||
@ -54,10 +57,6 @@ delete from t2;
|
|||||||
set timestamp=1000072000;
|
set timestamp=1000072000;
|
||||||
insert into t2 values (current_timestamp), (current_date), (current_time);
|
insert into t2 values (current_timestamp), (current_date), (current_time);
|
||||||
sync_slave_with_master;
|
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;
|
select * from t2;
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -73,13 +72,24 @@ sync_slave_with_master;
|
|||||||
select * from t2;
|
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
|
# replication
|
||||||
#
|
#
|
||||||
connection master;
|
connection master;
|
||||||
--error 1387
|
|
||||||
set global time_zone='MET';
|
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
|
# Clean up
|
||||||
|
connection master;
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
|
@ -1307,6 +1307,9 @@ innobase_end(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (innodb_inited) {
|
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) {
|
if (innobase_very_fast_shutdown) {
|
||||||
srv_very_fast_shutdown = TRUE;
|
srv_very_fast_shutdown = TRUE;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@ -1314,6 +1317,7 @@ innobase_end(void)
|
|||||||
"InnoDB: the InnoDB buffer pool to data files. At the next mysqld startup\n"
|
"InnoDB: the InnoDB buffer pool to data files. At the next mysqld startup\n"
|
||||||
"InnoDB: InnoDB will do a crash recovery!\n");
|
"InnoDB: InnoDB will do a crash recovery!\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
innodb_inited = 0;
|
innodb_inited = 0;
|
||||||
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
|
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 (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)
|
if (thd->last_insert_id_used)
|
||||||
{
|
{
|
||||||
Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
|
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));
|
field_list->push_back(new Item_empty_string("Info", 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !MYSQL_CLIENT */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Log_event::write()
|
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,
|
int Log_event::read_log_event(IO_CACHE* file, String* packet,
|
||||||
pthread_mutex_t* log_lock)
|
pthread_mutex_t* log_lock)
|
||||||
{
|
{
|
||||||
@ -956,6 +953,7 @@ void Query_log_event::pack_info(Protocol *protocol)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Query_log_event::write()
|
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+8+ // code of sql_mode and sql_mode
|
||||||
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
|
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
|
||||||
1+4+ // code of autoinc and the 2 autoinc variables
|
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;
|
], *start, *start_of_status;
|
||||||
ulong event_length;
|
ulong event_length;
|
||||||
|
|
||||||
@ -1030,20 +1029,20 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||||||
start_of_status= start= buf+QUERY_HEADER_LEN;
|
start_of_status= start= buf+QUERY_HEADER_LEN;
|
||||||
if (flags2_inited)
|
if (flags2_inited)
|
||||||
{
|
{
|
||||||
*(start++)= Q_FLAGS2_CODE;
|
*start++= Q_FLAGS2_CODE;
|
||||||
int4store(start, flags2);
|
int4store(start, flags2);
|
||||||
start+= 4;
|
start+= 4;
|
||||||
}
|
}
|
||||||
if (sql_mode_inited)
|
if (sql_mode_inited)
|
||||||
{
|
{
|
||||||
*(start++)= Q_SQL_MODE_CODE;
|
*start++= Q_SQL_MODE_CODE;
|
||||||
int8store(start, (ulonglong)sql_mode);
|
int8store(start, (ulonglong)sql_mode);
|
||||||
start+= 8;
|
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++= Q_CATALOG_CODE;
|
||||||
*(start++)= (uchar) catalog_len;
|
*start++= (uchar) catalog_len;
|
||||||
bmove(start, catalog, catalog_len);
|
bmove(start, catalog, catalog_len);
|
||||||
start+= catalog_len;
|
start+= catalog_len;
|
||||||
/*
|
/*
|
||||||
@ -1071,15 +1070,24 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||||||
}
|
}
|
||||||
if (charset_inited)
|
if (charset_inited)
|
||||||
{
|
{
|
||||||
*(start++)= Q_CHARSET_CODE;
|
*start++= Q_CHARSET_CODE;
|
||||||
memcpy(start, charset, 6);
|
memcpy(start, charset, 6);
|
||||||
start+= 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
|
Here there could be code like
|
||||||
if (command-line-option-which-says-"log_this_variable" && inited)
|
if (command-line-option-which-says-"log_this_variable" && inited)
|
||||||
{
|
{
|
||||||
*(start++)= Q_THIS_VARIABLE_CODE;
|
*start++= Q_THIS_VARIABLE_CODE;
|
||||||
int4store(start, this_variable);
|
int4store(start, this_variable);
|
||||||
start+= 4;
|
start+= 4;
|
||||||
}
|
}
|
||||||
@ -1108,8 +1116,6 @@ bool Query_log_event::write(IO_CACHE* file)
|
|||||||
/*
|
/*
|
||||||
Query_log_event::Query_log_event()
|
Query_log_event::Query_log_event()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||||
ulong query_length, bool using_trans,
|
ulong query_length, bool using_trans,
|
||||||
bool suppress_use)
|
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, thd_arg->variables.character_set_client->number);
|
||||||
int2store(charset+2, thd_arg->variables.collation_connection->number);
|
int2store(charset+2, thd_arg->variables.collation_connection->number);
|
||||||
int2store(charset+4, thd_arg->variables.collation_server->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));
|
DBUG_PRINT("info",("Query_log_event has flags2=%lu sql_mode=%lu",flags2,sql_mode));
|
||||||
}
|
}
|
||||||
#endif /* MYSQL_CLIENT */
|
#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,
|
Query_log_event::Query_log_event(const char* buf, uint event_len,
|
||||||
const Format_description_log_event *description_event,
|
const Format_description_log_event *description_event,
|
||||||
Log_event_type event_type)
|
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),
|
db(NullS), catalog_len(0), status_vars_len(0),
|
||||||
flags2_inited(0), sql_mode_inited(0), charset_inited(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;
|
ulong data_len;
|
||||||
uint32 tmp;
|
uint32 tmp;
|
||||||
uint8 common_header_len, post_header_len;
|
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*,...)");
|
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
|
||||||
|
|
||||||
common_header_len= description_event->common_header_len;
|
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);
|
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
|
||||||
exec_time = uint4korr(buf + Q_EXEC_TIME_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);
|
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 */
|
/* variable-part: the status vars; only in MySQL 5.0 */
|
||||||
|
|
||||||
start= (char*) (buf+post_header_len);
|
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;)
|
for (const uchar* pos= (const uchar*) start; pos < (const uchar*) end;)
|
||||||
{
|
{
|
||||||
switch (*pos++) {
|
switch (*pos++) {
|
||||||
@ -1240,8 +1260,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Q_CATALOG_CODE:
|
case Q_CATALOG_CODE:
|
||||||
catalog_len= *pos;
|
if ((catalog_len= *pos))
|
||||||
if (catalog_len)
|
|
||||||
catalog= (char*) pos+1; // Will be copied later
|
catalog= (char*) pos+1; // Will be copied later
|
||||||
pos+= catalog_len+2;
|
pos+= catalog_len+2;
|
||||||
break;
|
break;
|
||||||
@ -1257,6 +1276,13 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
|
|||||||
pos+= 6;
|
pos+= 6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Q_TIME_ZONE_CODE:
|
||||||
|
{
|
||||||
|
if ((time_zone_len= *pos))
|
||||||
|
time_zone_str= (char *)(pos+1);
|
||||||
|
pos+= time_zone_len+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
/* That's why you must write status vars in growing order of code */
|
/* 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\
|
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 + 1 +
|
||||||
|
time_zone_len + 1 +
|
||||||
if (!(start= data_buf = (char*) my_malloc(catalog_len + data_len +2, MYF(MY_WME))))
|
data_len + 1, MYF(MY_WME))))
|
||||||
DBUG_VOID_RETURN;
|
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;
|
catalog= start;
|
||||||
start+= catalog_len+1;
|
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
|
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;
|
db= start;
|
||||||
query= start + db_len + 1;
|
query= start + db_len + 1;
|
||||||
q_len= data_len - 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;
|
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;
|
last_event_info->auto_increment_offset= auto_increment_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: print the catalog when we feature SET CATALOG */
|
||||||
|
|
||||||
if (likely(charset_inited))
|
if (likely(charset_inited))
|
||||||
{
|
{
|
||||||
if (unlikely(!last_event_info->charset_inited)) /* first Query event */
|
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);
|
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.
|
alloced block (see Query_log_event::exec_event()). Same for thd->db.
|
||||||
Thank you.
|
Thank you.
|
||||||
*/
|
*/
|
||||||
thd->catalog= (char*) catalog;
|
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
|
||||||
thd->db_length= db_len;
|
thd->db_length= db_len;
|
||||||
thd->db= (char*) rewrite_db(db, &thd->db_length);
|
thd->db= (char*) rewrite_db(db, &thd->db_length);
|
||||||
thd->variables.auto_increment_increment= auto_increment_increment;
|
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))))
|
get_charset(uint2korr(charset+4), MYF(MY_WME))))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We updated the thd->variables with nonsensical values (0), and the
|
We updated the thd->variables with nonsensical values (0). Let's
|
||||||
thread is not guaranteed to terminate now (as it may be configured
|
set them to something safe (i.e. which avoids crash), and we'll
|
||||||
to ignore EE_UNKNOWN_CHARSET);if we're going to execute a next
|
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
|
||||||
statement we'll have a new charset info with it, so no problem to
|
ignore this error).
|
||||||
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).
|
|
||||||
*/
|
*/
|
||||||
rli->cached_charset_invalidate();
|
set_slave_thread_default_charset(thd, rli);
|
||||||
goto compare_errors;
|
goto compare_errors;
|
||||||
}
|
}
|
||||||
thd->update_charset(); // for the charset change to take effect
|
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()) */
|
/* Execute the query (note that we bypass dispatch_command()) */
|
||||||
mysql_parse(thd, thd->query, thd->query_length);
|
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()
|
Start_log_event_v3::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Start_log_event_v3::write(IO_CACHE* file)
|
bool Start_log_event_v3::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buff[START_V3_HEADER_LEN];
|
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)) ||
|
return (write_header(file, sizeof(buff)) ||
|
||||||
my_b_safe_write(file, (byte*) buff, 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;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Format_description_log_event::write(IO_CACHE* file)
|
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)) ||
|
return (write_header(file, sizeof(buff)) ||
|
||||||
my_b_safe_write(file, buff, sizeof(buff)));
|
my_b_safe_write(file, buff, sizeof(buff)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
@ -2208,6 +2260,8 @@ void Load_log_event::pack_info(Protocol *protocol)
|
|||||||
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
|
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Load_log_event::write_data_header()
|
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()
|
Load_log_event::Load_log_event()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
|
||||||
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
|
||||||
const char *db_arg, const char *table_name_arg,
|
const char *db_arg, const char *table_name_arg,
|
||||||
List<Item> &fields_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()
|
Rotate_log_event::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Rotate_log_event::write(IO_CACHE* file)
|
bool Rotate_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[ROTATE_HEADER_LEN];
|
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*)buf, ROTATE_HEADER_LEN) ||
|
||||||
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
|
my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Rotate_log_event::exec_event()
|
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).
|
master is 4.0 then the events are in the slave's format (conversion).
|
||||||
*/
|
*/
|
||||||
set_slave_thread_options(thd);
|
set_slave_thread_options(thd);
|
||||||
|
set_slave_thread_default_charset(thd, rli);
|
||||||
thd->variables.sql_mode= global_system_variables.sql_mode;
|
thd->variables.sql_mode= global_system_variables.sql_mode;
|
||||||
thd->variables.auto_increment_increment=
|
thd->variables.auto_increment_increment=
|
||||||
thd->variables.auto_increment_offset= 1;
|
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_mutex_unlock(&rli->data_lock);
|
||||||
pthread_cond_broadcast(&rli->data_cond);
|
pthread_cond_broadcast(&rli->data_cond);
|
||||||
@ -3001,6 +3048,7 @@ const char* Intvar_log_event::get_var_type_name()
|
|||||||
Intvar_log_event::write()
|
Intvar_log_event::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Intvar_log_event::write(IO_CACHE* file)
|
bool Intvar_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[9];
|
byte buf[9];
|
||||||
@ -3009,6 +3057,7 @@ bool Intvar_log_event::write(IO_CACHE* file)
|
|||||||
return (write_header(file, sizeof(buf)) ||
|
return (write_header(file, sizeof(buf)) ||
|
||||||
my_b_safe_write(file, buf, 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)
|
bool Rand_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[16];
|
byte buf[16];
|
||||||
@ -3101,6 +3151,7 @@ bool Rand_log_event::write(IO_CACHE* file)
|
|||||||
return (write_header(file, sizeof(buf)) ||
|
return (write_header(file, sizeof(buf)) ||
|
||||||
my_b_safe_write(file, buf, sizeof(buf)));
|
my_b_safe_write(file, buf, sizeof(buf)));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
@ -3164,11 +3215,13 @@ Xid_log_event(const char* buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Xid_log_event::write(IO_CACHE* file)
|
bool Xid_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
return write_header(file, sizeof(xid)) ||
|
return write_header(file, sizeof(xid)) ||
|
||||||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
|
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#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)
|
bool User_var_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
char buf[UV_NAME_LEN_SIZE];
|
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*) buf1, buf1_length) ||
|
||||||
my_b_safe_write(file, (byte*) pos, val_len));
|
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)
|
bool Slave_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
ulong event_length= get_data_size();
|
ulong event_length= get_data_size();
|
||||||
@ -3644,6 +3700,7 @@ bool Slave_log_event::write(IO_CACHE* file)
|
|||||||
return (write_header(file, event_length) ||
|
return (write_header(file, event_length) ||
|
||||||
my_b_safe_write(file, (byte*) mem_pool, event_length));
|
my_b_safe_write(file, (byte*) mem_pool, event_length));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void Slave_log_event::init_from_mem_pool(int data_size)
|
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();
|
sql_ex.force_new_format();
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
#endif /* !MYSQL_CLIENT */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3815,6 +3871,7 @@ bool Create_file_log_event::write_base(IO_CACHE* file)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* !MYSQL_CLIENT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create_file_log_event ctor
|
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()
|
Append_block_log_event::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Append_block_log_event::write(IO_CACHE* file)
|
bool Append_block_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[APPEND_BLOCK_HEADER_LEN];
|
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, buf, APPEND_BLOCK_HEADER_LEN) ||
|
||||||
my_b_safe_write(file, (byte*) block, block_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()
|
Delete_file_log_event::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Delete_file_log_event::write(IO_CACHE* file)
|
bool Delete_file_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[DELETE_FILE_HEADER_LEN];
|
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)) ||
|
return (write_header(file, sizeof(buf)) ||
|
||||||
my_b_safe_write(file, buf, 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()
|
Execute_load_log_event::write()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool Execute_load_log_event::write(IO_CACHE* file)
|
bool Execute_load_log_event::write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
byte buf[EXEC_LOAD_HEADER_LEN];
|
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)) ||
|
return (write_header(file, sizeof(buf)) ||
|
||||||
my_b_safe_write(file, buf, 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
|
bool
|
||||||
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
|
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;
|
*(buf + 4 + 4 + 4)= (char)dup_handling;
|
||||||
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
|
return my_b_safe_write(file, (byte*) buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef MYSQL_CLIENT
|
#ifdef MYSQL_CLIENT
|
||||||
|
@ -237,6 +237,7 @@ struct sql_ex_info
|
|||||||
#define Q_CATALOG_CODE 2
|
#define Q_CATALOG_CODE 2
|
||||||
#define Q_AUTO_INCREMENT 3
|
#define Q_AUTO_INCREMENT 3
|
||||||
#define Q_CHARSET_CODE 4
|
#define Q_CHARSET_CODE 4
|
||||||
|
#define Q_TIME_ZONE_CODE 5
|
||||||
|
|
||||||
/* Intvar event post-header */
|
/* Intvar event post-header */
|
||||||
|
|
||||||
@ -448,6 +449,7 @@ typedef struct st_last_event_info
|
|||||||
ulong auto_increment_increment, auto_increment_offset;
|
ulong auto_increment_increment, auto_increment_offset;
|
||||||
bool charset_inited;
|
bool charset_inited;
|
||||||
char charset[6]; // 3 variables, each of them storable in 2 bytes
|
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()
|
st_last_event_info()
|
||||||
:flags2_inited(0), sql_mode_inited(0),
|
:flags2_inited(0), sql_mode_inited(0),
|
||||||
auto_increment_increment(1),auto_increment_offset(1), charset_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(db, sizeof(db));
|
||||||
bzero(charset, sizeof(charset));
|
bzero(charset, sizeof(charset));
|
||||||
|
bzero(time_zone_str, sizeof(time_zone_str));
|
||||||
}
|
}
|
||||||
} LAST_EVENT_INFO;
|
} LAST_EVENT_INFO;
|
||||||
#endif
|
#endif
|
||||||
@ -583,6 +586,7 @@ public:
|
|||||||
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write_header(IO_CACHE* file, ulong data_length);
|
bool write_header(IO_CACHE* file, ulong data_length);
|
||||||
virtual bool write(IO_CACHE* file)
|
virtual bool write(IO_CACHE* file)
|
||||||
{
|
{
|
||||||
@ -590,13 +594,14 @@ public:
|
|||||||
write_data_header(file) ||
|
write_data_header(file) ||
|
||||||
write_data_body(file));
|
write_data_body(file));
|
||||||
}
|
}
|
||||||
virtual bool is_artificial_event() { return 0; }
|
|
||||||
virtual bool write_data_header(IO_CACHE* file)
|
virtual bool write_data_header(IO_CACHE* file)
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
|
virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
|
||||||
{ return 0; }
|
{ return 0; }
|
||||||
|
#endif
|
||||||
virtual Log_event_type get_type_code() = 0;
|
virtual Log_event_type get_type_code() = 0;
|
||||||
virtual bool is_valid() const = 0;
|
virtual bool is_valid() const = 0;
|
||||||
|
virtual bool is_artificial_event() { return 0; }
|
||||||
inline bool get_cache_stmt() { return cache_stmt; }
|
inline bool get_cache_stmt() { return cache_stmt; }
|
||||||
Log_event(const char* buf, const Format_description_log_event* description_event);
|
Log_event(const char* buf, const Format_description_log_event* description_event);
|
||||||
virtual ~Log_event() { free_temp_buf();}
|
virtual ~Log_event() { free_temp_buf();}
|
||||||
@ -672,7 +677,7 @@ public:
|
|||||||
concerned) from here.
|
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:
|
We want to be able to store a variable number of N-bit status vars:
|
||||||
@ -714,6 +719,8 @@ public:
|
|||||||
ulong sql_mode;
|
ulong sql_mode;
|
||||||
ulong auto_increment_increment, auto_increment_offset;
|
ulong auto_increment_increment, auto_increment_offset;
|
||||||
char charset[6];
|
char charset[6];
|
||||||
|
uint time_zone_len; /* 0 means uninited */
|
||||||
|
const char *time_zone_str;
|
||||||
|
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
|
|
||||||
@ -737,12 +744,13 @@ public:
|
|||||||
~Query_log_event()
|
~Query_log_event()
|
||||||
{
|
{
|
||||||
if (data_buf)
|
if (data_buf)
|
||||||
{
|
|
||||||
my_free((gptr) data_buf, MYF(0));
|
my_free((gptr) data_buf, MYF(0));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Log_event_type get_type_code() { return QUERY_EVENT; }
|
Log_event_type get_type_code() { return QUERY_EVENT; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
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; }
|
bool is_valid() const { return query != 0; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -751,7 +759,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual ulong get_post_header_size_for_derived() { return 0; }
|
virtual ulong get_post_header_size_for_derived() { return 0; }
|
||||||
/* Writes derived event-specific part of post header. */
|
/* Writes derived event-specific part of post header. */
|
||||||
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
@ -790,7 +797,9 @@ public:
|
|||||||
int get_data_size();
|
int get_data_size();
|
||||||
bool is_valid() const { return master_host != 0; }
|
bool is_valid() const { return master_host != 0; }
|
||||||
Log_event_type get_type_code() { return SLAVE_EVENT; }
|
Log_event_type get_type_code() { return SLAVE_EVENT; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
@ -885,8 +894,10 @@ public:
|
|||||||
{
|
{
|
||||||
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
|
return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
|
||||||
}
|
}
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write_data_header(IO_CACHE* file);
|
bool write_data_header(IO_CACHE* file);
|
||||||
bool write_data_body(IO_CACHE* file);
|
bool write_data_body(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return table_name != 0; }
|
bool is_valid() const { return table_name != 0; }
|
||||||
int get_data_size()
|
int get_data_size()
|
||||||
{
|
{
|
||||||
@ -962,7 +973,9 @@ public:
|
|||||||
const Format_description_log_event* description_event);
|
const Format_description_log_event* description_event);
|
||||||
~Start_log_event_v3() {}
|
~Start_log_event_v3() {}
|
||||||
Log_event_type get_type_code() { return START_EVENT_V3;}
|
Log_event_type get_type_code() { return START_EVENT_V3;}
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
bool is_valid() const { return 1; }
|
||||||
int get_data_size()
|
int get_data_size()
|
||||||
{
|
{
|
||||||
@ -1004,7 +1017,9 @@ public:
|
|||||||
const Format_description_log_event* description_event);
|
const Format_description_log_event* description_event);
|
||||||
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
|
~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); }
|
||||||
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
|
Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const
|
bool is_valid() const
|
||||||
{
|
{
|
||||||
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
|
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
|
||||||
@ -1054,7 +1069,9 @@ public:
|
|||||||
Log_event_type get_type_code() { return INTVAR_EVENT;}
|
Log_event_type get_type_code() { return INTVAR_EVENT;}
|
||||||
const char* get_var_type_name();
|
const char* get_var_type_name();
|
||||||
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
|
int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
bool is_valid() const { return 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1092,7 +1109,9 @@ class Rand_log_event: public Log_event
|
|||||||
~Rand_log_event() {}
|
~Rand_log_event() {}
|
||||||
Log_event_type get_type_code() { return RAND_EVENT;}
|
Log_event_type get_type_code() { return RAND_EVENT;}
|
||||||
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
|
int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
bool is_valid() const { return 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1127,7 +1146,9 @@ class Xid_log_event: public Log_event
|
|||||||
~Xid_log_event() {}
|
~Xid_log_event() {}
|
||||||
Log_event_type get_type_code() { return XID_EVENT;}
|
Log_event_type get_type_code() { return XID_EVENT;}
|
||||||
int get_data_size() { return sizeof(xid); }
|
int get_data_size() { return sizeof(xid); }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
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(const char* buf, const Format_description_log_event* description_event);
|
||||||
~User_var_log_event() {}
|
~User_var_log_event() {}
|
||||||
Log_event_type get_type_code() { return USER_VAR_EVENT;}
|
Log_event_type get_type_code() { return USER_VAR_EVENT;}
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
bool is_valid() const { return 1; }
|
bool is_valid() const { return 1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1239,7 +1262,9 @@ public:
|
|||||||
Log_event_type get_type_code() { return ROTATE_EVENT;}
|
Log_event_type get_type_code() { return ROTATE_EVENT;}
|
||||||
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
|
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
|
||||||
bool is_valid() const { return new_log_ident != 0; }
|
bool is_valid() const { return new_log_ident != 0; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1299,6 +1324,7 @@ public:
|
|||||||
4 + 1 + block_len);
|
4 + 1 + block_len);
|
||||||
}
|
}
|
||||||
bool is_valid() const { return inited_from_old || block != 0; }
|
bool is_valid() const { return inited_from_old || block != 0; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write_data_header(IO_CACHE* file);
|
bool write_data_header(IO_CACHE* file);
|
||||||
bool write_data_body(IO_CACHE* file);
|
bool write_data_body(IO_CACHE* file);
|
||||||
/*
|
/*
|
||||||
@ -1306,6 +1332,7 @@ public:
|
|||||||
write it as Load event - used on the slave
|
write it as Load event - used on the slave
|
||||||
*/
|
*/
|
||||||
bool write_base(IO_CACHE* file);
|
bool write_base(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1352,7 +1379,9 @@ public:
|
|||||||
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
|
Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
|
||||||
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
|
int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
|
||||||
bool is_valid() const { return block != 0; }
|
bool is_valid() const { return block != 0; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
const char* get_db() { return db; }
|
const char* get_db() { return db; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1386,7 +1415,9 @@ public:
|
|||||||
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
|
Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
|
||||||
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
|
int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
|
||||||
bool is_valid() const { return file_id != 0; }
|
bool is_valid() const { return file_id != 0; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
const char* get_db() { return db; }
|
const char* get_db() { return db; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1419,7 +1450,9 @@ public:
|
|||||||
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
|
Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
|
||||||
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
|
int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
|
||||||
bool is_valid() const { return file_id != 0; }
|
bool is_valid() const { return file_id != 0; }
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write(IO_CACHE* file);
|
bool write(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
const char* get_db() { return db; }
|
const char* get_db() { return db; }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1507,7 +1540,9 @@ public:
|
|||||||
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
|
bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
|
||||||
|
|
||||||
ulong get_post_header_size_for_derived();
|
ulong get_post_header_size_for_derived();
|
||||||
|
#ifndef MYSQL_CLIENT
|
||||||
bool write_post_header_for_derived(IO_CACHE* file);
|
bool write_post_header_for_derived(IO_CACHE* file);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,6 +257,12 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
|
|||||||
/* Flag set if setup_tables already done */
|
/* Flag set if setup_tables already done */
|
||||||
#define OPTION_SETUP_TABLES_DONE (1L << 30)
|
#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 */
|
/* The rest of the file is included in the server only */
|
||||||
#ifndef MYSQL_CLIENT
|
#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,
|
CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
|
||||||
enum_var_type type)
|
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)
|
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 str(buff, sizeof(buff), &my_charset_latin1);
|
||||||
String *res= var->value->val_str(&str);
|
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=
|
if (!(var->save_result.time_zone=
|
||||||
my_tz_find(res, thd->lex->time_zone_tables_used)))
|
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)
|
if (type == OPT_GLOBAL)
|
||||||
return (byte *)(global_system_variables.time_zone->get_name()->ptr());
|
return (byte *)(global_system_variables.time_zone->get_name()->ptr());
|
||||||
else
|
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());
|
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:
|
public:
|
||||||
sys_var_character_set_server(const char *name_arg) :
|
sys_var_character_set_server(const char *name_arg) :
|
||||||
sys_var_character_set(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);
|
void set_default(THD *thd, enum_var_type type);
|
||||||
CHARSET_INFO **ci_ptr(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:
|
public:
|
||||||
sys_var_collation_server(const char *name_arg) :sys_var_collation(name_arg) {}
|
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);
|
bool update(THD *thd, set_var *var);
|
||||||
void set_default(THD *thd, enum_var_type type);
|
void set_default(THD *thd, enum_var_type type);
|
||||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
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
|
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.
|
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
|
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.
|
charset info in each binlog event.
|
||||||
We don't do it for 3.23 because masters <3.23.50 hang on
|
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
|
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
|
such check will broke everything for them. (And now everything will
|
||||||
work for them because by default both their master and slave will have
|
work for them because by default both their master and slave will have
|
||||||
'SYSTEM' time zone).
|
'SYSTEM' time zone).
|
||||||
|
This check is only necessary for 4.x masters (and < 5.0.4 masters but
|
||||||
TODO: when the new replication of timezones is sorted out with Dmitri,
|
those were alpha).
|
||||||
change >= '4' to == '4'.
|
|
||||||
*/
|
*/
|
||||||
if ((*mysql->server_version >= '4') &&
|
if ((*mysql->server_version == '4') &&
|
||||||
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
|
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
|
||||||
(master_res= mysql_store_result(mysql)))
|
(master_res= mysql_store_result(mysql)))
|
||||||
{
|
{
|
||||||
@ -2770,6 +2769,18 @@ void set_slave_thread_options(THD* thd)
|
|||||||
thd->variables.completion_type= 0;
|
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()
|
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,
|
int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset,
|
||||||
const char** errmsg);
|
const char** errmsg);
|
||||||
void set_slave_thread_options(THD* thd);
|
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);
|
void rotate_relay_log(MASTER_INFO* mi);
|
||||||
|
|
||||||
extern "C" pthread_handler_decl(handle_slave_io,arg);
|
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'",
|
DBUG_PRINT("enter", ("time zone name='%s'",
|
||||||
name ? ((String *)name)->c_ptr() : "NULL"));
|
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)
|
if (!name)
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
@ -2210,7 +2210,7 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
|
|||||||
(const byte *)name->ptr(),
|
(const byte *)name->ptr(),
|
||||||
name->length())))
|
name->length())))
|
||||||
result_tz= tmp_tzname->tz;
|
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);
|
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);
|
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) */
|
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ extern Time_zone * my_tz_UTC;
|
|||||||
extern Time_zone * my_tz_SYSTEM;
|
extern Time_zone * my_tz_SYSTEM;
|
||||||
extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr);
|
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(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 my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap);
|
||||||
extern void my_tz_free();
|
extern void my_tz_free();
|
||||||
|
|
||||||
@ -96,10 +97,4 @@ inline bool my_tz_check_n_skip_implicit_tables(TABLE_LIST **table,
|
|||||||
return FALSE;
|
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) */
|
#endif /* !defined(TESTTIME) && !defined(TZINFO2SQL) */
|
||||||
|
Reference in New Issue
Block a user