mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
manually merged
This commit is contained in:
297
sql/log_event.cc
297
sql/log_event.cc
@@ -269,9 +269,10 @@ const char* Log_event::get_type_str()
|
||||
case DELETE_FILE_EVENT: return "Delete_file";
|
||||
case EXEC_LOAD_EVENT: return "Exec_load";
|
||||
case RAND_EVENT: return "RAND";
|
||||
case XID_EVENT: return "Xid";
|
||||
case USER_VAR_EVENT: return "User var";
|
||||
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
|
||||
default: return "Unknown"; /* impossible */
|
||||
default: return "Unknown"; /* impossible */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,16 +287,15 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
|
||||
{
|
||||
server_id= thd->server_id;
|
||||
when= thd->start_time;
|
||||
cache_stmt= (using_trans &&
|
||||
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
|
||||
cache_stmt= using_trans;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This minimal constructor is for when you are not even sure that there is a
|
||||
valid THD. For example in the server when we are shutting down or flushing
|
||||
logs after receiving a SIGHUP (then we must write a Rotate to the binlog but
|
||||
we have no THD, so we need this minimal constructor).
|
||||
This minimal constructor is for when you are not even sure that there
|
||||
is a valid THD. For example in the server when we are shutting down or
|
||||
flushing logs after receiving a SIGHUP (then we must write a Rotate to
|
||||
the binlog but we have no THD, so we need this minimal constructor).
|
||||
*/
|
||||
|
||||
Log_event::Log_event()
|
||||
@@ -314,12 +314,12 @@ Log_event::Log_event()
|
||||
*/
|
||||
|
||||
Log_event::Log_event(const char* buf,
|
||||
const Format_description_log_event* description_event)
|
||||
const Format_description_log_event* description_event)
|
||||
:temp_buf(0), cache_stmt(0)
|
||||
{
|
||||
#ifndef MYSQL_CLIENT
|
||||
thd = 0;
|
||||
#endif
|
||||
#endif
|
||||
when = uint4korr(buf);
|
||||
server_id = uint4korr(buf + SERVER_ID_OFFSET);
|
||||
if (description_event->binlog_version==1)
|
||||
@@ -331,14 +331,14 @@ Log_event::Log_event(const char* buf,
|
||||
/* 4.0 or newer */
|
||||
log_pos= uint4korr(buf + LOG_POS_OFFSET);
|
||||
/*
|
||||
If the log is 4.0 (so here it can only be a 4.0 relay log read by the SQL
|
||||
thread or a 4.0 master binlog read by the I/O thread), log_pos is the
|
||||
beginning of the event: we transform it into the end of the event, which is
|
||||
more useful.
|
||||
But how do you know that the log is 4.0: you know it if description_event
|
||||
is version 3 *and* you are not reading a Format_desc (remember that
|
||||
mysqlbinlog starts by assuming that 5.0 logs are in 4.0 format, until it
|
||||
finds a Format_desc).
|
||||
If the log is 4.0 (so here it can only be a 4.0 relay log read by
|
||||
the SQL thread or a 4.0 master binlog read by the I/O thread),
|
||||
log_pos is the beginning of the event: we transform it into the end
|
||||
of the event, which is more useful.
|
||||
But how do you know that the log is 4.0: you know it if
|
||||
description_event is version 3 *and* you are not reading a
|
||||
Format_desc (remember that mysqlbinlog starts by assuming that 5.0
|
||||
logs are in 4.0 format, until it finds a Format_desc).
|
||||
*/
|
||||
if (description_event->binlog_version==3 &&
|
||||
buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
|
||||
@@ -346,13 +346,13 @@ Log_event::Log_event(const char* buf,
|
||||
/*
|
||||
If log_pos=0, don't change it. log_pos==0 is a marker to mean
|
||||
"don't change rli->group_master_log_pos" (see
|
||||
inc_group_relay_log_pos()). As it is unreal log_pos, adding the event
|
||||
len's is nonsense. For example, a fake Rotate event should
|
||||
inc_group_relay_log_pos()). As it is unreal log_pos, adding the
|
||||
event len's is nonsense. For example, a fake Rotate event should
|
||||
not have its log_pos (which is 0) changed or it will modify
|
||||
Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense value
|
||||
of (a non-zero offset which does not exist in the master's binlog, so
|
||||
which will cause problems if the user uses this value in
|
||||
CHANGE MASTER).
|
||||
Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
|
||||
value of (a non-zero offset which does not exist in the master's
|
||||
binlog, so which will cause problems if the user uses this value
|
||||
in CHANGE MASTER).
|
||||
*/
|
||||
log_pos+= uint4korr(buf + EVENT_LEN_OFFSET);
|
||||
}
|
||||
@@ -363,16 +363,17 @@ Log_event::Log_event(const char* buf,
|
||||
(buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
|
||||
{
|
||||
/*
|
||||
These events always have a header which stops here (i.e. their header is
|
||||
FROZEN).
|
||||
These events always have a header which stops here (i.e. their
|
||||
header is FROZEN).
|
||||
*/
|
||||
/*
|
||||
Initialization to zero of all other Log_event members as they're not
|
||||
specified. Currently there are no such members; in the future there will
|
||||
be an event UID (but Format_description and Rotate don't need this UID,
|
||||
as they are not propagated through --log-slave-updates (remember the UID
|
||||
is used to not play a query twice when you have two masters which are
|
||||
slaves of a 3rd master). Then we are done.
|
||||
Initialization to zero of all other Log_event members as they're
|
||||
not specified. Currently there are no such members; in the future
|
||||
there will be an event UID (but Format_description and Rotate
|
||||
don't need this UID, as they are not propagated through
|
||||
--log-slave-updates (remember the UID is used to not play a query
|
||||
twice when you have two masters which are slaves of a 3rd master).
|
||||
Then we are done.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
@@ -405,10 +406,10 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
|
||||
if (rli)
|
||||
{
|
||||
/*
|
||||
If in a transaction, and if the slave supports transactions,
|
||||
just inc_event_relay_log_pos(). We only have to check for OPTION_BEGIN
|
||||
(not OPTION_NOT_AUTOCOMMIT) as transactions are logged
|
||||
with BEGIN/COMMIT, not with SET AUTOCOMMIT= .
|
||||
If in a transaction, and if the slave supports transactions, just
|
||||
inc_event_relay_log_pos(). We only have to check for OPTION_BEGIN
|
||||
(not OPTION_NOT_AUTOCOMMIT) as transactions are logged with
|
||||
BEGIN/COMMIT, not with SET AUTOCOMMIT= .
|
||||
|
||||
CAUTION: opt_using_transactions means
|
||||
innodb || bdb ; suppose the master supports InnoDB and BDB,
|
||||
@@ -416,17 +417,18 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
|
||||
will arise:
|
||||
- suppose an InnoDB table is created on the master,
|
||||
- then it will be MyISAM on the slave
|
||||
- but as opt_using_transactions is true, the slave will believe he is
|
||||
transactional with the MyISAM table. And problems will come when one
|
||||
does START SLAVE; STOP SLAVE; START SLAVE; (the slave will resume at
|
||||
BEGIN whereas there has not been any rollback). This is the problem of
|
||||
using opt_using_transactions instead of a finer
|
||||
"does the slave support _the_transactional_handler_used_on_the_master_".
|
||||
|
||||
More generally, we'll have problems when a query mixes a transactional
|
||||
handler and MyISAM and STOP SLAVE is issued in the middle of the
|
||||
"transaction". START SLAVE will resume at BEGIN while the MyISAM table
|
||||
has already been updated.
|
||||
- but as opt_using_transactions is true, the slave will believe he
|
||||
is transactional with the MyISAM table. And problems will come
|
||||
when one does START SLAVE; STOP SLAVE; START SLAVE; (the slave
|
||||
will resume at BEGIN whereas there has not been any rollback).
|
||||
This is the problem of using opt_using_transactions instead of a
|
||||
finer "does the slave support
|
||||
_the_transactional_handler_used_on_the_master_".
|
||||
|
||||
More generally, we'll have problems when a query mixes a
|
||||
transactional handler and MyISAM and STOP SLAVE is issued in the
|
||||
middle of the "transaction". START SLAVE will resume at BEGIN
|
||||
while the MyISAM table has already been updated.
|
||||
*/
|
||||
if ((thd->options & OPTION_BEGIN) && opt_using_transactions)
|
||||
rli->inc_event_relay_log_pos();
|
||||
@@ -435,8 +437,8 @@ int Log_event::exec_event(struct st_relay_log_info* rli)
|
||||
rli->inc_group_relay_log_pos(log_pos);
|
||||
flush_relay_log_info(rli);
|
||||
/*
|
||||
Note that Rotate_log_event::exec_event() does not call this function,
|
||||
so there is no chance that a fake rotate event resets
|
||||
Note that Rotate_log_event::exec_event() does not call this
|
||||
function, so there is no chance that a fake rotate event resets
|
||||
last_master_timestamp.
|
||||
Note that we update without mutex (probably ok - except in some very
|
||||
rare cases, only consequence is that value may take some time to
|
||||
@@ -649,11 +651,9 @@ end:
|
||||
#ifndef MYSQL_CLIENT
|
||||
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
|
||||
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
|
||||
#define max_allowed_packet current_thd->variables.max_allowed_packet
|
||||
#else
|
||||
#define UNLOCK_MUTEX
|
||||
#define LOCK_MUTEX
|
||||
#define max_allowed_packet (*mysql_get_parameters()->p_max_allowed_packet)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -670,16 +670,17 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
#else
|
||||
Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
const Format_description_log_event *description_event)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, Format_description_log_event *");
|
||||
DBUG_ASSERT(description_event);
|
||||
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
|
||||
/*
|
||||
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
|
||||
check the event for sanity and to know its length; no need to really parse
|
||||
it. We say "at most" because this could be a 3.23 master, which has header
|
||||
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's "minimal"
|
||||
over the set {MySQL >=4.0}).
|
||||
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
|
||||
"minimal" over the set {MySQL >=4.0}).
|
||||
*/
|
||||
uint header_size= min(description_event->common_header_len,
|
||||
LOG_EVENT_MINIMAL_HEADER_LEN);
|
||||
@@ -692,17 +693,21 @@ Log_event* Log_event::read_log_event(IO_CACHE* file,
|
||||
failed my_b_read"));
|
||||
UNLOCK_MUTEX;
|
||||
/*
|
||||
No error here; it could be that we are at the file's end. However if the
|
||||
next my_b_read() fails (below), it will be an error as we were able to
|
||||
read the first bytes.
|
||||
No error here; it could be that we are at the file's end. However
|
||||
if the next my_b_read() fails (below), it will be an error as we
|
||||
were able to read the first bytes.
|
||||
*/
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
|
||||
char *buf= 0;
|
||||
const char *error= 0;
|
||||
Log_event *res= 0;
|
||||
#ifndef max_allowed_packet
|
||||
THD *thd=current_thd;
|
||||
uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~0;
|
||||
#endif
|
||||
|
||||
if (data_len > max_allowed_packet)
|
||||
{
|
||||
@@ -729,16 +734,16 @@ failed my_b_read"));
|
||||
error = "read error";
|
||||
goto err;
|
||||
}
|
||||
if ((res= read_log_event(buf, data_len, &error,
|
||||
description_event)))
|
||||
if ((res= read_log_event(buf, data_len, &error, description_event)))
|
||||
res->register_temp_buf(buf);
|
||||
|
||||
err:
|
||||
UNLOCK_MUTEX;
|
||||
if (error)
|
||||
if (!res)
|
||||
{
|
||||
sql_print_error("\
|
||||
Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d",
|
||||
DBUG_ASSERT(error);
|
||||
sql_print_error("Error in Log_event::read_log_event(): "
|
||||
"'%s', data_len: %d, event_type: %d",
|
||||
error,data_len,head[EVENT_TYPE_OFFSET]);
|
||||
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
|
||||
/*
|
||||
@@ -751,7 +756,7 @@ Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d",
|
||||
*/
|
||||
file->error= -1;
|
||||
}
|
||||
return res;
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
@@ -775,7 +780,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
*error="Sanity check failed"; // Needed to free buffer
|
||||
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
|
||||
}
|
||||
|
||||
|
||||
switch(buf[EVENT_TYPE_OFFSET]) {
|
||||
case QUERY_EVENT:
|
||||
ev = new Query_log_event(buf, event_len, description_event);
|
||||
@@ -809,14 +814,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
|
||||
ev = new Start_log_event_v3(buf, description_event);
|
||||
break;
|
||||
#ifdef HAVE_REPLICATION
|
||||
case STOP_EVENT:
|
||||
ev = new Stop_log_event(buf, description_event);
|
||||
break;
|
||||
#endif /* HAVE_REPLICATION */
|
||||
case INTVAR_EVENT:
|
||||
ev = new Intvar_log_event(buf, description_event);
|
||||
break;
|
||||
case XID_EVENT:
|
||||
ev = new Xid_log_event(buf, description_event);
|
||||
break;
|
||||
case RAND_EVENT:
|
||||
ev = new Rand_log_event(buf, description_event);
|
||||
break;
|
||||
@@ -831,14 +837,15 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
|
||||
ev= NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
is_valid() are small event-specific sanity tests which are important; for
|
||||
example there are some my_malloc() in constructors
|
||||
(e.g. Query_log_event::Query_log_event(char*...)); when these my_malloc()
|
||||
fail we can't return an error out of the constructor (because constructor
|
||||
is "void") ; so instead we leave the pointer we wanted to allocate
|
||||
(e.g. 'query') to 0 and we test it in is_valid(). Same for
|
||||
Format_description_log_event, member 'post_header_len'.
|
||||
is_valid() are small event-specific sanity tests which are
|
||||
important; for example there are some my_malloc() in constructors
|
||||
(e.g. Query_log_event::Query_log_event(char*...)); when these
|
||||
my_malloc() fail we can't return an error out of the constructor
|
||||
(because constructor is "void") ; so instead we leave the pointer we
|
||||
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
|
||||
Same for Format_description_log_event, member 'post_header_len'.
|
||||
*/
|
||||
if (!ev || !ev->is_valid())
|
||||
{
|
||||
@@ -1082,8 +1089,8 @@ bool Query_log_event::write(IO_CACHE* file)
|
||||
|
||||
return (write_header(file, event_length) ||
|
||||
my_b_safe_write(file, (byte*) buf, (uint) (start-buf)) ||
|
||||
my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
||||
my_b_safe_write(file, (byte*) query, q_len)) ? 1 : 0;
|
||||
my_b_safe_write(file, (db) ? (byte*) db : (byte*)"", db_len + 1) ||
|
||||
my_b_safe_write(file, (byte*) query, q_len)) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1095,7 +1102,7 @@ bool Query_log_event::write(IO_CACHE* file)
|
||||
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
|
||||
ulong query_length, bool using_trans,
|
||||
bool suppress_use)
|
||||
:Log_event(thd_arg,
|
||||
:Log_event(thd_arg,
|
||||
((thd_arg->tmp_table_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0)
|
||||
| (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0)),
|
||||
using_trans),
|
||||
@@ -1303,18 +1310,12 @@ void Query_log_event::print(FILE* file, bool short_form,
|
||||
my_fwrite(file, (byte*) buff, (uint) (end-buff),MYF(MY_NABP | MY_WME));
|
||||
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
|
||||
fprintf(file,"SET @@session.pseudo_thread_id=%lu;\n",(ulong)thread_id);
|
||||
/*
|
||||
Now the session variables;
|
||||
it's more efficient to pass SQL_MODE as a number instead of a
|
||||
comma-separated list.
|
||||
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
|
||||
variables (they have no global version; they're not listed in sql_class.h),
|
||||
The tests below work for pure binlogs or pure relay logs. Won't work for
|
||||
mixed relay logs but we don't create mixed relay logs (that is, there is no
|
||||
relay log with a format change except within the 3 first events, which
|
||||
mysqlbinlog handles gracefully). So this code should always be good.
|
||||
*/
|
||||
|
||||
/*
|
||||
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
|
||||
print (remember we don't produce mixed relay logs so there cannot be
|
||||
5.0 events before that one so there is nothing to reset).
|
||||
*/
|
||||
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
|
||||
{
|
||||
/* tmp is a bitmask of bits which have changed. */
|
||||
@@ -1343,9 +1344,16 @@ void Query_log_event::print(FILE* file, bool short_form,
|
||||
}
|
||||
|
||||
/*
|
||||
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to print
|
||||
(remember we don't produce mixed relay logs so there cannot be 5.0 events
|
||||
before that one so there is nothing to reset).
|
||||
Now the session variables;
|
||||
it's more efficient to pass SQL_MODE as a number instead of a
|
||||
comma-separated list.
|
||||
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
|
||||
variables (they have no global version; they're not listed in
|
||||
sql_class.h), The tests below work for pure binlogs or pure relay
|
||||
logs. Won't work for mixed relay logs but we don't create mixed
|
||||
relay logs (that is, there is no relay log with a format change
|
||||
except within the 3 first events, which mysqlbinlog handles
|
||||
gracefully). So this code should always be good.
|
||||
*/
|
||||
|
||||
if (likely(sql_mode_inited))
|
||||
@@ -1439,7 +1447,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
thd->query_length= q_len;
|
||||
thd->query = (char*)query;
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query_id = query_id++;
|
||||
thd->query_id = next_query_id();
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->variables.pseudo_thread_id= thread_id; // for temp tables
|
||||
mysql_log.write(thd,COM_QUERY,"%s",thd->query);
|
||||
@@ -1759,15 +1767,19 @@ int Start_log_event_v3::exec_event(struct st_relay_log_info* rli)
|
||||
}
|
||||
/*
|
||||
As a transaction NEVER spans on 2 or more binlogs:
|
||||
if we have an active transaction at this point, the master died while
|
||||
writing the transaction to the binary log, i.e. while flushing the binlog
|
||||
cache to the binlog. As the write was started, the transaction had been
|
||||
committed on the master, so we lack of information to replay this
|
||||
transaction on the slave; all we can do is stop with error.
|
||||
Note: this event could be sent by the master to inform us of the format
|
||||
of its binlog; in other words maybe it is not at its original place when
|
||||
it comes to us; we'll know this by checking log_pos ("artificial" events
|
||||
have log_pos == 0).
|
||||
if we have an active transaction at this point, the master died
|
||||
while writing the transaction to the binary log, i.e. while
|
||||
flushing the binlog cache to the binlog. As the write was started,
|
||||
the transaction had been committed on the master, so we lack of
|
||||
information to replay this transaction on the slave; all we can do
|
||||
is stop with error.
|
||||
Note: this event could be sent by the master to inform us of the
|
||||
format of its binlog; in other words maybe it is not at its
|
||||
original place when it comes to us; we'll know this by checking
|
||||
log_pos ("artificial" events have log_pos == 0).
|
||||
|
||||
TODO test whether it's really necessary, as slave.cc does ROLLBACK
|
||||
itself
|
||||
*/
|
||||
if (!artificial_event && (thd->options & OPTION_BEGIN))
|
||||
{
|
||||
@@ -1836,8 +1848,7 @@ binary log.");
|
||||
*/
|
||||
|
||||
Format_description_log_event::
|
||||
Format_description_log_event(uint8 binlog_ver,
|
||||
const char* server_ver)
|
||||
Format_description_log_event(uint8 binlog_ver, const char* server_ver)
|
||||
:Start_log_event_v3()
|
||||
{
|
||||
created= when;
|
||||
@@ -1849,7 +1860,7 @@ Format_description_log_event(uint8 binlog_ver,
|
||||
number_of_event_types= LOG_EVENT_TYPES;
|
||||
/* we'll catch my_malloc() error in is_valid() */
|
||||
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
|
||||
MYF(0));
|
||||
MYF(MY_ZEROFILL));
|
||||
/*
|
||||
This long list of assignments is not beautiful, but I see no way to
|
||||
make it nicer, as the right members are #defines, not array members, so
|
||||
@@ -1859,18 +1870,13 @@ Format_description_log_event(uint8 binlog_ver,
|
||||
{
|
||||
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
|
||||
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
|
||||
post_header_len[STOP_EVENT-1]= 0;
|
||||
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
|
||||
post_header_len[INTVAR_EVENT-1]= 0;
|
||||
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
|
||||
post_header_len[SLAVE_EVENT-1]= 0;
|
||||
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
|
||||
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
|
||||
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
|
||||
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
|
||||
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
|
||||
post_header_len[RAND_EVENT-1]= 0;
|
||||
post_header_len[USER_VAR_EVENT-1]= 0;
|
||||
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
|
||||
}
|
||||
break;
|
||||
@@ -1957,8 +1963,7 @@ Format_description_log_event(const char* buf,
|
||||
/* If alloc fails, we'll detect it in is_valid() */
|
||||
post_header_len= (uint8*) my_memdup((byte*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
|
||||
number_of_event_types*
|
||||
sizeof(*post_header_len),
|
||||
MYF(0));
|
||||
sizeof(*post_header_len), MYF(0));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@@ -2038,7 +2043,7 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
/**************************************************************************
|
||||
Load_log_event methods
|
||||
General note about Load_log_event: the binlogging of LOAD DATA INFILE is
|
||||
going to be changed in 5.0 (or maybe in 4.1; not decided yet).
|
||||
going to be changed in 5.0 (or maybe in 5.1; not decided yet).
|
||||
However, the 5.0 slave could still have to read such events (from a 4.x
|
||||
master), convert them (which just means maybe expand the header, when 5.0
|
||||
servers have a UID in events) (remember that whatever is after the header
|
||||
@@ -2553,7 +2558,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
|
||||
{
|
||||
thd->set_time((time_t)when);
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query_id = query_id++;
|
||||
thd->query_id = next_query_id();
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
/*
|
||||
Initing thd->row_count is not necessary in theory as this variable has no
|
||||
@@ -3068,6 +3073,74 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
Xid_log_event methods
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
void Xid_log_event::pack_info(Protocol *protocol)
|
||||
{
|
||||
char buf[128], *pos;
|
||||
pos= strmov(buf, "COMMIT /* xid=");
|
||||
pos= longlong10_to_str(xid, pos, 10);
|
||||
pos= strmov(pos, " */");
|
||||
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
NOTE it's ok not to use int8store here,
|
||||
as long as xid_t::set(ulonglong) and
|
||||
xid_t::get_my_xid doesn't do it either
|
||||
|
||||
we don't care about actual values of xids as long as
|
||||
identical numbers compare identically
|
||||
*/
|
||||
Xid_log_event::Xid_log_event(const char* buf,
|
||||
const Format_description_log_event* description_event)
|
||||
:Log_event(buf, description_event)
|
||||
{
|
||||
buf+= description_event->common_header_len;
|
||||
xid=*((my_xid *)buf);
|
||||
}
|
||||
|
||||
|
||||
bool Xid_log_event::write(IO_CACHE* file)
|
||||
{
|
||||
return write_header(file, sizeof(xid)) ||
|
||||
my_b_safe_write(file, (byte*) &xid, sizeof(xid));
|
||||
}
|
||||
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
void Xid_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info)
|
||||
{
|
||||
if (!short_form)
|
||||
{
|
||||
char buf[64];
|
||||
longlong10_to_str(xid, buf, 10);
|
||||
|
||||
print_header(file);
|
||||
fprintf(file, "\tXid = %s\n", buf);
|
||||
fflush(file);
|
||||
}
|
||||
fprintf(file, "COMMIT;\n");
|
||||
}
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
|
||||
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
|
||||
int Xid_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
{
|
||||
rli->inc_event_relay_log_pos();
|
||||
/* For a slave Xid_log_event is COMMIT */
|
||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
return ha_commit(thd);
|
||||
}
|
||||
#endif /* !MYSQL_CLIENT */
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
User_var_log_event methods
|
||||
**************************************************************************/
|
||||
|
Reference in New Issue
Block a user