1
/* Copyright (C) 2000-2004 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
19
#include "mysql_priv.h"
23
#ifdef USE_PRAGMA_IMPLEMENTATION
24
#pragma implementation // gcc: Class implementation
27
#include "mysql_priv.h"
31
#include "rpl_filter.h"
32
#include "rpl_utility.h"
33
#include "rpl_record.h"
36
#endif /* MYSQL_CLIENT */
39
#include <my_bitmap.h>
41
#define log_cs &my_charset_latin1
43
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
47
Size of buffer for printing a double in format %.<PREC>g
49
optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
50
exponent digits + '\0'
52
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
55
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
56
static const char *HA_ERR(int i)
59
case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
60
case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
61
case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
62
case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
63
case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
64
case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
65
case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
66
case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
67
case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
68
case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
69
case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
70
case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
71
case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
72
case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
73
case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
74
case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
75
case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
76
case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
77
case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
78
case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
79
case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
80
case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
81
case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
82
case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
83
case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
84
case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
85
case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
86
case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
87
case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
88
case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
89
case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
90
case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
91
case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
92
case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
93
case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
94
case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
95
case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
96
case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
97
case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
98
case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
99
case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
100
case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
101
case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
102
case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
103
case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
104
case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
105
case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
106
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
107
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
108
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
114
Error reporting facility for Rows_log_event::do_apply_event
116
@param level error, warning or info
117
@param ha_error HA_ERR_ code
118
@param rli pointer to the active Relay_log_info instance
119
@param thd pointer to the slave thread's thd
120
@param table pointer to the event's table object
121
@param type the type of the event
122
@param log_name the master binlog file name
123
@param pos the master binlog file pos (the next after the event)
126
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
127
Relay_log_info const *rli, THD *thd,
128
TABLE *table, const char * type,
129
const char *log_name, ulong pos)
131
const char *handler_error= HA_ERR(ha_error);
132
char buff[MAX_SLAVE_ERRMSG], *slider;
133
const char *buff_end= buff + sizeof(buff);
135
List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
139
for (err= it++, slider= buff; err && slider < buff_end - 1;
140
slider += len, err= it++)
142
len= my_snprintf(slider, buff_end - slider,
143
" %s, Error_code: %d;", err->msg, err->code);
146
rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
147
"Could not execute %s event on table %s.%s;"
148
"%s handler error %s; "
149
"the event's master log %s, end_log_pos %lu",
150
type, table->s->db.str,
151
table->s->table_name.str,
153
handler_error == NULL? "<unknown>" : handler_error,
159
Cache that will automatically be written to a dedicated file on
165
class Write_on_release_cache
173
typedef unsigned short flag_set;
179
Write_on_release_cache
180
cache Pointer to cache to use
181
file File to write cache to upon destruction
182
flags Flags for the cache
186
Class used to guarantee copy of cache to file before exiting the
187
current block. On successful copy of the cache, the cache will
188
be reinited as a WRITE_CACHE.
190
Currently, a pointer to the cache is provided in the
191
constructor, but it would be possible to create a subclass
192
holding the IO_CACHE itself.
194
Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
195
: m_cache(cache), m_file(file), m_flags(flags)
197
reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
200
~Write_on_release_cache()
202
copy_event_cache_to_file_and_reinit(m_cache, m_file);
203
if (m_flags | FLUSH_F)
208
Return a pointer to the internal IO_CACHE.
215
Function to return a pointer to the internal cache, so that the
216
object can be treated as a IO_CACHE and used with the my_b_*
220
A pointer to the internal IO_CACHE.
222
IO_CACHE *operator&()
228
// Hidden, to prevent usage.
229
Write_on_release_cache(Write_on_release_cache const&);
237
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
245
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
247
const char* end = str + len;
248
my_b_printf(cache, "\'");
252
switch ((c=*str++)) {
253
case '\n': my_b_printf(cache, "\\n"); break;
254
case '\r': my_b_printf(cache, "\\r"); break;
255
case '\\': my_b_printf(cache, "\\\\"); break;
256
case '\b': my_b_printf(cache, "\\b"); break;
257
case '\t': my_b_printf(cache, "\\t"); break;
258
case '\'': my_b_printf(cache, "\\'"); break;
259
case 0 : my_b_printf(cache, "\\0"); break;
261
my_b_printf(cache, "%c", c);
265
my_b_printf(cache, "\'");
267
#endif /* MYSQL_CLIENT */
269
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
271
static void clear_all_errors(THD *thd, Relay_log_info *rli)
273
thd->is_slave_error = 0;
280
Ignore error code specified on command line.
283
inline int ignored_error_code(int err_code)
285
return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
286
(use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
295
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
296
static char *pretty_print_str(char *packet, const char *str, int len)
298
const char *end= str + len;
304
switch ((c=*str++)) {
305
case '\n': *pos++= '\\'; *pos++= 'n'; break;
306
case '\r': *pos++= '\\'; *pos++= 'r'; break;
307
case '\\': *pos++= '\\'; *pos++= '\\'; break;
308
case '\b': *pos++= '\\'; *pos++= 'b'; break;
309
case '\t': *pos++= '\\'; *pos++= 't'; break;
310
case '\'': *pos++= '\\'; *pos++= '\''; break;
311
case 0 : *pos++= '\\'; *pos++= '0'; break;
320
#endif /* !MYSQL_CLIENT */
323
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
326
Creates a temporary name for load data infile:.
328
@param buf Store new filename here
329
@param file_id File_id (part of file name)
330
@param event_server_id Event_id (part of file name)
331
@param ext Extension for file name
334
Pointer to start of extension
337
static char *slave_load_file_stem(char *buf, uint file_id,
338
int event_server_id, const char *ext)
341
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
345
buf = int10_to_str(::server_id, buf, 10);
347
buf = int10_to_str(event_server_id, buf, 10);
349
res= int10_to_str(file_id, buf, 10);
350
strmov(res, ext); // Add extension last
351
return res; // Pointer to extension
356
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
359
Delete all temporary files used for SQL_LOAD.
362
static void cleanup_load_tmpdir()
367
char fname[FN_REFLEN], prefbuf[31], *p;
369
if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
373
When we are deleting temporary files, we should only remove
374
the files associated with the server id of our server.
375
We don't use event_server_id here because since we've disabled
376
direct binlogging of Create_file/Append_file/Exec_load events
377
we cannot meet Start_log event in the middle of events from one
380
p= strmake(prefbuf, STRING_WITH_LEN("SQL_LOAD-"));
381
p= int10_to_str(::server_id, p, 10);
385
for (i=0 ; i < (uint)dirp->number_off_files; i++)
387
file=dirp->dir_entry+i;
388
if (is_prefix(file->name, prefbuf))
390
fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
391
my_delete(fname, MYF(0));
404
static bool write_str(IO_CACHE *file, const char *str, uint length)
407
tmp[0]= (uchar) length;
408
return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
409
my_b_safe_write(file, (uchar*) str, length));
417
static inline int read_str(const char **buf, const char *buf_end,
418
const char **str, uint8 *len)
420
if (*buf + ((uint) (uchar) **buf) >= buf_end)
424
(*buf)+= (uint) *len+1;
430
Transforms a string into "" or its expression in 0x... form.
433
char *str_to_hex(char *to, const char *from, uint len)
439
to= octet2hex(to, from, len);
442
to= strmov(to, "\"\"");
443
return to; // pointer to end 0 of 'to'
449
Append a version of the 'from' string suitable for use in a query to
450
the 'to' string. To generate a correct escaping, the character set
451
information in 'csinfo' is used.
455
append_query_string(CHARSET_INFO *csinfo,
456
String const *from, String *to)
459
uint32 const orig_len= to->length();
460
if (to->reserve(orig_len + from->length()*2+3))
463
beg= to->c_ptr_quick() + to->length();
465
if (csinfo->escape_with_backslash_is_dangerous)
466
ptr= str_to_hex(ptr, from->ptr(), from->length());
470
ptr+= escape_string_for_mysql(csinfo, ptr, 0,
471
from->ptr(), from->length());
474
to->length(orig_len + ptr - beg);
481
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
482
commands just before it prints a query.
487
static void print_set_option(IO_CACHE* file, uint32 bits_changed,
488
uint32 option, uint32 flags, const char* name,
491
if (bits_changed & option)
494
my_b_printf(file,", ");
495
my_b_printf(file,"%s=%d", name, test(flags & option));
501
/**************************************************************************
502
Log_event methods (= the parent class of all events)
503
**************************************************************************/
507
returns the human readable name of the event's type
510
const char* Log_event::get_type_str(Log_event_type type)
513
case START_EVENT_V3: return "Start_v3";
514
case STOP_EVENT: return "Stop";
515
case QUERY_EVENT: return "Query";
516
case ROTATE_EVENT: return "Rotate";
517
case INTVAR_EVENT: return "Intvar";
518
case LOAD_EVENT: return "Load";
519
case NEW_LOAD_EVENT: return "New_load";
520
case SLAVE_EVENT: return "Slave";
521
case CREATE_FILE_EVENT: return "Create_file";
522
case APPEND_BLOCK_EVENT: return "Append_block";
523
case DELETE_FILE_EVENT: return "Delete_file";
524
case EXEC_LOAD_EVENT: return "Exec_load";
525
case RAND_EVENT: return "RAND";
526
case XID_EVENT: return "Xid";
527
case USER_VAR_EVENT: return "User var";
528
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
529
case TABLE_MAP_EVENT: return "Table_map";
530
case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
531
case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
532
case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
533
case WRITE_ROWS_EVENT: return "Write_rows";
534
case UPDATE_ROWS_EVENT: return "Update_rows";
535
case DELETE_ROWS_EVENT: return "Delete_rows";
536
case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
537
case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
538
case INCIDENT_EVENT: return "Incident";
539
default: return "Unknown"; /* impossible */
543
const char* Log_event::get_type_str()
545
return get_type_str(get_type_code());
550
Log_event::Log_event()
554
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
555
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
557
server_id= thd->server_id;
558
when= thd->start_time;
559
cache_stmt= using_trans;
564
This minimal constructor is for when you are not even sure that there
565
is a valid THD. For example in the server when we are shutting down or
566
flushing logs after receiving a SIGHUP (then we must write a Rotate to
567
the binlog but we have no THD, so we need this minimal constructor).
570
Log_event::Log_event()
571
:temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
574
server_id= ::server_id;
576
We can't call my_time() here as this would cause a call before
582
#endif /* !MYSQL_CLIENT */
586
Log_event::Log_event()
589
Log_event::Log_event(const char* buf,
590
const Format_description_log_event* description_event)
591
:temp_buf(0), cache_stmt(0)
596
when = uint4korr(buf);
597
server_id = uint4korr(buf + SERVER_ID_OFFSET);
598
data_written= uint4korr(buf + EVENT_LEN_OFFSET);
599
if (description_event->binlog_version==1)
606
log_pos= uint4korr(buf + LOG_POS_OFFSET);
608
If the log is 4.0 (so here it can only be a 4.0 relay log read by
609
the SQL thread or a 4.0 master binlog read by the I/O thread),
610
log_pos is the beginning of the event: we transform it into the end
611
of the event, which is more useful.
612
But how do you know that the log is 4.0: you know it if
613
description_event is version 3 *and* you are not reading a
614
Format_desc (remember that mysqlbinlog starts by assuming that 5.0
615
logs are in 4.0 format, until it finds a Format_desc).
617
if (description_event->binlog_version==3 &&
618
buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
621
If log_pos=0, don't change it. log_pos==0 is a marker to mean
622
"don't change rli->group_master_log_pos" (see
623
inc_group_relay_log_pos()). As it is unreal log_pos, adding the
624
event len's is nonsense. For example, a fake Rotate event should
625
not have its log_pos (which is 0) changed or it will modify
626
Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
627
value of (a non-zero offset which does not exist in the master's
628
binlog, so which will cause problems if the user uses this value
631
log_pos+= data_written; /* purecov: inspected */
633
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
635
flags= uint2korr(buf + FLAGS_OFFSET);
636
if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
637
(buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
640
These events always have a header which stops here (i.e. their
644
Initialization to zero of all other Log_event members as they're
645
not specified. Currently there are no such members; in the future
646
there will be an event UID (but Format_description and Rotate
647
don't need this UID, as they are not propagated through
648
--log-slave-updates (remember the UID is used to not play a query
649
twice when you have two masters which are slaves of a 3rd master).
654
/* otherwise, go on with reading the header from buf (nothing now) */
658
#ifdef HAVE_REPLICATION
660
int Log_event::do_update_pos(Relay_log_info *rli)
663
rli is null when (as far as I (Guilhem) know) the caller is
664
Load_log_event::do_apply_event *and* that one is called from
665
Execute_load_log_event::do_apply_event. In this case, we don't
666
do anything here ; Execute_load_log_event::do_apply_event will
667
call Log_event::do_apply_event again later with the proper rli.
668
Strictly speaking, if we were sure that rli is null only in the
669
case discussed above, 'if (rli)' is useless here. But as we are
670
not 100% sure, keep it for now.
672
Matz: I don't think we will need this check with this refactoring.
677
bug#29309 simulation: resetting the flag to force
678
wrong behaviour of artificial event to update
679
rli->last_master_timestamp for only one time -
680
the first FLUSH LOGS in the test.
682
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
683
if (debug_not_change_ts_if_art_event == 1
684
&& is_artificial_event())
686
debug_not_change_ts_if_art_event= 0;
689
rli->stmt_done(log_pos,
690
is_artificial_event() &&
691
debug_not_change_ts_if_art_event > 0 ? 0 : when);
693
rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
695
DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
696
if (debug_not_change_ts_if_art_event == 0)
698
debug_not_change_ts_if_art_event= 2;
701
return 0; // Cannot fail currently
705
Log_event::enum_skip_reason
706
Log_event::do_shall_skip(Relay_log_info *rli)
708
DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
709
" rli->replicate_same_server_id=%d,"
710
" rli->slave_skip_counter=%d",
711
(ulong) server_id, (ulong) ::server_id,
712
rli->replicate_same_server_id,
713
rli->slave_skip_counter));
714
if ((server_id == ::server_id && !rli->replicate_same_server_id) || (rli->slave_skip_counter == 1 && rli->is_in_group()))
715
return EVENT_SKIP_IGNORE;
716
else if (rli->slave_skip_counter > 0)
717
return EVENT_SKIP_COUNT;
719
return EVENT_SKIP_NOT;
724
Log_event::pack_info()
727
void Log_event::pack_info(Protocol *protocol)
729
protocol->store("", &my_charset_bin);
734
Only called by SHOW BINLOG EVENTS
736
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
738
const char *p= strrchr(log_name, FN_LIBCHAR);
739
const char *event_type;
743
protocol->prepare_for_resend();
744
protocol->store(log_name, &my_charset_bin);
745
protocol->store((ulonglong) pos);
746
event_type = get_type_str();
747
protocol->store(event_type, strlen(event_type), &my_charset_bin);
748
protocol->store((uint32) server_id);
749
protocol->store((ulonglong) log_pos);
751
return protocol->write();
753
#endif /* HAVE_REPLICATION */
757
init_show_field_list() prepares the column names and types for the
758
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
762
void Log_event::init_show_field_list(List<Item>* field_list)
764
field_list->push_back(new Item_empty_string("Log_name", 20));
765
field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
766
MYSQL_TYPE_LONGLONG));
767
field_list->push_back(new Item_empty_string("Event_type", 20));
768
field_list->push_back(new Item_return_int("Server_id", 10,
770
field_list->push_back(new Item_return_int("End_log_pos",
771
MY_INT32_NUM_DECIMAL_DIGITS,
772
MYSQL_TYPE_LONGLONG));
773
field_list->push_back(new Item_empty_string("Info", 20));
781
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
783
uchar header[LOG_EVENT_HEADER_LEN];
785
DBUG_ENTER("Log_event::write_header");
787
/* Store number of bytes that will be written by this event */
788
data_written= event_data_length + sizeof(header);
791
log_pos != 0 if this is relay-log event. In this case we should not
795
if (is_artificial_event())
798
We should not do any cleanup on slave when reading this. We
799
mark this by setting log_pos to 0. Start_log_event_v3() will
800
detect this on reading and set artificial_event=1 for the event.
807
Calculate position of end of event
809
Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
810
work well. So this will give slightly wrong positions for the
811
Format_desc/Rotate/Stop events which the slave writes to its
812
relay log. For example, the initial Format_desc will have
813
end_log_pos=91 instead of 95. Because after writing the first 4
814
bytes of the relay log, my_b_tell() still reports 0. Because
815
my_b_append() does not update the counter which my_b_tell()
816
later uses (one should probably use my_b_append_tell() to work
817
around this). To get right positions even when writing to the
818
relay log, we use the (new) my_b_safe_tell().
820
Note that this raises a question on the correctness of all these
821
DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
823
If in a transaction, the log_pos which we calculate below is not
824
very good (because then my_b_safe_tell() returns start position
825
of the BEGIN, so it's like the statement was at the BEGIN's
826
place), but it's not a very serious problem (as the slave, when
827
it is in a transaction, does not take those end_log_pos into
828
account (as it calls inc_event_relay_log_pos()). To be fixed
829
later, so that it looks less strange. But not bug.
832
log_pos= my_b_safe_tell(file)+data_written;
835
now= (ulong) get_time(); // Query start time
838
Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
839
FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
840
LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
841
because we read them before knowing the format).
844
int4store(header, now); // timestamp
845
header[EVENT_TYPE_OFFSET]= get_type_code();
846
int4store(header+ SERVER_ID_OFFSET, server_id);
847
int4store(header+ EVENT_LEN_OFFSET, data_written);
848
int4store(header+ LOG_POS_OFFSET, log_pos);
849
int2store(header+ FLAGS_OFFSET, flags);
851
DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0);
856
This needn't be format-tolerant, because we only read
857
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
860
int Log_event::read_log_event(IO_CACHE* file, String* packet,
861
pthread_mutex_t* log_lock)
865
char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
866
DBUG_ENTER("Log_event::read_log_event");
869
pthread_mutex_lock(log_lock);
870
if (my_b_read(file, (uchar*) buf, sizeof(buf)))
873
If the read hits eof, we must report it as eof so the caller
874
will know it can go into cond_wait to be woken up on the next
877
DBUG_PRINT("error",("file->error: %d", file->error));
879
result= LOG_READ_EOF;
881
result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
884
data_len= uint4korr(buf + EVENT_LEN_OFFSET);
885
if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
886
data_len > current_thd->variables.max_allowed_packet)
888
DBUG_PRINT("error",("data_len: %ld", data_len));
889
result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
894
/* Append the log event header to packet */
895
if (packet->append(buf, sizeof(buf)))
897
/* Failed to allocate packet */
898
result= LOG_READ_MEM;
901
data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
904
/* Append rest of event, read directly from file into packet */
905
if (packet->append(file, data_len))
908
Fatal error occured when appending rest of the event
909
to packet, possible failures:
910
1. EOF occured when reading from file, it's really an error
911
as data_len is >=0 there's supposed to be more bytes available.
912
file->error will have been set to number of bytes left to read
913
2. Read was interrupted, file->error would normally be set to -1
914
3. Failed to allocate memory for packet, my_errno
915
will be ENOMEM(file->error shuold be 0, but since the
916
memory allocation occurs before the call to read it might
919
result= (my_errno == ENOMEM ? LOG_READ_MEM :
920
(file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
921
/* Implicit goto end; */
927
pthread_mutex_unlock(log_lock);
930
#endif /* !MYSQL_CLIENT */
933
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
934
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
943
Allocates memory; The caller is responsible for clean-up.
945
Log_event* Log_event::read_log_event(IO_CACHE* file,
946
pthread_mutex_t* log_lock,
947
const Format_description_log_event
950
Log_event* Log_event::read_log_event(IO_CACHE* file,
951
const Format_description_log_event
955
DBUG_ENTER("Log_event::read_log_event");
956
DBUG_ASSERT(description_event != 0);
957
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
959
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
960
check the event for sanity and to know its length; no need to really parse
961
it. We say "at most" because this could be a 3.23 master, which has header
962
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
963
"minimal" over the set {MySQL >=4.0}).
965
uint header_size= min(description_event->common_header_len,
966
LOG_EVENT_MINIMAL_HEADER_LEN);
969
DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
970
if (my_b_read(file, (uchar *) head, header_size))
972
DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
976
No error here; it could be that we are at the file's end. However
977
if the next my_b_read() fails (below), it will be an error as we
978
were able to read the first bytes.
982
uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
984
const char *error= 0;
986
#ifndef max_allowed_packet
987
THD *thd=current_thd;
988
uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
991
if (data_len > max_allowed_packet)
993
error = "Event too big";
997
if (data_len < header_size)
999
error = "Event too small";
1003
// some events use the extra byte to null-terminate strings
1004
if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
1006
error = "Out of memory";
1010
memcpy(buf, head, header_size);
1011
if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1013
error = "read error";
1016
if ((res= read_log_event(buf, data_len, &error, description_event)))
1017
res->register_temp_buf(buf);
1023
DBUG_ASSERT(error != 0);
1024
sql_print_error("Error in Log_event::read_log_event(): "
1025
"'%s', data_len: %d, event_type: %d",
1026
error,data_len,head[EVENT_TYPE_OFFSET]);
1027
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1029
The SQL slave thread will check if file->error<0 to know
1030
if there was an I/O error. Even if there is no "low-level" I/O errors
1031
with 'file', any of the high-level above errors is worrying
1032
enough to stop the SQL thread now ; as we are skipping the current event,
1033
going on with reading and successfully executing other events can
1034
only corrupt the slave's databases. So stop.
1043
Binlog format tolerance is in (buf, event_len, description_event)
1047
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1049
const Format_description_log_event *description_event)
1052
DBUG_ENTER("Log_event::read_log_event(char*,...)");
1053
DBUG_ASSERT(description_event != 0);
1054
DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1055
DBUG_DUMP("data", (unsigned char*) buf, event_len);
1057
/* Check the integrity */
1058
if (event_len < EVENT_LEN_OFFSET ||
1059
buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
1060
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1062
*error="Sanity check failed"; // Needed to free buffer
1063
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1066
uint event_type= buf[EVENT_TYPE_OFFSET];
1067
if (event_type > description_event->number_of_event_types &&
1068
event_type != FORMAT_DESCRIPTION_EVENT)
1071
It is unsafe to use the description_event if its post_header_len
1072
array does not include the event type.
1074
DBUG_PRINT("error", ("event type %d found, but the current "
1075
"Format_description_log_event supports only %d event "
1076
"types", event_type,
1077
description_event->number_of_event_types));
1083
In some previuos versions (see comment in
1084
Format_description_log_event::Format_description_log_event(char*,...)),
1085
event types were assigned different id numbers than in the
1086
present version. In order to replicate from such versions to the
1087
present version, we must map those event type id's to our event
1088
type id's. The mapping is done with the event_type_permutation
1089
array, which was set up when the Format_description_log_event
1092
if (description_event->event_type_permutation)
1096
description_event->event_type_permutation[event_type];
1098
("converting event type %d to %d (%s)",
1099
event_type, new_event_type,
1100
get_type_str((Log_event_type)new_event_type)));
1102
event_type= description_event->event_type_permutation[event_type];
1105
switch(event_type) {
1107
ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1110
ev = new Load_log_event(buf, event_len, description_event);
1112
case NEW_LOAD_EVENT:
1113
ev = new Load_log_event(buf, event_len, description_event);
1116
ev = new Rotate_log_event(buf, event_len, description_event);
1118
#ifdef HAVE_REPLICATION
1119
case SLAVE_EVENT: /* can never happen (unused event) */
1120
ev = new Slave_log_event(buf, event_len);
1122
#endif /* HAVE_REPLICATION */
1123
case CREATE_FILE_EVENT:
1124
ev = new Create_file_log_event(buf, event_len, description_event);
1126
case APPEND_BLOCK_EVENT:
1127
ev = new Append_block_log_event(buf, event_len, description_event);
1129
case DELETE_FILE_EVENT:
1130
ev = new Delete_file_log_event(buf, event_len, description_event);
1132
case EXEC_LOAD_EVENT:
1133
ev = new Execute_load_log_event(buf, event_len, description_event);
1135
case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1136
ev = new Start_log_event_v3(buf, description_event);
1139
ev = new Stop_log_event(buf, description_event);
1142
ev = new Intvar_log_event(buf, description_event);
1145
ev = new Xid_log_event(buf, description_event);
1148
ev = new Rand_log_event(buf, description_event);
1150
case USER_VAR_EVENT:
1151
ev = new User_var_log_event(buf, description_event);
1153
case FORMAT_DESCRIPTION_EVENT:
1154
ev = new Format_description_log_event(buf, event_len, description_event);
1156
#if defined(HAVE_REPLICATION)
1157
case WRITE_ROWS_EVENT:
1158
ev = new Write_rows_log_event(buf, event_len, description_event);
1160
case UPDATE_ROWS_EVENT:
1161
ev = new Update_rows_log_event(buf, event_len, description_event);
1163
case DELETE_ROWS_EVENT:
1164
ev = new Delete_rows_log_event(buf, event_len, description_event);
1166
case TABLE_MAP_EVENT:
1167
ev = new Table_map_log_event(buf, event_len, description_event);
1170
case BEGIN_LOAD_QUERY_EVENT:
1171
ev = new Begin_load_query_log_event(buf, event_len, description_event);
1173
case EXECUTE_LOAD_QUERY_EVENT:
1174
ev= new Execute_load_query_log_event(buf, event_len, description_event);
1176
case INCIDENT_EVENT:
1177
ev = new Incident_log_event(buf, event_len, description_event);
1180
DBUG_PRINT("error",("Unknown event code: %d",
1181
(int) buf[EVENT_TYPE_OFFSET]));
1187
DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1188
ev ? ev->get_type_str() : "<unknown>",
1189
buf[EVENT_TYPE_OFFSET],
1192
is_valid() are small event-specific sanity tests which are
1193
important; for example there are some my_malloc() in constructors
1194
(e.g. Query_log_event::Query_log_event(char*...)); when these
1195
my_malloc() fail we can't return an error out of the constructor
1196
(because constructor is "void") ; so instead we leave the pointer we
1197
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1198
Same for Format_description_log_event, member 'post_header_len'.
1200
if (!ev || !ev->is_valid())
1202
DBUG_PRINT("error",("Found invalid event in binary log"));
1206
if (!force_opt) /* then mysqlbinlog dies */
1208
*error= "Found invalid event in binary log";
1211
ev= new Unknown_log_event(buf, description_event);
1213
*error= "Found invalid event in binary log";
1223
Log_event::print_header()
1226
void Log_event::print_header(IO_CACHE* file,
1227
PRINT_EVENT_INFO* print_event_info,
1228
bool is_more __attribute__((unused)))
1231
my_off_t hexdump_from= print_event_info->hexdump_from;
1232
DBUG_ENTER("Log_event::print_header");
1234
my_b_printf(file, "#");
1235
print_timestamp(file);
1236
my_b_printf(file, " server id %d end_log_pos %s ", server_id,
1237
llstr(log_pos,llbuff));
1239
/* mysqlbinlog --hexdump */
1240
if (print_event_info->hexdump_from)
1242
my_b_printf(file, "\n");
1243
uchar *ptr= (uchar*)temp_buf;
1245
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1248
/* Header len * 4 >= header len * (2 chars + space + extra space) */
1249
char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
1250
char *c, char_string[16+1]= {0};
1252
/* Pretty-print event common header if header is exactly 19 bytes */
1253
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1255
char emit_buf[256]; // Enough for storing one line
1256
my_b_printf(file, "# Position Timestamp Type Master ID "
1257
"Size Master Pos Flags \n");
1258
int const bytes_written=
1259
my_snprintf(emit_buf, sizeof(emit_buf),
1260
"# %8.8lx %02x %02x %02x %02x %02x "
1261
"%02x %02x %02x %02x %02x %02x %02x %02x "
1262
"%02x %02x %02x %02x %02x %02x\n",
1263
(unsigned long) hexdump_from,
1264
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1265
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1266
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1267
DBUG_ASSERT(bytes_written >= 0);
1268
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1269
my_b_write(file, (uchar*) emit_buf, bytes_written);
1270
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1271
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1274
/* Rest of event (without common header) */
1275
for (i= 0, c= char_string, h=hex_string;
1279
my_snprintf(h, 4, "%02x ", *ptr);
1282
*c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1287
my_b_printf() does not support full printf() formats, so we
1288
have to do it this way.
1290
TODO: Rewrite my_b_printf() to support full printf() syntax.
1293
int const bytes_written=
1294
my_snprintf(emit_buf, sizeof(emit_buf),
1295
"# %8.8lx %-48.48s |%16s|\n",
1296
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1297
hex_string, char_string);
1298
DBUG_ASSERT(bytes_written >= 0);
1299
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1300
my_b_write(file, (uchar*) emit_buf, bytes_written);
1306
else if (i % 8 == 7) *h++ = ' ';
1313
int const bytes_written=
1314
my_snprintf(emit_buf, sizeof(emit_buf),
1315
"# %8.8lx %-48.48s |%s|\n",
1316
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1317
hex_string, char_string);
1318
DBUG_ASSERT(bytes_written >= 0);
1319
DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1320
my_b_write(file, (uchar*) emit_buf, bytes_written);
1323
need a # to prefix the rest of printouts for example those of
1324
Rows_log_event::print_helper().
1326
my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1332
void Log_event::print_base64(IO_CACHE* file,
1333
PRINT_EVENT_INFO* print_event_info,
1336
const uchar *ptr= (const uchar *)temp_buf;
1337
uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
1338
DBUG_ENTER("Log_event::print_base64");
1340
size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
1341
char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
1343
fprintf(stderr, "\nError: Out of memory. "
1344
"Could not print correct binlog event.\n");
1348
if (base64_encode(ptr, (size_t) size, tmp_str))
1353
if (my_b_tell(file) == 0)
1354
my_b_printf(file, "\nBINLOG '\n");
1356
my_b_printf(file, "%s\n", tmp_str);
1359
my_b_printf(file, "'%s\n", print_event_info->delimiter);
1361
my_free(tmp_str, MYF(0));
1367
Log_event::print_timestamp()
1370
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
1373
DBUG_ENTER("Log_event::print_timestamp");
1376
#ifdef MYSQL_SERVER // This is always false
1378
localtime_r(ts,(res= &tm_tmp));
1383
my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
1393
#endif /* MYSQL_CLIENT */
1396
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1397
inline Log_event::enum_skip_reason
1398
Log_event::continue_group(Relay_log_info *rli)
1400
if (rli->slave_skip_counter == 1)
1401
return Log_event::EVENT_SKIP_IGNORE;
1402
return Log_event::do_shall_skip(rli);
1406
/**************************************************************************
1407
Query_log_event methods
1408
**************************************************************************/
1410
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1413
This (which is used only for SHOW BINLOG EVENTS) could be updated to
1414
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1415
only an information, it does not produce suitable queries to replay (for
1416
example it does not print LOAD DATA INFILE).
1421
void Query_log_event::pack_info(Protocol *protocol)
1423
// TODO: show the catalog ??
1425
if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
1428
if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1431
pos= strmov(buf, "use `");
1432
memcpy(pos, db, db_len);
1433
pos= strmov(pos+db_len, "`; ");
1437
memcpy(pos, query, q_len);
1440
protocol->store(buf, pos-buf, &my_charset_bin);
1441
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1445
#ifndef MYSQL_CLIENT
1448
Utility function for the next method (Query_log_event::write()) .
1450
static void write_str_with_code_and_len(char **dst, const char *src,
1455
*((*dst)++)= (uchar) len;
1456
bmove(*dst, src, len);
1462
Query_log_event::write().
1465
In this event we have to modify the header to have the correct
1466
EVENT_LEN_OFFSET as we don't yet know how many status variables we
1470
bool Query_log_event::write(IO_CACHE* file)
1473
@todo if catalog can be of length FN_REFLEN==512, then we are not
1474
replicating it correctly, since the length is stored in a byte
1477
uchar buf[QUERY_HEADER_LEN+
1478
1+4+ // code of flags2 and flags2
1479
1+8+ // code of sql_mode and sql_mode
1480
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1481
1+4+ // code of autoinc and the 2 autoinc variables
1482
1+6+ // code of charset and charset
1483
1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
1484
1+2+ // code of lc_time_names and lc_time_names_number
1485
1+2 // code of charset_database and charset_database_number
1486
], *start, *start_of_status;
1490
return 1; // Something wrong with event
1493
We want to store the thread id:
1494
(- as an information for the user when he reads the binlog)
1495
- if the query uses temporary table: for the slave SQL thread to know to
1496
which master connection the temp table belongs.
1497
Now imagine we (write()) are called by the slave SQL thread (we are
1498
logging a query executed by this thread; the slave runs with
1499
--log-slave-updates). Then this query will be logged with
1500
thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
1501
the same name were created simultaneously on the master (in the master
1503
CREATE TEMPORARY TABLE t; (thread 1)
1504
CREATE TEMPORARY TABLE t; (thread 2)
1506
then in the slave's binlog there will be
1507
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
1508
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
1509
which is bad (same thread id!).
1511
To avoid this, we log the thread's thread id EXCEPT for the SQL
1512
slave thread for which we log the original (master's) thread id.
1513
Now this moves the bug: what happens if the thread id on the
1514
master was 10 and when the slave replicates the query, a
1515
connection number 10 is opened by a normal client on the slave,
1516
and updates a temp table of the same name? We get a problem
1517
again. To avoid this, in the handling of temp tables (sql_base.cc)
1518
we use thread_id AND server_id. TODO when this is merged into
1519
4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
1520
and is a session variable: that's to make mysqlbinlog work with
1521
temp tables. We probably need to introduce
1523
SET PSEUDO_SERVER_ID
1524
for mysqlbinlog in 4.1. mysqlbinlog would print:
1525
SET PSEUDO_SERVER_ID=
1526
SET PSEUDO_THREAD_ID=
1527
for each query using temp tables.
1529
int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
1530
int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
1531
buf[Q_DB_LEN_OFFSET] = (char) db_len;
1532
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
1535
You MUST always write status vars in increasing order of code. This
1536
guarantees that a slightly older slave will be able to parse those he
1539
start_of_status= start= buf+QUERY_HEADER_LEN;
1542
*start++= Q_FLAGS2_CODE;
1543
int4store(start, flags2);
1546
if (sql_mode_inited)
1548
*start++= Q_SQL_MODE_CODE;
1549
int8store(start, (ulonglong)sql_mode);
1552
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1554
write_str_with_code_and_len((char **)(&start),
1555
catalog, catalog_len, Q_CATALOG_NZ_CODE);
1557
In 5.0.x where x<4 masters we used to store the end zero here. This was
1558
a waste of one byte so we don't do it in x>=4 masters. We change code to
1559
Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
1560
of this x>=4 master segfault (expecting a zero when there is
1561
none). Remaining compatibility problems are: the older slave will not
1562
find the catalog; but it is will not crash, and it's not an issue
1563
that it does not find the catalog as catalogs were not used in these
1564
older MySQL versions (we store it in binlog and read it from relay log
1565
but do nothing useful with it). What is an issue is that the older slave
1566
will stop processing the Q_* blocks (and jumps to the db/query) as soon
1567
as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
1568
Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
1569
various ways. Documented that you should not mix alpha/beta versions if
1570
they are not exactly the same version, with example of 5.0.3->5.0.2 and
1571
5.0.4->5.0.3. If replication is from older to new, the new will
1572
recognize Q_CATALOG_CODE and have no problem.
1575
if (auto_increment_increment != 1 || auto_increment_offset != 1)
1577
*start++= Q_AUTO_INCREMENT;
1578
int2store(start, auto_increment_increment);
1579
int2store(start+2, auto_increment_offset);
1584
*start++= Q_CHARSET_CODE;
1585
memcpy(start, charset, 6);
1590
/* In the TZ sys table, column Name is of length 64 so this should be ok */
1591
DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1592
*start++= Q_TIME_ZONE_CODE;
1593
*start++= time_zone_len;
1594
memcpy(start, time_zone_str, time_zone_len);
1595
start+= time_zone_len;
1597
if (lc_time_names_number)
1599
DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
1600
*start++= Q_LC_TIME_NAMES_CODE;
1601
int2store(start, lc_time_names_number);
1604
if (charset_database_number)
1606
DBUG_ASSERT(charset_database_number <= 0xFFFF);
1607
*start++= Q_CHARSET_DATABASE_CODE;
1608
int2store(start, charset_database_number);
1612
Here there could be code like
1613
if (command-line-option-which-says-"log_this_variable" && inited)
1615
*start++= Q_THIS_VARIABLE_CODE;
1616
int4store(start, this_variable);
1621
/* Store length of status variables */
1622
status_vars_len= (uint) (start-start_of_status);
1623
DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
1624
int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
1627
Calculate length of whole event
1628
The "1" below is the \0 in the db's length
1630
event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1632
return (write_header(file, event_length) ||
1633
my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1634
write_post_header_for_derived(file) ||
1635
my_b_safe_write(file, (uchar*) start_of_status,
1636
(uint) (start-start_of_status)) ||
1637
my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
1638
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1642
The simplest constructor that could possibly work. This is used for
1643
creating static objects that have a special meaning and are invisible
1646
Query_log_event::Query_log_event()
1647
:Log_event(), data_buf(0)
1654
Query_log_event::Query_log_event()
1655
thd_arg - thread handle
1656
query_arg - array of char representing the query
1657
query_length - size of the `query_arg' array
1658
using_trans - there is a modified transactional table
1659
suppress_use - suppress the generation of 'USE' statements
1660
killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
1661
if the value is different from the default, the arg
1662
is set to the current thd->killed value.
1663
A caller might need to masquerade thd->killed with
1666
Creates an event for binlogging
1667
The value for local `killed_status' can be supplied by caller.
1669
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
1670
ulong query_length, bool using_trans,
1672
THD::killed_state killed_status_arg)
1674
(thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1676
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1678
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1679
db(thd_arg->db), q_len((uint32) query_length),
1680
thread_id(thd_arg->thread_id),
1681
/* save the original thread id; we already know the server id */
1682
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1683
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1685
auto_increment_increment(thd_arg->variables.auto_increment_increment),
1686
auto_increment_offset(thd_arg->variables.auto_increment_offset),
1687
lc_time_names_number(thd_arg->variables.lc_time_names->number),
1688
charset_database_number(0)
1692
if (killed_status_arg == THD::KILLED_NO_VALUE)
1693
killed_status_arg= thd_arg->killed;
1695
(killed_status_arg == THD::NOT_KILLED) ?
1696
(thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1697
((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
1698
thd_arg->killed_errno());
1701
exec_time = (ulong) (end_time - thd_arg->start_time);
1703
@todo this means that if we have no catalog, then it is replicated
1704
as an existing catalog of length zero. is that safe? /sven
1706
catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
1707
/* status_vars_len is set just before writing the event */
1708
db_len = (db) ? (uint32) strlen(db) : 0;
1709
if (thd_arg->variables.collation_database != thd_arg->db_charset)
1710
charset_database_number= thd_arg->variables.collation_database->number;
1713
If we don't use flags2 for anything else than options contained in
1714
thd_arg->options, it would be more efficient to flags2=thd_arg->options
1715
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1716
But it's likely that we don't want to use 32 bits for 3 bits; in the future
1717
we will probably want to reclaim the 29 bits. So we need the &.
1719
flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1720
DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
1721
DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
1722
DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
1723
DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
1724
int2store(charset, thd_arg->variables.character_set_client->number);
1725
int2store(charset+2, thd_arg->variables.collation_connection->number);
1726
int2store(charset+4, thd_arg->variables.collation_server->number);
1727
if (thd_arg->time_zone_used)
1730
Note that our event becomes dependent on the Time_zone object
1731
representing the time zone. Fortunately such objects are never deleted
1732
or changed during mysqld's lifetime.
1734
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
1735
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
1739
DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %lu",
1740
(ulong) flags2, sql_mode));
1742
#endif /* MYSQL_CLIENT */
1745
/* 2 utility functions for the next method */
1748
Read a string with length from memory.
1750
This function reads the string-with-length stored at
1751
<code>src</code> and extract the length into <code>*len</code> and
1752
a pointer to the start of the string into <code>*dst</code>. The
1753
string can then be copied using <code>memcpy()</code> with the
1754
number of bytes given in <code>*len</code>.
1756
@param src Pointer to variable holding a pointer to the memory to
1757
read the string from.
1758
@param dst Pointer to variable holding a pointer where the actual
1759
string starts. Starting from this position, the string
1760
can be copied using @c memcpy().
1761
@param len Pointer to variable where the length will be stored.
1762
@param end One-past-the-end of the memory where the string is
1765
@return Zero if the entire string can be copied successfully,
1766
@c UINT_MAX if the length could not be read from memory
1767
(that is, if <code>*src >= end</code>), otherwise the
1768
number of bytes that are missing to read the full
1769
string, which happends <code>*dst + *len >= end</code>.
1772
get_str_len_and_pointer(const Log_event::Byte **src,
1775
const Log_event::Byte *end)
1778
return -1; // Will be UINT_MAX in two-complement arithmetics
1782
if (*src + length >= end)
1783
return *src + length - end + 1; // Number of bytes missing
1784
*dst= (char *)*src + 1; // Will be copied later
1791
static void copy_str_and_move(const char **src,
1792
Log_event::Byte **dst,
1795
memcpy(*dst, *src, len);
1796
*src= (const char *)*dst;
1806
static char buf[255];
1808
case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
1809
case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
1810
case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
1811
case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
1812
case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
1813
case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
1814
case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
1815
case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
1816
case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
1818
sprintf(buf, "CODE#%d", code);
1824
Macro to check that there is enough space to read from memory.
1826
@param PTR Pointer to memory
1827
@param END End of memory
1828
@param CNT Number of bytes that should be read.
1830
#define CHECK_SPACE(PTR,END,CNT) \
1832
DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
1833
DBUG_ASSERT((PTR) + (CNT) <= (END)); \
1834
if ((PTR) + (CNT) > (END)) { \
1835
DBUG_PRINT("info", ("query= 0")); \
1843
This is used by the SQL slave thread to prepare the event before execution.
1845
Query_log_event::Query_log_event(const char* buf, uint event_len,
1846
const Format_description_log_event
1848
Log_event_type event_type)
1849
:Log_event(buf, description_event), data_buf(0), query(NullS),
1850
db(NullS), catalog_len(0), status_vars_len(0),
1851
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1852
auto_increment_increment(1), auto_increment_offset(1),
1853
time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1857
uint8 common_header_len, post_header_len;
1858
Log_event::Byte *start;
1859
const Log_event::Byte *end;
1861
DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
1863
common_header_len= description_event->common_header_len;
1864
post_header_len= description_event->post_header_len[event_type-1];
1865
DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
1866
event_len, common_header_len, post_header_len));
1869
We test if the event's length is sensible, and if so we compute data_len.
1870
We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
1871
We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
1873
if (event_len < (uint)(common_header_len + post_header_len))
1875
data_len = event_len - (common_header_len + post_header_len);
1876
buf+= common_header_len;
1878
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
1879
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
1880
db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
1881
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
1884
5.0 format starts here.
1885
Depending on the format, we may or not have affected/warnings etc
1886
The remnent post-header to be parsed has length:
1888
tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
1891
status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
1893
Check if status variable length is corrupt and will lead to very
1894
wrong data. We could be even more strict and require data_len to
1895
be even bigger, but this will suffice to catch most corruption
1896
errors that can lead to a crash.
1898
if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
1900
DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
1901
status_vars_len, data_len));
1905
data_len-= status_vars_len;
1906
DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
1907
(uint) status_vars_len));
1911
We have parsed everything we know in the post header for QUERY_EVENT,
1912
the rest of post header is either comes from older version MySQL or
1913
dedicated to derived events (e.g. Execute_load_query...)
1916
/* variable-part: the status vars; only in MySQL 5.0 */
1918
start= (Log_event::Byte*) (buf+post_header_len);
1919
end= (const Log_event::Byte*) (start+status_vars_len);
1920
for (const Log_event::Byte* pos= start; pos < end;)
1924
CHECK_SPACE(pos, end, 4);
1926
flags2= uint4korr(pos);
1927
DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
1930
case Q_SQL_MODE_CODE:
1935
CHECK_SPACE(pos, end, 8);
1937
sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong
1938
DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
1939
llstr(sql_mode, buff)));
1943
case Q_CATALOG_NZ_CODE:
1944
DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
1945
(ulong) pos, (ulong) end));
1946
if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
1948
DBUG_PRINT("info", ("query= 0"));
1953
case Q_AUTO_INCREMENT:
1954
CHECK_SPACE(pos, end, 4);
1955
auto_increment_increment= uint2korr(pos);
1956
auto_increment_offset= uint2korr(pos+2);
1959
case Q_CHARSET_CODE:
1961
CHECK_SPACE(pos, end, 6);
1963
memcpy(charset, pos, 6);
1967
case Q_TIME_ZONE_CODE:
1969
if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1971
DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
1977
case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
1978
CHECK_SPACE(pos, end, 1);
1979
if ((catalog_len= *pos))
1980
catalog= (char*) pos+1; // Will be copied later
1981
CHECK_SPACE(pos, end, catalog_len + 2);
1982
pos+= catalog_len+2; // leap over end 0
1983
catalog_nz= 0; // catalog has end 0 in event
1985
case Q_LC_TIME_NAMES_CODE:
1986
CHECK_SPACE(pos, end, 2);
1987
lc_time_names_number= uint2korr(pos);
1990
case Q_CHARSET_DATABASE_CODE:
1991
CHECK_SPACE(pos, end, 2);
1992
charset_database_number= uint2korr(pos);
1996
/* That's why you must write status vars in growing order of code */
1997
DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
1998
code: %u), skipping the rest of them", (uint) *(pos-1)));
1999
pos= (const uchar*) end; // Break loop
2003
if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
2008
if (catalog_len) // If catalog is given
2011
@todo we should clean up and do only copy_str_and_move; it
2012
works for both cases. Then we can remove the catalog_nz
2015
if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
2016
copy_str_and_move(&catalog, &start, catalog_len);
2019
memcpy(start, catalog, catalog_len+1); // copy end 0
2020
catalog= (const char *)start;
2021
start+= catalog_len+1;
2025
copy_str_and_move(&time_zone_str, &start, time_zone_len);
2028
if time_zone_len or catalog_len are 0, then time_zone and catalog
2029
are uninitialized at this point. shouldn't they point to the
2030
zero-length null-terminated strings we allocated space for in the
2031
my_alloc call above? /sven
2034
/* A 2nd variable part; this is common to all versions */
2035
memcpy((char*) start, end, data_len); // Copy db and query
2036
start[data_len]= '\0'; // End query with \0 (For safetly)
2038
query= (char *)(start + db_len + 1);
2039
q_len= data_len - db_len -1;
2046
Query_log_event::print().
2049
print the catalog ??
2051
void Query_log_event::print_query_header(IO_CACHE* file,
2052
PRINT_EVENT_INFO* print_event_info)
2054
// TODO: print the catalog ??
2055
char buff[40],*end; // Enough for SET TIMESTAMP
2056
bool different_db= 1;
2059
if (!print_event_info->short_form)
2061
print_header(file, print_event_info, FALSE);
2062
my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
2063
get_type_str(), (ulong) thread_id, (ulong) exec_time,
2067
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
2069
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
2070
memcpy(print_event_info->db, db, db_len + 1);
2071
if (db[0] && different_db)
2072
my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
2075
end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
2076
end= strmov(end, print_event_info->delimiter);
2078
my_b_write(file, (uchar*) buff, (uint) (end-buff));
2079
if ((!print_event_info->thread_id_printed ||
2080
((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
2081
thread_id != print_event_info->thread_id)))
2083
// If --short-form, print deterministic value instead of pseudo_thread_id.
2084
my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
2085
short_form ? 999999999 : (ulong)thread_id,
2086
print_event_info->delimiter);
2087
print_event_info->thread_id= thread_id;
2088
print_event_info->thread_id_printed= 1;
2092
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
2093
print (remember we don't produce mixed relay logs so there cannot be
2094
5.0 events before that one so there is nothing to reset).
2096
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
2098
/* tmp is a bitmask of bits which have changed. */
2099
if (likely(print_event_info->flags2_inited))
2100
/* All bits which have changed */
2101
tmp= (print_event_info->flags2) ^ flags2;
2102
else /* that's the first Query event we read */
2104
print_event_info->flags2_inited= 1;
2105
tmp= ~((uint32)0); /* all bits have changed */
2108
if (unlikely(tmp)) /* some bits have changed */
2111
my_b_printf(file, "SET ");
2112
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
2113
"@@session.foreign_key_checks", &need_comma);
2114
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
2115
"@@session.sql_auto_is_null", &need_comma);
2116
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
2117
"@@session.unique_checks", &need_comma);
2118
my_b_printf(file,"%s\n", print_event_info->delimiter);
2119
print_event_info->flags2= flags2;
2124
Now the session variables;
2125
it's more efficient to pass SQL_MODE as a number instead of a
2126
comma-separated list.
2127
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
2128
variables (they have no global version; they're not listed in
2129
sql_class.h), The tests below work for pure binlogs or pure relay
2130
logs. Won't work for mixed relay logs but we don't create mixed
2131
relay logs (that is, there is no relay log with a format change
2132
except within the 3 first events, which mysqlbinlog handles
2133
gracefully). So this code should always be good.
2136
if (print_event_info->auto_increment_increment != auto_increment_increment ||
2137
print_event_info->auto_increment_offset != auto_increment_offset)
2139
my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
2140
auto_increment_increment,auto_increment_offset,
2141
print_event_info->delimiter);
2142
print_event_info->auto_increment_increment= auto_increment_increment;
2143
print_event_info->auto_increment_offset= auto_increment_offset;
2146
/* TODO: print the catalog when we feature SET CATALOG */
2148
if (likely(charset_inited) &&
2149
(unlikely(!print_event_info->charset_inited ||
2150
bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
2152
CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
2155
/* for mysql client */
2156
my_b_printf(file, "/*!\\C %s */%s\n",
2157
cs_info->csname, print_event_info->delimiter);
2159
my_b_printf(file,"SET "
2160
"@@session.character_set_client=%d,"
2161
"@@session.collation_connection=%d,"
2162
"@@session.collation_server=%d"
2165
uint2korr(charset+2),
2166
uint2korr(charset+4),
2167
print_event_info->delimiter);
2168
memcpy(print_event_info->charset, charset, 6);
2169
print_event_info->charset_inited= 1;
2173
if (bcmp((uchar*) print_event_info->time_zone_str,
2174
(uchar*) time_zone_str, time_zone_len+1))
2176
my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
2177
time_zone_str, print_event_info->delimiter);
2178
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
2181
if (lc_time_names_number != print_event_info->lc_time_names_number)
2183
my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
2184
lc_time_names_number, print_event_info->delimiter);
2185
print_event_info->lc_time_names_number= lc_time_names_number;
2187
if (charset_database_number != print_event_info->charset_database_number)
2189
if (charset_database_number)
2190
my_b_printf(file, "SET @@session.collation_database=%d%s\n",
2191
charset_database_number, print_event_info->delimiter);
2193
my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
2194
print_event_info->delimiter);
2195
print_event_info->charset_database_number= charset_database_number;
2200
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2202
Write_on_release_cache cache(&print_event_info->head_cache, file);
2204
print_query_header(&cache, print_event_info);
2205
my_b_write(&cache, (uchar*) query, q_len);
2206
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
2208
#endif /* MYSQL_CLIENT */
2212
Query_log_event::do_apply_event()
2215
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2217
int Query_log_event::do_apply_event(Relay_log_info const *rli)
2219
return do_apply_event(rli, query, q_len);
2225
Compare the values of "affected rows" around here. Something
2228
if ((uint32) affected_in_event != (uint32) affected_on_slave)
2230
sql_print_error("Slave: did not get the expected number of affected \
2231
rows running query from master - expected %d, got %d (this numbers \
2232
should have matched modulo 4294967296).", 0, ...);
2233
thd->query_error = 1;
2236
We may also want an option to tell the slave to ignore "affected"
2237
mismatch. This mismatch could be implemented with a new ER_ code, and
2238
to ignore it you would use --slave-skip-errors...
2240
int Query_log_event::do_apply_event(Relay_log_info const *rli,
2241
const char *query_arg, uint32 q_len_arg)
2244
int expected_error,actual_error= 0;
2246
Colleagues: please never free(thd->catalog) in MySQL. This would
2247
lead to bugs as here thd->catalog is a part of an alloced block,
2248
not an entire alloced block (see
2249
Query_log_event::do_apply_event()). Same for thd->db. Thank
2252
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
2253
new_db.length= db_len;
2254
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2255
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
2256
thd->variables.auto_increment_increment= auto_increment_increment;
2257
thd->variables.auto_increment_offset= auto_increment_offset;
2260
InnoDB internally stores the master log position it has executed so far,
2261
i.e. the position just after the COMMIT event.
2262
When InnoDB will want to store, the positions in rli won't have
2263
been updated yet, so group_master_log_* will point to old BEGIN
2264
and event_master_log* will point to the beginning of current COMMIT.
2265
But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
2266
END of the current log event (COMMIT). We save it in rli so that InnoDB can
2269
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
2270
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
2272
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2273
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
2276
Note: We do not need to execute reset_one_shot_variables() if this
2278
Reason: The db stored in binlog events is the same for SET and for
2279
its companion query. If the SET is ignored because of
2280
db_ok(), the companion query will also be ignored, and if
2281
the companion query is ignored in the db_ok() test of
2282
::do_apply_event(), then the companion SET also have so
2283
we don't need to reset_one_shot_variables().
2285
if (rpl_filter->db_ok(thd->db))
2287
thd->set_time((time_t)when);
2288
thd->query_length= q_len_arg;
2289
thd->query= (char*)query_arg;
2290
VOID(pthread_mutex_lock(&LOCK_thread_count));
2291
thd->query_id = next_query_id();
2292
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2293
thd->variables.pseudo_thread_id= thread_id; // for temp tables
2294
DBUG_PRINT("query",("%s",thd->query));
2296
if (ignored_error_code((expected_error= error_code)) ||
2297
!check_expected_error(thd,rli,expected_error))
2301
all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
2302
must take their value from flags2.
2304
thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2306
else, we are in a 3.23/4.0 binlog; we previously received a
2307
Rotate_log_event which reset thd->options and sql_mode etc, so
2312
if (rli->cached_charset_compare(charset))
2314
/* Verify that we support the charsets found in the event. */
2315
if (!(thd->variables.character_set_client=
2316
get_charset(uint2korr(charset), MYF(MY_WME))) ||
2317
!(thd->variables.collation_connection=
2318
get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
2319
!(thd->variables.collation_server=
2320
get_charset(uint2korr(charset+4), MYF(MY_WME))))
2323
We updated the thd->variables with nonsensical values (0). Let's
2324
set them to something safe (i.e. which avoids crash), and we'll
2325
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
2328
set_slave_thread_default_charset(thd, rli);
2329
goto compare_errors;
2331
thd->update_charset(); // for the charset change to take effect
2336
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
2337
if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
2339
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
2340
thd->variables.time_zone= global_system_variables.time_zone;
2341
goto compare_errors;
2344
if (lc_time_names_number)
2346
if (!(thd->variables.lc_time_names=
2347
my_locale_by_number(lc_time_names_number)))
2349
my_printf_error(ER_UNKNOWN_ERROR,
2350
"Unknown locale: '%d'", MYF(0), lc_time_names_number);
2351
thd->variables.lc_time_names= &my_locale_en_US;
2352
goto compare_errors;
2356
thd->variables.lc_time_names= &my_locale_en_US;
2357
if (charset_database_number)
2360
if (!(cs= get_charset(charset_database_number, MYF(0))))
2363
int10_to_str((int) charset_database_number, buf, -10);
2364
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
2365
goto compare_errors;
2367
thd->variables.collation_database= cs;
2370
thd->variables.collation_database= thd->db_charset;
2372
/* Execute the query (note that we bypass dispatch_command()) */
2373
const char* found_semicolon= NULL;
2374
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
2375
log_slow_statement(thd);
2380
The query got a really bad error on the master (thread killed etc),
2381
which could be inconsistent. Parse it to test the table names: if the
2382
replicate-*-do|ignore-table rules say "this query must be ignored" then
2383
we exit gracefully; otherwise we warn about the bad error and tell DBA
2386
if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
2387
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
2390
rli->report(ERROR_LEVEL, expected_error,
2392
Query partially completed on the master (error on master: %d) \
2393
and was aborted. There is a chance that your master is inconsistent at this \
2394
point. If you are sure that your master is ok, run this query manually on the \
2395
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
2396
START SLAVE; . Query: '%s'", expected_error, thd->query);
2397
thd->is_slave_error= 1;
2402
/* If the query was not ignored, it is printed to the general log */
2403
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
2404
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
2409
If we expected a non-zero error code, and we don't get the same error
2410
code, and none of them should be ignored.
2412
actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
2413
DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
2414
expected_error, actual_error));
2415
if ((expected_error != actual_error) &&
2417
!ignored_error_code(actual_error) &&
2418
!ignored_error_code(expected_error))
2420
rli->report(ERROR_LEVEL, 0,
2422
Query caused different errors on master and slave. \
2423
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
2424
Default database: '%s'. Query: '%s'",
2425
ER_SAFE(expected_error),
2427
actual_error ? thd->main_da.message() : "no error",
2429
print_slave_db_safe(db), query_arg);
2430
thd->is_slave_error= 1;
2433
If we get the same error code as expected, or they should be ignored.
2435
else if (expected_error == actual_error ||
2436
ignored_error_code(actual_error))
2438
DBUG_PRINT("info",("error ignored"));
2439
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2440
thd->killed= THD::NOT_KILLED;
2443
Other cases: mostly we expected no error and get one.
2445
else if (thd->is_slave_error || thd->is_fatal_error)
2447
rli->report(ERROR_LEVEL, actual_error,
2448
"Error '%s' on query. Default database: '%s'. Query: '%s'",
2449
(actual_error ? thd->main_da.message() :
2450
"unexpected success or fatal error"),
2451
print_slave_db_safe(thd->db), query_arg);
2452
thd->is_slave_error= 1;
2456
TODO: compare the values of "affected rows" around here. Something
2458
if ((uint32) affected_in_event != (uint32) affected_on_slave)
2460
sql_print_error("Slave: did not get the expected number of affected \
2461
rows running query from master - expected %d, got %d (this numbers \
2462
should have matched modulo 4294967296).", 0, ...);
2463
thd->is_slave_error = 1;
2465
We may also want an option to tell the slave to ignore "affected"
2466
mismatch. This mismatch could be implemented with a new ER_ code, and
2467
to ignore it you would use --slave-skip-errors...
2469
To do the comparison we need to know the value of "affected" which the
2470
above mysql_parse() computed. And we need to know the value of
2471
"affected" in the master's binlog. Both will be implemented later. The
2472
important thing is that we now have the format ready to log the values
2473
of "affected" in the binlog. So we can release 5.0.0 before effectively
2474
logging "affected" and effectively comparing it.
2476
} /* End of if (db_ok(... */
2479
VOID(pthread_mutex_lock(&LOCK_thread_count));
2481
Probably we have set thd->query, thd->db, thd->catalog to point to places
2482
in the data_buf of this event. Now the event is going to be deleted
2483
probably, so data_buf will be freed, so the thd->... listed above will be
2484
pointers to freed memory.
2485
So we must set them to 0, so that those bad pointers values are not later
2486
used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
2487
don't suffer from these assignments to 0 as DROP TEMPORARY
2488
TABLE uses the db.table syntax.
2491
thd->set_db(NULL, 0); /* will free the current database */
2492
DBUG_PRINT("info", ("end: query= 0"));
2493
thd->query= 0; // just to be sure
2494
thd->query_length= 0;
2495
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2496
close_thread_tables(thd);
2498
As a disk space optimization, future masters will not log an event for
2499
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
2500
to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
2501
variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
2502
resetting below we are ready to support that.
2504
thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
2505
thd->first_successful_insert_id_in_prev_stmt= 0;
2506
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
2507
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2508
return thd->is_slave_error;
2511
int Query_log_event::do_update_pos(Relay_log_info *rli)
2514
Note that we will not increment group* positions if we are just
2515
after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
2516
from its following updating query.
2518
if (thd->one_shot_set)
2520
rli->inc_event_relay_log_pos();
2524
return Log_event::do_update_pos(rli);
2528
Log_event::enum_skip_reason
2529
Query_log_event::do_shall_skip(Relay_log_info *rli)
2531
DBUG_ENTER("Query_log_event::do_shall_skip");
2532
DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
2533
DBUG_ASSERT(query && q_len > 0);
2535
if (rli->slave_skip_counter > 0)
2537
if (strcmp("BEGIN", query) == 0)
2539
thd->options|= OPTION_BEGIN;
2540
DBUG_RETURN(Log_event::continue_group(rli));
2543
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
2545
thd->options&= ~OPTION_BEGIN;
2546
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
2549
DBUG_RETURN(Log_event::do_shall_skip(rli));
2555
/**************************************************************************
2556
Start_log_event_v3 methods
2557
**************************************************************************/
2559
#ifndef MYSQL_CLIENT
2560
Start_log_event_v3::Start_log_event_v3()
2561
:Log_event(), created(0), binlog_version(BINLOG_VERSION),
2562
artificial_event(0), dont_set_created(0)
2564
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2569
Start_log_event_v3::pack_info()
2572
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2573
void Start_log_event_v3::pack_info(Protocol *protocol)
2575
char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
2576
pos= strmov(buf, "Server ver: ");
2577
pos= strmov(pos, server_version);
2578
pos= strmov(pos, ", Binlog ver: ");
2579
pos= int10_to_str(binlog_version, pos, 10);
2580
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
2586
Start_log_event_v3::print()
2590
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2592
DBUG_ENTER("Start_log_event_v3::print");
2594
Write_on_release_cache cache(&print_event_info->head_cache, file,
2595
Write_on_release_cache::FLUSH_F);
2597
if (!print_event_info->short_form)
2599
print_header(&cache, print_event_info, FALSE);
2600
my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
2601
binlog_version, server_version);
2602
print_timestamp(&cache);
2604
my_b_printf(&cache," at startup");
2605
my_b_printf(&cache, "\n");
2606
if (flags & LOG_EVENT_BINLOG_IN_USE_F)
2607
my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
2608
"Most probably mysqld crashed writing it.\n");
2610
if (!artificial_event && created)
2612
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
2614
This is for mysqlbinlog: like in replication, we want to delete the stale
2615
tmp files left by an unclean shutdown of mysqld (temporary tables)
2616
and rollback unfinished transaction.
2617
Probably this can be done with RESET CONNECTION (syntax to be defined).
2619
my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
2621
my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
2625
print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
2626
!print_event_info->short_form)
2628
my_b_printf(&cache, "BINLOG '\n");
2629
print_base64(&cache, print_event_info, FALSE);
2630
print_event_info->printed_fd_event= TRUE;
2634
#endif /* MYSQL_CLIENT */
2637
Start_log_event_v3::Start_log_event_v3()
2640
Start_log_event_v3::Start_log_event_v3(const char* buf,
2641
const Format_description_log_event
2643
:Log_event(buf, description_event)
2645
buf+= description_event->common_header_len;
2646
binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
2647
memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
2649
// prevent overrun if log is corrupted on disk
2650
server_version[ST_SERVER_VER_LEN-1]= 0;
2651
created= uint4korr(buf+ST_CREATED_OFFSET);
2652
/* We use log_pos to mark if this was an artificial event or not */
2653
artificial_event= (log_pos == 0);
2654
dont_set_created= 1;
2659
Start_log_event_v3::write()
2662
#ifndef MYSQL_CLIENT
2663
bool Start_log_event_v3::write(IO_CACHE* file)
2665
char buff[START_V3_HEADER_LEN];
2666
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2667
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2668
if (!dont_set_created)
2669
created= when= get_time();
2670
int4store(buff + ST_CREATED_OFFSET,created);
2671
return (write_header(file, sizeof(buff)) ||
2672
my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
2677
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2680
Start_log_event_v3::do_apply_event() .
2684
- To handle the case where the master died without having time to write
2685
DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
2686
TODO), we clean up all temporary tables that we got, if we are sure we
2690
- Remove all active user locks.
2691
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
2692
the use of a bit of memory for a user lock which will not be used
2693
anymore. If the user lock is later used, the old one will be released. In
2694
other words, no deadlock problem.
2697
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
2699
DBUG_ENTER("Start_log_event_v3::do_apply_event");
2700
switch (binlog_version)
2705
This can either be 4.x (then a Start_log_event_v3 is only at master
2706
startup so we are sure the master has restarted and cleared his temp
2707
tables; the event always has 'created'>0) or 5.0 (then we have to test
2712
close_temporary_tables(thd);
2713
cleanup_load_tmpdir();
2718
Now the older formats; in that case load_tmpdir is cleaned up by the I/O
2722
if (strncmp(rli->relay_log.description_event_for_exec->server_version,
2723
"3.23.57",7) >= 0 && created)
2726
Can distinguish, based on the value of 'created': this event was
2727
generated at master startup.
2729
close_temporary_tables(thd);
2732
Otherwise, can't distinguish a Start_log_event generated at
2733
master startup and one generated by master FLUSH LOGS, so cannot
2734
be sure temp tables have to be dropped. So do nothing.
2738
/* this case is impossible */
2743
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
2745
/***************************************************************************
2746
Format_description_log_event methods
2747
****************************************************************************/
2750
Format_description_log_event 1st ctor.
2752
Ctor. Can be used to create the event to write to the binary log (when the
2753
server starts or when FLUSH LOGS), or to create artificial events to parse
2754
binlogs from MySQL 3.23 or 4.x.
2755
When in a client, only the 2nd use is possible.
2757
@param binlog_version the binlog version for which we want to build
2758
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
2759
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
2760
old 4.0 (binlog version 2) is not supported;
2761
it should not be used for replication with
2765
Format_description_log_event::
2766
Format_description_log_event(uint8 binlog_ver, const char* server_ver)
2767
:Start_log_event_v3(), event_type_permutation(0)
2769
binlog_version= binlog_ver;
2770
switch (binlog_ver) {
2771
case 4: /* MySQL 5.0 */
2772
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2773
DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
2774
strmov(server_version, "5.0.34"););
2775
common_header_len= LOG_EVENT_HEADER_LEN;
2776
number_of_event_types= LOG_EVENT_TYPES;
2777
/* we'll catch my_malloc() error in is_valid() */
2778
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2781
This long list of assignments is not beautiful, but I see no way to
2782
make it nicer, as the right members are #defines, not array members, so
2783
it's impossible to write a loop.
2785
if (post_header_len)
2787
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
2788
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
2789
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
2790
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
2791
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
2792
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
2793
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
2794
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
2795
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
2796
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
2797
post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
2798
post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2799
post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2800
post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2802
We here have the possibility to simulate a master of before we changed
2803
the table map id to be stored in 6 bytes: when it was stored in 4
2804
bytes (=> post_header_len was 6). This is used to test backward
2806
This code can be removed after a few months (today is Dec 21st 2005),
2807
when we know that the 4-byte masters are not deployed anymore (check
2808
with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
2811
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
2812
post_header_len[TABLE_MAP_EVENT-1]=
2813
post_header_len[WRITE_ROWS_EVENT-1]=
2814
post_header_len[UPDATE_ROWS_EVENT-1]=
2815
post_header_len[DELETE_ROWS_EVENT-1]= 6;);
2816
post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
2817
post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
2818
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
2819
post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
2824
case 3: /* 4.0.x x>=2 */
2826
We build an artificial (i.e. not sent by the master) event, which
2827
describes what those old master versions send.
2830
strmov(server_version, server_ver ? server_ver : "3.23");
2832
strmov(server_version, server_ver ? server_ver : "4.0");
2833
common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2834
LOG_EVENT_MINIMAL_HEADER_LEN;
2836
The first new event in binlog version 4 is Format_desc. So any event type
2837
after that does not exist in older versions. We use the events known by
2838
version 3, even if version 1 had only a subset of them (this is not a
2839
problem: it uses a few bytes for nothing but unifies code; it does not
2840
make the slave detect less corruptions).
2842
number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
2843
post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2845
if (post_header_len)
2847
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
2848
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
2849
post_header_len[STOP_EVENT-1]= 0;
2850
post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
2851
post_header_len[INTVAR_EVENT-1]= 0;
2852
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
2853
post_header_len[SLAVE_EVENT-1]= 0;
2854
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
2855
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
2856
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
2857
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
2858
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
2859
post_header_len[RAND_EVENT-1]= 0;
2860
post_header_len[USER_VAR_EVENT-1]= 0;
2863
default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
2864
post_header_len= 0; /* will make is_valid() fail */
2867
calc_server_version_split();
2872
The problem with this constructor is that the fixed header may have a
2873
length different from this version, but we don't know this length as we
2874
have not read the Format_description_log_event which says it, yet. This
2875
length is in the post-header of the event, but we don't know where the
2878
So this type of event HAS to:
2879
- either have the header's length at the beginning (in the header, at a
2880
fixed position which will never be changed), not in the post-header. That
2881
would make the header be "shifted" compared to other events.
2882
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
2883
versions, so that we know for sure.
2885
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
2886
it is sent before Format_description_log_event).
2889
Format_description_log_event::
2890
Format_description_log_event(const char* buf,
2893
Format_description_log_event*
2895
:Start_log_event_v3(buf, description_event), event_type_permutation(0)
2897
DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
2898
buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
2899
if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
2900
DBUG_VOID_RETURN; /* sanity check */
2901
number_of_event_types=
2902
event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
2903
DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
2904
common_header_len, number_of_event_types));
2905
/* If alloc fails, we'll detect it in is_valid() */
2906
post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2907
number_of_event_types*
2908
sizeof(*post_header_len), MYF(0));
2909
calc_server_version_split();
2912
In some previous versions, the events were given other event type
2913
id numbers than in the present version. When replicating from such
2914
a version, we therefore set up an array that maps those id numbers
2915
to the id numbers of the present server.
2917
If post_header_len is null, it means malloc failed, and is_valid
2918
will fail, so there is no need to do anything.
2920
The trees in which events have wrong id's are:
2922
mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
2923
mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
2924
mysql-5.1-wl2325-no-dd
2926
(this was found by grepping for two lines in sequence where the
2927
first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
2928
"TABLE_MAP_EVENT," in log_event.h in all trees)
2930
In these trees, the following server_versions existed since
2931
TABLE_MAP_EVENT was introduced:
2933
5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
2934
5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
2935
5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
2936
5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
2937
5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
2938
5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
2939
5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
2940
5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
2941
5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
2942
5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
2943
5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
2944
5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
2945
5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
2946
5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
2949
(this was found by grepping for "mysql," in all historical
2950
versions of configure.in in the trees listed above).
2952
There are 5.1.1-alpha versions that use the new event id's, so we
2953
do not test that version string. So replication from 5.1.1-alpha
2954
with the other event id's to a new version does not work.
2955
Moreover, we can safely ignore the part after drop[56]. This
2956
allows us to simplify the big list above to the following regexes:
2958
5\.1\.[1-5]-a_drop5.*
2960
5\.2\.[0-2]-a_drop6.*
2962
This is what we test for in the 'if' below.
2964
if (post_header_len &&
2965
server_version[0] == '5' && server_version[1] == '.' &&
2966
server_version[3] == '.' &&
2967
strncmp(server_version + 5, "-a_drop", 7) == 0 &&
2968
((server_version[2] == '1' &&
2969
server_version[4] >= '1' && server_version[4] <= '5' &&
2970
server_version[12] == '5') ||
2971
(server_version[2] == '1' &&
2972
server_version[4] == '4' &&
2973
server_version[12] == '6') ||
2974
(server_version[2] == '2' &&
2975
server_version[4] >= '0' && server_version[4] <= '2' &&
2976
server_version[12] == '6')))
2978
if (number_of_event_types != 22)
2980
DBUG_PRINT("info", (" number_of_event_types=%d",
2981
number_of_event_types));
2982
/* this makes is_valid() return false. */
2983
my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2984
post_header_len= NULL;
2987
static const uint8 perm[23]=
2989
UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
2990
INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
2991
APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
2993
RAND_EVENT, USER_VAR_EVENT,
2994
FORMAT_DESCRIPTION_EVENT,
2996
PRE_GA_WRITE_ROWS_EVENT,
2997
PRE_GA_UPDATE_ROWS_EVENT,
2998
PRE_GA_DELETE_ROWS_EVENT,
3000
BEGIN_LOAD_QUERY_EVENT,
3001
EXECUTE_LOAD_QUERY_EVENT,
3003
event_type_permutation= perm;
3005
Since we use (permuted) event id's to index the post_header_len
3006
array, we need to permute the post_header_len array too.
3008
uint8 post_header_len_temp[23];
3009
for (int i= 1; i < 23; i++)
3010
post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
3011
for (int i= 0; i < 22; i++)
3012
post_header_len[i] = post_header_len_temp[i];
3017
#ifndef MYSQL_CLIENT
3018
bool Format_description_log_event::write(IO_CACHE* file)
3021
We don't call Start_log_event_v3::write() because this would make 2
3024
uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
3025
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
3026
memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
3027
if (!dont_set_created)
3028
created= when= get_time();
3029
int4store(buff + ST_CREATED_OFFSET,created);
3030
buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
3031
memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
3033
return (write_header(file, sizeof(buff)) ||
3034
my_b_safe_write(file, buff, sizeof(buff)));
3038
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3039
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
3041
DBUG_ENTER("Format_description_log_event::do_apply_event");
3044
As a transaction NEVER spans on 2 or more binlogs:
3045
if we have an active transaction at this point, the master died
3046
while writing the transaction to the binary log, i.e. while
3047
flushing the binlog cache to the binlog. XA guarantees that master has
3048
rolled back. So we roll back.
3049
Note: this event could be sent by the master to inform us of the
3050
format of its binlog; in other words maybe it is not at its
3051
original place when it comes to us; we'll know this by checking
3052
log_pos ("artificial" events have log_pos == 0).
3054
if (!artificial_event && created && thd->transaction.all.ha_list)
3056
/* This is not an error (XA is safe), just an information */
3057
rli->report(INFORMATION_LEVEL, 0,
3058
"Rolling back unfinished transaction (no COMMIT "
3059
"or ROLLBACK in relay log). A probable cause is that "
3060
"the master died while writing the transaction to "
3061
"its binary log, thus rolled back too.");
3062
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
3065
If this event comes from ourselves, there is no cleaning task to
3066
perform, we don't call Start_log_event_v3::do_apply_event()
3067
(this was just to update the log's description event).
3069
if (server_id != (uint32) ::server_id)
3072
If the event was not requested by the slave i.e. the master sent
3073
it while the slave asked for a position >4, the event will make
3074
rli->group_master_log_pos advance. Say that the slave asked for
3075
position 1000, and the Format_desc event's end is 96. Then in
3076
the beginning of replication rli->group_master_log_pos will be
3077
0, then 96, then jump to first really asked event (which is
3078
>96). So this is ok.
3080
DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
3085
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
3087
/* save the information describing this binlog */
3088
delete rli->relay_log.description_event_for_exec;
3089
rli->relay_log.description_event_for_exec= this;
3091
if (server_id == (uint32) ::server_id)
3094
We only increase the relay log position if we are skipping
3095
events and do not touch any group_* variables, nor flush the
3096
relay log info. If there is a crash, we will have to re-skip
3097
the events again, but that is a minor issue.
3099
If we do not skip stepping the group log position (and the
3100
server id was changed when restarting the server), it might well
3101
be that we start executing at a position that is invalid, e.g.,
3102
at a Rows_log_event or a Query_log_event preceeded by a
3103
Intvar_log_event instead of starting at a Table_map_log_event or
3104
the Intvar_log_event respectively.
3106
rli->inc_event_relay_log_pos();
3111
return Log_event::do_update_pos(rli);
3115
Log_event::enum_skip_reason
3116
Format_description_log_event::do_shall_skip(Relay_log_info *rli)
3118
return Log_event::EVENT_SKIP_NOT;
3125
Splits the event's 'server_version' string into three numeric pieces stored
3126
into 'server_version_split':
3127
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
3130
'server_version_split' is then used for lookups to find if the server which
3131
created this event has some known bug.
3133
void Format_description_log_event::calc_server_version_split()
3135
char *p= server_version, *r;
3137
for (uint i= 0; i<=2; i++)
3139
number= strtoul(p, &r, 10);
3140
server_version_split[i]= (uchar)number;
3141
DBUG_ASSERT(number < 256); // fit in uchar
3143
DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
3145
p++; // skip the dot
3147
DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
3148
" '%s' %d %d %d", server_version,
3149
server_version_split[0],
3150
server_version_split[1], server_version_split[2]));
3154
/**************************************************************************
3155
Load_log_event methods
3156
General note about Load_log_event: the binlogging of LOAD DATA INFILE is
3157
going to be changed in 5.0 (or maybe in 5.1; not decided yet).
3158
However, the 5.0 slave could still have to read such events (from a 4.x
3159
master), convert them (which just means maybe expand the header, when 5.0
3160
servers have a UID in events) (remember that whatever is after the header
3161
will be like in 4.x, as this event's format is not modified in 5.0 as we
3162
will use new types of events to log the new LOAD DATA INFILE features).
3163
To be able to read/convert, we just need to not assume that the common
3164
header is of length LOG_EVENT_HEADER_LEN (we must use the description
3166
Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
3167
between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
3168
positions displayed in SHOW SLAVE STATUS then are fine too).
3169
**************************************************************************/
3172
Load_log_event::pack_info()
3175
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3176
uint Load_log_event::get_query_buffer_length()
3179
5 + db_len + 3 + // "use DB; "
3180
18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
3182
9 + // " REPLACE or IGNORE "
3183
13 + table_name_len*2 + // "INTO TABLE `table`"
3184
21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
3185
23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
3186
12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
3187
21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
3188
19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
3189
15 + 22 + // " IGNORE xxx LINES"
3190
3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
3194
void Load_log_event::print_query(bool need_db, char *buf,
3195
char **end, char **fn_start, char **fn_end)
3199
if (need_db && db && db_len)
3201
pos= strmov(pos, "use `");
3202
memcpy(pos, db, db_len);
3203
pos= strmov(pos+db_len, "`; ");
3206
pos= strmov(pos, "LOAD DATA ");
3211
if (check_fname_outside_temp_buf())
3212
pos= strmov(pos, "LOCAL ");
3213
pos= strmov(pos, "INFILE '");
3214
memcpy(pos, fname, fname_len);
3215
pos= strmov(pos+fname_len, "' ");
3217
if (sql_ex.opt_flags & REPLACE_FLAG)
3218
pos= strmov(pos, " REPLACE ");
3219
else if (sql_ex.opt_flags & IGNORE_FLAG)
3220
pos= strmov(pos, " IGNORE ");
3222
pos= strmov(pos ,"INTO");
3227
pos= strmov(pos ," TABLE `");
3228
memcpy(pos, table_name, table_name_len);
3229
pos+= table_name_len;
3231
/* We have to create all optinal fields as the default is not empty */
3232
pos= strmov(pos, "` FIELDS TERMINATED BY ");
3233
pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
3234
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3235
pos= strmov(pos, " OPTIONALLY ");
3236
pos= strmov(pos, " ENCLOSED BY ");
3237
pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
3239
pos= strmov(pos, " ESCAPED BY ");
3240
pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
3242
pos= strmov(pos, " LINES TERMINATED BY ");
3243
pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
3244
if (sql_ex.line_start_len)
3246
pos= strmov(pos, " STARTING BY ");
3247
pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
3250
if ((long) skip_lines > 0)
3252
pos= strmov(pos, " IGNORE ");
3253
pos= longlong10_to_str((longlong) skip_lines, pos, 10);
3254
pos= strmov(pos," LINES ");
3260
const char *field= fields;
3261
pos= strmov(pos, " (");
3262
for (i = 0; i < num_fields; i++)
3269
memcpy(pos, field, field_lens[i]);
3270
pos+= field_lens[i];
3271
field+= field_lens[i] + 1;
3280
void Load_log_event::pack_info(Protocol *protocol)
3284
if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
3286
print_query(TRUE, buf, &end, 0, 0);
3287
protocol->store(buf, end-buf, &my_charset_bin);
3288
my_free(buf, MYF(0));
3290
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
3293
#ifndef MYSQL_CLIENT
3296
Load_log_event::write_data_header()
3299
bool Load_log_event::write_data_header(IO_CACHE* file)
3301
char buf[LOAD_HEADER_LEN];
3302
int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
3303
int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
3304
int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
3305
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
3306
buf[L_DB_LEN_OFFSET] = (char)db_len;
3307
int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
3308
return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
3313
Load_log_event::write_data_body()
3316
bool Load_log_event::write_data_body(IO_CACHE* file)
3318
if (sql_ex.write_data(file))
3320
if (num_fields && fields && field_lens)
3322
if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
3323
my_b_safe_write(file, (uchar*)fields, field_block_len))
3326
return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
3327
my_b_safe_write(file, (uchar*)db, db_len + 1) ||
3328
my_b_safe_write(file, (uchar*)fname, fname_len));
3333
Load_log_event::Load_log_event()
3336
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
3337
const char *db_arg, const char *table_name_arg,
3338
List<Item> &fields_arg,
3339
enum enum_duplicates handle_dup,
3340
bool ignore, bool using_trans)
3342
thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
3344
thread_id(thd_arg->thread_id),
3345
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3346
num_fields(0),fields(0),
3347
field_lens(0),field_block_len(0),
3348
table_name(table_name_arg ? table_name_arg : ""),
3349
db(db_arg), fname(ex->file_name), local_fname(FALSE)
3353
exec_time = (ulong) (end_time - thd_arg->start_time);
3354
/* db can never be a zero pointer in 4.0 */
3355
db_len = (uint32) strlen(db);
3356
table_name_len = (uint32) strlen(table_name);
3357
fname_len = (fname) ? (uint) strlen(fname) : 0;
3358
sql_ex.field_term = (char*) ex->field_term->ptr();
3359
sql_ex.field_term_len = (uint8) ex->field_term->length();
3360
sql_ex.enclosed = (char*) ex->enclosed->ptr();
3361
sql_ex.enclosed_len = (uint8) ex->enclosed->length();
3362
sql_ex.line_term = (char*) ex->line_term->ptr();
3363
sql_ex.line_term_len = (uint8) ex->line_term->length();
3364
sql_ex.line_start = (char*) ex->line_start->ptr();
3365
sql_ex.line_start_len = (uint8) ex->line_start->length();
3366
sql_ex.escaped = (char*) ex->escaped->ptr();
3367
sql_ex.escaped_len = (uint8) ex->escaped->length();
3368
sql_ex.opt_flags = 0;
3369
sql_ex.cached_new_format = -1;
3372
sql_ex.opt_flags|= DUMPFILE_FLAG;
3373
if (ex->opt_enclosed)
3374
sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
3376
sql_ex.empty_flags= 0;
3378
switch (handle_dup) {
3380
sql_ex.opt_flags|= REPLACE_FLAG;
3382
case DUP_UPDATE: // Impossible here
3387
sql_ex.opt_flags|= IGNORE_FLAG;
3389
if (!ex->field_term->length())
3390
sql_ex.empty_flags |= FIELD_TERM_EMPTY;
3391
if (!ex->enclosed->length())
3392
sql_ex.empty_flags |= ENCLOSED_EMPTY;
3393
if (!ex->line_term->length())
3394
sql_ex.empty_flags |= LINE_TERM_EMPTY;
3395
if (!ex->line_start->length())
3396
sql_ex.empty_flags |= LINE_START_EMPTY;
3397
if (!ex->escaped->length())
3398
sql_ex.empty_flags |= ESCAPED_EMPTY;
3400
skip_lines = ex->skip_lines;
3402
List_iterator<Item> li(fields_arg);
3403
field_lens_buf.length(0);
3404
fields_buf.length(0);
3406
while ((item = li++))
3409
uchar len = (uchar) strlen(item->name);
3410
field_block_len += len + 1;
3411
fields_buf.append(item->name, len + 1);
3412
field_lens_buf.append((char*)&len, 1);
3415
field_lens = (const uchar*)field_lens_buf.ptr();
3416
fields = fields_buf.ptr();
3418
#endif /* !MYSQL_CLIENT */
3423
The caller must do buf[event_len] = 0 before he starts using the
3426
Load_log_event::Load_log_event(const char *buf, uint event_len,
3427
const Format_description_log_event *description_event)
3428
:Log_event(buf, description_event), num_fields(0), fields(0),
3429
field_lens(0),field_block_len(0),
3430
table_name(0), db(0), fname(0), local_fname(FALSE)
3432
DBUG_ENTER("Load_log_event");
3434
I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
3435
4.0->5.0 and 5.0->5.0 and it works.
3438
copy_log_event(buf, event_len,
3439
((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
3441
description_event->common_header_len :
3442
LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
3444
/* otherwise it's a derived class, will call copy_log_event() itself */
3450
Load_log_event::copy_log_event()
3453
int Load_log_event::copy_log_event(const char *buf, ulong event_len,
3455
const Format_description_log_event *description_event)
3457
DBUG_ENTER("Load_log_event::copy_log_event");
3459
char* buf_end = (char*)buf + event_len;
3460
/* this is the beginning of the post-header */
3461
const char* data_head = buf + description_event->common_header_len;
3462
slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
3463
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
3464
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
3465
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
3466
db_len = (uint)data_head[L_DB_LEN_OFFSET];
3467
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
3469
if ((int) event_len < body_offset)
3472
Sql_ex.init() on success returns the pointer to the first byte after
3473
the sql_ex structure, which is the start of field lengths array.
3475
if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
3477
buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
3480
data_len = event_len - body_offset;
3481
if (num_fields > data_len) // simple sanity check against corruption
3483
for (uint i = 0; i < num_fields; i++)
3484
field_block_len += (uint)field_lens[i] + 1;
3486
fields = (char*)field_lens + num_fields;
3487
table_name = fields + field_block_len;
3488
db = table_name + table_name_len + 1;
3489
fname = db + db_len + 1;
3490
fname_len = strlen(fname);
3491
// null termination is accomplished by the caller doing buf[event_len]=0
3498
Load_log_event::print()
3502
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3504
print(file, print_event_info, 0);
3508
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
3511
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
3513
DBUG_ENTER("Load_log_event::print");
3514
if (!print_event_info->short_form)
3516
print_header(&cache, print_event_info, FALSE);
3517
my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
3518
thread_id, exec_time);
3521
bool different_db= 1;
3525
If the database is different from the one of the previous statement, we
3526
need to print the "use" command, and we update the last_db.
3527
But if commented, the "use" is going to be commented so we should not
3530
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
3532
memcpy(print_event_info->db, db, db_len + 1);
3535
if (db && db[0] && different_db)
3536
my_b_printf(&cache, "%suse %s%s\n",
3537
commented ? "# " : "",
3538
db, print_event_info->delimiter);
3540
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
3541
my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
3542
commented ? "# " : "", (ulong)thread_id,
3543
print_event_info->delimiter);
3544
my_b_printf(&cache, "%sLOAD DATA ",
3545
commented ? "# " : "");
3546
if (check_fname_outside_temp_buf())
3547
my_b_printf(&cache, "LOCAL ");
3548
my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
3550
if (sql_ex.opt_flags & REPLACE_FLAG)
3551
my_b_printf(&cache," REPLACE ");
3552
else if (sql_ex.opt_flags & IGNORE_FLAG)
3553
my_b_printf(&cache," IGNORE ");
3555
my_b_printf(&cache, "INTO TABLE `%s`", table_name);
3556
my_b_printf(&cache, " FIELDS TERMINATED BY ");
3557
pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
3559
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3560
my_b_printf(&cache," OPTIONALLY ");
3561
my_b_printf(&cache, " ENCLOSED BY ");
3562
pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
3564
my_b_printf(&cache, " ESCAPED BY ");
3565
pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
3567
my_b_printf(&cache," LINES TERMINATED BY ");
3568
pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
3571
if (sql_ex.line_start)
3573
my_b_printf(&cache," STARTING BY ");
3574
pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
3576
if ((long) skip_lines > 0)
3577
my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
3582
const char* field = fields;
3583
my_b_printf(&cache, " (");
3584
for (i = 0; i < num_fields; i++)
3587
my_b_printf(&cache, ",");
3588
my_b_printf(&cache, field);
3590
field += field_lens[i] + 1;
3592
my_b_printf(&cache, ")");
3595
my_b_printf(&cache, "%s\n", print_event_info->delimiter);
3598
#endif /* MYSQL_CLIENT */
3600
#ifndef MYSQL_CLIENT
3603
Load_log_event::set_fields()
3606
This function can not use the member variable
3607
for the database, since LOAD DATA INFILE on the slave
3608
can be for a different database than the current one.
3609
This is the reason for the affected_db argument to this method.
3612
void Load_log_event::set_fields(const char* affected_db,
3613
List<Item> &field_list,
3614
Name_resolution_context *context)
3617
const char* field = fields;
3618
for (i= 0; i < num_fields; i++)
3620
field_list.push_back(new Item_field(context,
3621
affected_db, table_name, field));
3622
field+= field_lens[i] + 1;
3625
#endif /* !MYSQL_CLIENT */
3628
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3630
Does the data loading job when executing a LOAD DATA on the slave.
3634
@param use_rli_only_for_errors If set to 1, rli is provided to
3635
Load_log_event::exec_event only for this
3636
function to have RPL_LOG_NAME and
3637
rli->last_slave_error, both being used by
3638
error reports. rli's position advancing
3639
is skipped (done by the caller which is
3640
Execute_load_log_event::exec_event).
3641
If set to 0, rli is provided for full use,
3642
i.e. for error reports and position
3646
fix this; this can be done by testing rules in
3647
Create_file_log_event::exec_event() and then discarding Append_block and
3650
this is a bug - this needs to be moved to the I/O thread
3658
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
3659
bool use_rli_only_for_errors)
3662
new_db.length= db_len;
3663
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
3664
thd->set_db(new_db.str, new_db.length);
3665
DBUG_ASSERT(thd->query == 0);
3666
thd->query_length= 0; // Should not be needed
3667
thd->is_slave_error= 0;
3668
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
3670
/* see Query_log_event::do_apply_event() and BUG#13360 */
3671
DBUG_ASSERT(!rli->m_table_map.count());
3673
Usually lex_start() is called by mysql_parse(), but we need it here
3674
as the present method does not call mysql_parse().
3677
mysql_reset_thd_for_next_command(thd);
3679
if (!use_rli_only_for_errors)
3682
Saved for InnoDB, see comment in
3683
Query_log_event::do_apply_event()
3685
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
3686
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
3690
We test replicate_*_db rules. Note that we have already prepared
3691
the file to load, even if we are going to ignore and delete it
3692
now. So it is possible that we did a lot of disk writes for
3693
nothing. In other words, a big LOAD DATA INFILE on the master will
3694
still consume a lot of space on the slave (space in the relay log
3695
+ space of temp files: twice the space of the file to load...)
3696
even if it will finally be ignored. TODO: fix this; this can be
3697
done by testing rules in Create_file_log_event::do_apply_event()
3698
and then discarding Append_block and al. Another way is do the
3699
filtering in the I/O thread (more efficient: no disk writes at
3703
Note: We do not need to execute reset_one_shot_variables() if this
3705
Reason: The db stored in binlog events is the same for SET and for
3706
its companion query. If the SET is ignored because of
3707
db_ok(), the companion query will also be ignored, and if
3708
the companion query is ignored in the db_ok() test of
3709
::do_apply_event(), then the companion SET also have so
3710
we don't need to reset_one_shot_variables().
3712
if (rpl_filter->db_ok(thd->db))
3714
thd->set_time((time_t)when);
3715
VOID(pthread_mutex_lock(&LOCK_thread_count));
3716
thd->query_id = next_query_id();
3717
VOID(pthread_mutex_unlock(&LOCK_thread_count));
3719
Initing thd->row_count is not necessary in theory as this variable has no
3720
influence in the case of the slave SQL thread (it is used to generate a
3721
"data truncated" warning but which is absorbed and never gets to the
3722
error log); still we init it to avoid a Valgrind message.
3724
mysql_reset_errors(thd, 0);
3727
bzero((char*) &tables,sizeof(tables));
3728
tables.db= thd->strmake(thd->db, thd->db_length);
3729
tables.alias = tables.table_name = (char*) table_name;
3730
tables.lock_type = TL_WRITE;
3733
// the table will be opened in mysql_load
3734
if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
3736
// TODO: this is a bug - this needs to be moved to the I/O thread
3738
skip_load_data_infile(net);
3744
enum enum_duplicates handle_dup;
3746
char *load_data_query;
3749
Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
3750
and written to slave's binlog if binlogging is on.
3752
if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
3755
This will set thd->fatal_error in case of OOM. So we surely will notice
3756
that something is wrong.
3761
print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
3762
(char **)&thd->lex->fname_end);
3764
thd->query_length= end - load_data_query;
3765
thd->query= load_data_query;
3767
if (sql_ex.opt_flags & REPLACE_FLAG)
3769
handle_dup= DUP_REPLACE;
3771
else if (sql_ex.opt_flags & IGNORE_FLAG)
3774
handle_dup= DUP_ERROR;
3779
When replication is running fine, if it was DUP_ERROR on the
3780
master then we could choose IGNORE here, because if DUP_ERROR
3781
suceeded on master, and data is identical on the master and slave,
3782
then there should be no uniqueness errors on slave, so IGNORE is
3783
the same as DUP_ERROR. But in the unlikely case of uniqueness errors
3784
(because the data on the master and slave happen to be different
3785
(user error or bug), we want LOAD DATA to print an error message on
3786
the slave to discover the problem.
3788
If reading from net (a 3.23 master), mysql_load() will change this
3791
handle_dup= DUP_ERROR;
3794
We need to set thd->lex->sql_command and thd->lex->duplicates
3795
since InnoDB tests these variables to decide if this is a LOAD
3796
DATA ... REPLACE INTO ... statement even though mysql_parse()
3797
is not called. This is not needed in 5.0 since there the LOAD
3798
DATA ... statement is replicated using mysql_parse(), which
3799
sets the thd->lex fields correctly.
3801
thd->lex->sql_command= SQLCOM_LOAD;
3802
thd->lex->duplicates= handle_dup;
3804
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
3805
String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
3806
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
3807
String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
3808
String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
3809
String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
3810
ex.field_term= &field_term;
3811
ex.enclosed= &enclosed;
3812
ex.line_term= &line_term;
3813
ex.line_start= &line_start;
3814
ex.escaped= &escaped;
3816
ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
3817
if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
3818
ex.field_term->length(0);
3820
ex.skip_lines = skip_lines;
3821
List<Item> field_list;
3822
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
3823
set_fields(tables.db, field_list, &thd->lex->select_lex.context);
3824
thd->variables.pseudo_thread_id= thread_id;
3827
// mysql_load will use thd->net to read the file
3828
thd->net.vio = net->vio;
3830
Make sure the client does not get confused about the packet sequence
3832
thd->net.pkt_nr = net->pkt_nr;
3835
It is safe to use tmp_list twice because we are not going to
3836
update it inside mysql_load().
3838
List<Item> tmp_list;
3839
if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
3840
handle_dup, ignore, net != 0))
3841
thd->is_slave_error= 1;
3842
if (thd->cuted_fields)
3844
/* log_pos is the position of the LOAD event in the master log */
3845
sql_print_warning("Slave: load data infile on table '%s' at "
3846
"log position %s in log '%s' produced %ld "
3847
"warning(s). Default database: '%s'",
3849
llstr(log_pos,llbuff), RPL_LOG_NAME,
3850
(ulong) thd->cuted_fields,
3851
print_slave_db_safe(thd->db));
3854
net->pkt_nr= thd->net.pkt_nr;
3860
We will just ask the master to send us /dev/null if we do not
3861
want to load the data.
3862
TODO: this a bug - needs to be done in I/O thread
3865
skip_load_data_infile(net);
3870
const char *remember_db= thd->db;
3871
VOID(pthread_mutex_lock(&LOCK_thread_count));
3873
thd->set_db(NULL, 0); /* will free the current database */
3875
thd->query_length= 0;
3876
VOID(pthread_mutex_unlock(&LOCK_thread_count));
3877
close_thread_tables(thd);
3879
DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
3880
thd->is_slave_error= 0; thd->is_fatal_error= 1;);
3882
if (thd->is_slave_error)
3884
/* this err/sql_errno code is copy-paste from net_send_error() */
3887
if (thd->is_error())
3889
err= thd->main_da.message();
3890
sql_errno= thd->main_da.sql_errno();
3894
sql_errno=ER_UNKNOWN_ERROR;
3897
rli->report(ERROR_LEVEL, sql_errno,"\
3898
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
3899
err, (char*)table_name, print_slave_db_safe(remember_db));
3900
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3903
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3905
if (thd->is_fatal_error)
3908
my_snprintf(buf, sizeof(buf),
3909
"Running LOAD DATA INFILE on table '%-.64s'."
3910
" Default database: '%-.64s'",
3912
print_slave_db_safe(remember_db));
3914
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3915
ER(ER_SLAVE_FATAL_ERROR), buf);
3919
return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
3924
/**************************************************************************
3925
Rotate_log_event methods
3926
**************************************************************************/
3929
Rotate_log_event::pack_info()
3932
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3933
void Rotate_log_event::pack_info(Protocol *protocol)
3935
char buf1[256], buf[22];
3936
String tmp(buf1, sizeof(buf1), log_cs);
3938
tmp.append(new_log_ident, ident_len);
3939
tmp.append(STRING_WITH_LEN(";pos="));
3940
tmp.append(llstr(pos,buf));
3941
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3947
Rotate_log_event::print()
3951
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3954
Write_on_release_cache cache(&print_event_info->head_cache, file,
3955
Write_on_release_cache::FLUSH_F);
3957
if (print_event_info->short_form)
3959
print_header(&cache, print_event_info, FALSE);
3960
my_b_printf(&cache, "\tRotate to ");
3962
my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
3963
my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
3965
#endif /* MYSQL_CLIENT */
3970
Rotate_log_event::Rotate_log_event() (2 constructors)
3974
#ifndef MYSQL_CLIENT
3975
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
3976
uint ident_len_arg, ulonglong pos_arg,
3978
:Log_event(), new_log_ident(new_log_ident_arg),
3979
pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3980
(uint) strlen(new_log_ident_arg)), flags(flags_arg)
3984
DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
3985
DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
3986
llstr(pos_arg, buff), (ulong) flags));
3988
if (flags & DUP_NAME)
3989
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
3995
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
3996
const Format_description_log_event* description_event)
3997
:Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
3999
DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
4000
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
4001
uint8 header_size= description_event->common_header_len;
4002
uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
4004
if (event_len < header_size)
4007
pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
4008
ident_len = (uint)(event_len -
4009
(header_size+post_header_len));
4010
ident_offset = post_header_len;
4011
set_if_smaller(ident_len,FN_REFLEN-1);
4012
new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
4013
DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
4019
Rotate_log_event::write()
4022
#ifndef MYSQL_CLIENT
4023
bool Rotate_log_event::write(IO_CACHE* file)
4025
char buf[ROTATE_HEADER_LEN];
4026
int8store(buf + R_POS_OFFSET, pos);
4027
return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
4028
my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
4029
my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
4034
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4037
Got a rotate log event from the master.
4039
This is mainly used so that we can later figure out the logname and
4040
position for the master.
4042
We can't rotate the slave's BINlog as this will cause infinitive rotations
4043
in a A -> B -> A setup.
4044
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
4049
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
4051
DBUG_ENTER("Rotate_log_event::do_update_pos");
4056
DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
4057
(ulong) this->server_id, (ulong) ::server_id));
4058
DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
4059
DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
4061
pthread_mutex_lock(&rli->data_lock);
4062
rli->event_relay_log_pos= my_b_tell(rli->cur_log);
4064
If we are in a transaction or in a group: the only normal case is
4065
when the I/O thread was copying a big transaction, then it was
4066
stopped and restarted: we have this in the relay log:
4074
In that case, we don't want to touch the coordinates which
4075
correspond to the beginning of the transaction. Starting from
4076
5.0.0, there also are some rotates from the slave itself, in the
4077
relay log, which shall not change the group positions.
4079
if ((server_id != ::server_id || rli->replicate_same_server_id) &&
4080
!rli->is_in_group())
4082
DBUG_PRINT("info", ("old group_master_log_name: '%s' "
4083
"old group_master_log_pos: %lu",
4084
rli->group_master_log_name,
4085
(ulong) rli->group_master_log_pos));
4086
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
4087
rli->notify_group_master_log_name_update();
4088
rli->group_master_log_pos= pos;
4089
strmake(rli->group_relay_log_name, rli->event_relay_log_name,
4090
sizeof(rli->group_relay_log_name) - 1);
4091
rli->notify_group_relay_log_name_update();
4092
rli->group_relay_log_pos= rli->event_relay_log_pos;
4093
DBUG_PRINT("info", ("new group_master_log_name: '%s' "
4094
"new group_master_log_pos: %lu",
4095
rli->group_master_log_name,
4096
(ulong) rli->group_master_log_pos));
4098
Reset thd->options and sql_mode etc, because this could be the signal of
4099
a master's downgrade from 5.0 to 4.0.
4100
However, no need to reset description_event_for_exec: indeed, if the next
4101
master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
4102
master is 4.0 then the events are in the slave's format (conversion).
4104
set_slave_thread_options(thd);
4105
set_slave_thread_default_charset(thd, rli);
4106
thd->variables.auto_increment_increment=
4107
thd->variables.auto_increment_offset= 1;
4109
pthread_mutex_unlock(&rli->data_lock);
4110
pthread_cond_broadcast(&rli->data_cond);
4111
flush_relay_log_info(rli);
4117
Log_event::enum_skip_reason
4118
Rotate_log_event::do_shall_skip(Relay_log_info *rli)
4120
enum_skip_reason reason= Log_event::do_shall_skip(rli);
4123
case Log_event::EVENT_SKIP_NOT:
4124
case Log_event::EVENT_SKIP_COUNT:
4125
return Log_event::EVENT_SKIP_NOT;
4127
case Log_event::EVENT_SKIP_IGNORE:
4128
return Log_event::EVENT_SKIP_IGNORE;
4131
return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
4137
/**************************************************************************
4138
Intvar_log_event methods
4139
**************************************************************************/
4142
Intvar_log_event::pack_info()
4145
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4146
void Intvar_log_event::pack_info(Protocol *protocol)
4148
char buf[256], *pos;
4149
pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
4151
pos= longlong10_to_str(val, pos, -10);
4152
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4158
Intvar_log_event::Intvar_log_event()
4161
Intvar_log_event::Intvar_log_event(const char* buf,
4162
const Format_description_log_event* description_event)
4163
:Log_event(buf, description_event)
4165
buf+= description_event->common_header_len;
4166
type= buf[I_TYPE_OFFSET];
4167
val= uint8korr(buf+I_VAL_OFFSET);
4172
Intvar_log_event::get_var_type_name()
4175
const char* Intvar_log_event::get_var_type_name()
4178
case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
4179
case INSERT_ID_EVENT: return "INSERT_ID";
4180
default: /* impossible */ return "UNKNOWN";
4186
Intvar_log_event::write()
4189
#ifndef MYSQL_CLIENT
4190
bool Intvar_log_event::write(IO_CACHE* file)
4193
buf[I_TYPE_OFFSET]= (uchar) type;
4194
int8store(buf + I_VAL_OFFSET, val);
4195
return (write_header(file, sizeof(buf)) ||
4196
my_b_safe_write(file, buf, sizeof(buf)));
4202
Intvar_log_event::print()
4206
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4210
Write_on_release_cache cache(&print_event_info->head_cache, file,
4211
Write_on_release_cache::FLUSH_F);
4213
if (!print_event_info->short_form)
4215
print_header(&cache, print_event_info, FALSE);
4216
my_b_printf(&cache, "\tIntvar\n");
4219
my_b_printf(&cache, "SET ");
4221
case LAST_INSERT_ID_EVENT:
4222
msg="LAST_INSERT_ID";
4224
case INSERT_ID_EVENT:
4227
case INVALID_INT_EVENT:
4228
default: // cannot happen
4232
my_b_printf(&cache, "%s=%s%s\n",
4233
msg, llstr(val,llbuff), print_event_info->delimiter);
4239
Intvar_log_event::do_apply_event()
4242
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
4243
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
4246
We are now in a statement until the associated query log event has
4249
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4252
case LAST_INSERT_ID_EVENT:
4253
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
4254
thd->first_successful_insert_id_in_prev_stmt= val;
4256
case INSERT_ID_EVENT:
4257
thd->force_one_auto_inc_interval(val);
4263
int Intvar_log_event::do_update_pos(Relay_log_info *rli)
4265
rli->inc_event_relay_log_pos();
4270
Log_event::enum_skip_reason
4271
Intvar_log_event::do_shall_skip(Relay_log_info *rli)
4274
It is a common error to set the slave skip counter to 1 instead of
4275
2 when recovering from an insert which used a auto increment,
4276
rand, or user var. Therefore, if the slave skip counter is 1, we
4277
just say that this event should be skipped by ignoring it, meaning
4278
that we do not change the value of the slave skip counter since it
4279
will be decreased by the following insert event.
4281
return continue_group(rli);
4287
/**************************************************************************
4288
Rand_log_event methods
4289
**************************************************************************/
4291
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4292
void Rand_log_event::pack_info(Protocol *protocol)
4294
char buf1[256], *pos;
4295
pos= strmov(buf1,"rand_seed1=");
4296
pos= int10_to_str((long) seed1, pos, 10);
4297
pos= strmov(pos, ",rand_seed2=");
4298
pos= int10_to_str((long) seed2, pos, 10);
4299
protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
4304
Rand_log_event::Rand_log_event(const char* buf,
4305
const Format_description_log_event* description_event)
4306
:Log_event(buf, description_event)
4308
buf+= description_event->common_header_len;
4309
seed1= uint8korr(buf+RAND_SEED1_OFFSET);
4310
seed2= uint8korr(buf+RAND_SEED2_OFFSET);
4314
#ifndef MYSQL_CLIENT
4315
bool Rand_log_event::write(IO_CACHE* file)
4318
int8store(buf + RAND_SEED1_OFFSET, seed1);
4319
int8store(buf + RAND_SEED2_OFFSET, seed2);
4320
return (write_header(file, sizeof(buf)) ||
4321
my_b_safe_write(file, buf, sizeof(buf)));
4327
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4329
Write_on_release_cache cache(&print_event_info->head_cache, file,
4330
Write_on_release_cache::FLUSH_F);
4332
char llbuff[22],llbuff2[22];
4333
if (!print_event_info->short_form)
4335
print_header(&cache, print_event_info, FALSE);
4336
my_b_printf(&cache, "\tRand\n");
4338
my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
4339
llstr(seed1, llbuff),llstr(seed2, llbuff2),
4340
print_event_info->delimiter);
4342
#endif /* MYSQL_CLIENT */
4345
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4346
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
4349
We are now in a statement until the associated query log event has
4352
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4354
thd->rand.seed1= (ulong) seed1;
4355
thd->rand.seed2= (ulong) seed2;
4359
int Rand_log_event::do_update_pos(Relay_log_info *rli)
4361
rli->inc_event_relay_log_pos();
4366
Log_event::enum_skip_reason
4367
Rand_log_event::do_shall_skip(Relay_log_info *rli)
4370
It is a common error to set the slave skip counter to 1 instead of
4371
2 when recovering from an insert which used a auto increment,
4372
rand, or user var. Therefore, if the slave skip counter is 1, we
4373
just say that this event should be skipped by ignoring it, meaning
4374
that we do not change the value of the slave skip counter since it
4375
will be decreased by the following insert event.
4377
return continue_group(rli);
4380
#endif /* !MYSQL_CLIENT */
4383
/**************************************************************************
4384
Xid_log_event methods
4385
**************************************************************************/
4387
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4388
void Xid_log_event::pack_info(Protocol *protocol)
4390
char buf[128], *pos;
4391
pos= strmov(buf, "COMMIT /* xid=");
4392
pos= longlong10_to_str(xid, pos, 10);
4393
pos= strmov(pos, " */");
4394
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4400
It's ok not to use int8store here,
4401
as long as xid_t::set(ulonglong) and
4402
xid_t::get_my_xid doesn't do it either.
4403
We don't care about actual values of xids as long as
4404
identical numbers compare identically
4408
Xid_log_event(const char* buf,
4409
const Format_description_log_event *description_event)
4410
:Log_event(buf, description_event)
4412
buf+= description_event->common_header_len;
4413
memcpy((char*) &xid, buf, sizeof(xid));
4417
#ifndef MYSQL_CLIENT
4418
bool Xid_log_event::write(IO_CACHE* file)
4420
DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
4421
return write_header(file, sizeof(xid)) ||
4422
my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
4428
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4430
Write_on_release_cache cache(&print_event_info->head_cache, file,
4431
Write_on_release_cache::FLUSH_F);
4433
if (!print_event_info->short_form)
4436
longlong10_to_str(xid, buf, 10);
4438
print_header(&cache, print_event_info, FALSE);
4439
my_b_printf(&cache, "\tXid = %s\n", buf);
4441
my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
4443
#endif /* MYSQL_CLIENT */
4446
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4447
int Xid_log_event::do_apply_event(Relay_log_info const *rli)
4449
/* For a slave Xid_log_event is COMMIT */
4450
general_log_print(thd, COM_QUERY,
4451
"COMMIT /* implicit, from Xid_log_event */");
4452
return end_trans(thd, COMMIT);
4455
Log_event::enum_skip_reason
4456
Xid_log_event::do_shall_skip(Relay_log_info *rli)
4458
DBUG_ENTER("Xid_log_event::do_shall_skip");
4459
if (rli->slave_skip_counter > 0) {
4460
thd->options&= ~OPTION_BEGIN;
4461
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
4463
DBUG_RETURN(Log_event::do_shall_skip(rli));
4465
#endif /* !MYSQL_CLIENT */
4468
/**************************************************************************
4469
User_var_log_event methods
4470
**************************************************************************/
4472
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4473
void User_var_log_event::pack_info(Protocol* protocol)
4476
uint val_offset= 4 + name_len;
4477
uint event_len= val_offset;
4481
if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
4483
strmov(buf + val_offset, "NULL");
4484
event_len= val_offset + 4;
4491
float8get(real_val, val);
4492
if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
4495
event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
4496
buf + val_offset, NULL);
4499
if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
4501
event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
4503
case DECIMAL_RESULT:
4505
if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
4508
String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
4510
binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
4512
my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
4513
event_len= str.length() + val_offset;
4517
/* 15 is for 'COLLATE' and other chars */
4518
buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
4523
if (!(cs= get_charset(charset_number, MYF(0))))
4525
strmov(buf+val_offset, "???");
4530
char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
4531
p= str_to_hex(p, val, val_len);
4532
p= strxmov(p, " COLLATE ", cs->name, NullS);
4544
memcpy(buf+2, name, name_len);
4545
buf[2+name_len]= '`';
4546
buf[3+name_len]= '=';
4547
protocol->store(buf, event_len, &my_charset_bin);
4548
my_free(buf, MYF(0));
4550
#endif /* !MYSQL_CLIENT */
4553
User_var_log_event::
4554
User_var_log_event(const char* buf,
4555
const Format_description_log_event* description_event)
4556
:Log_event(buf, description_event)
4558
buf+= description_event->common_header_len;
4559
name_len= uint4korr(buf);
4560
name= (char *) buf + UV_NAME_LEN_SIZE;
4561
buf+= UV_NAME_LEN_SIZE + name_len;
4562
is_null= (bool) *buf;
4565
type= STRING_RESULT;
4566
charset_number= my_charset_bin.number;
4572
type= (Item_result) buf[UV_VAL_IS_NULL];
4573
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
4574
val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4575
UV_CHARSET_NUMBER_SIZE);
4576
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4577
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
4582
#ifndef MYSQL_CLIENT
4583
bool User_var_log_event::write(IO_CACHE* file)
4585
char buf[UV_NAME_LEN_SIZE];
4586
char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4587
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
4588
uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
4592
int4store(buf, name_len);
4594
if ((buf1[0]= is_null))
4597
val_len= 0; // Length of 'pos'
4602
int4store(buf1 + 2, charset_number);
4606
float8store(buf2, *(double*) val);
4609
int8store(buf2, *(longlong*) val);
4611
case DECIMAL_RESULT:
4613
my_decimal *dec= (my_decimal *)val;
4614
dec->fix_buffer_pointer();
4615
buf2[0]= (char)(dec->intg + dec->frac);
4616
buf2[1]= (char)dec->frac;
4617
decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
4618
val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
4629
int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
4633
/* Length of the whole event */
4634
event_length= sizeof(buf)+ name_len + buf1_length + val_len;
4636
return (write_header(file, event_length) ||
4637
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
4638
my_b_safe_write(file, (uchar*) name, name_len) ||
4639
my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
4640
my_b_safe_write(file, pos, val_len));
4646
User_var_log_event::print()
4650
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4652
Write_on_release_cache cache(&print_event_info->head_cache, file,
4653
Write_on_release_cache::FLUSH_F);
4655
if (!print_event_info->short_form)
4657
print_header(&cache, print_event_info, FALSE);
4658
my_b_printf(&cache, "\tUser_var\n");
4661
my_b_printf(&cache, "SET @`");
4662
my_b_write(&cache, (uchar*) name, (uint) (name_len));
4663
my_b_printf(&cache, "`");
4667
my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
4674
char real_buf[FMT_G_BUFSIZE(14)];
4675
float8get(real_val, val);
4676
my_sprintf(real_buf, (real_buf, "%.14g", real_val));
4677
my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
4681
longlong10_to_str(uint8korr(val), int_buf, -10);
4682
my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
4684
case DECIMAL_RESULT:
4687
int str_len= sizeof(str_buf) - 1;
4688
int precision= (int)val[0];
4689
int scale= (int)val[1];
4690
decimal_digit_t dec_buf[10];
4695
bin2decimal((uchar*) val+2, &dec, precision, scale);
4696
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
4697
str_buf[str_len]= 0;
4698
my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
4704
Let's express the string in hex. That's the most robust way. If we
4705
print it in character form instead, we need to escape it with
4706
character_set_client which we don't know (we will know it in 5.0, but
4707
in 4.1 we don't know it easily when we are printing
4708
User_var_log_event). Explanation why we would need to bother with
4709
character_set_client (quoting Bar):
4710
> Note, the parser doesn't switch to another unescaping mode after
4711
> it has met a character set introducer.
4712
> For example, if an SJIS client says something like:
4713
> SET @a= _ucs2 \0a\0b'
4714
> the string constant is still unescaped according to SJIS, not
4715
> according to UCS2.
4720
if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
4721
break; // no error, as we are 'void'
4722
str_to_hex(hex_str, val, val_len);
4724
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
4725
specify the variable's collation. It will however cause problems when
4726
people want to mysqlbinlog|mysql into another server not supporting the
4727
character set. But there's not much to do about this and it's unlikely.
4729
if (!(cs= get_charset(charset_number, MYF(0))))
4731
Generate an unusable command (=> syntax error) is probably the best
4732
thing we can do here.
4734
my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
4736
my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
4737
cs->csname, hex_str, cs->name,
4738
print_event_info->delimiter);
4753
User_var_log_event::do_apply_event()
4756
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4757
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
4760
CHARSET_INFO *charset;
4761
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
4763
LEX_STRING user_var_name;
4764
user_var_name.str= name;
4765
user_var_name.length= name_len;
4770
We are now in a statement until the associated query log event has
4773
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4777
it= new Item_null();
4783
float8get(real_val, val);
4784
it= new Item_float(real_val, 0);
4785
val= (char*) &real_val; // Pointer to value in native format
4789
int_val= (longlong) uint8korr(val);
4790
it= new Item_int(int_val);
4791
val= (char*) &int_val; // Pointer to value in native format
4794
case DECIMAL_RESULT:
4796
Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
4798
val= (char *)dec->val_decimal(NULL);
4799
val_len= sizeof(my_decimal);
4803
it= new Item_string(val, val_len, charset);
4811
Item_func_set_user_var e(user_var_name, it);
4813
Item_func_set_user_var can't substitute something else on its place =>
4814
0 can be passed as last argument (reference on item)
4816
e.fix_fields(thd, 0);
4818
A variable can just be considered as a table with
4819
a single record and with a single column. Thus, like
4820
a column value, it could always have IMPLICIT derivation.
4822
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
4823
free_root(thd->mem_root,0);
4828
int User_var_log_event::do_update_pos(Relay_log_info *rli)
4830
rli->inc_event_relay_log_pos();
4834
Log_event::enum_skip_reason
4835
User_var_log_event::do_shall_skip(Relay_log_info *rli)
4838
It is a common error to set the slave skip counter to 1 instead
4839
of 2 when recovering from an insert which used a auto increment,
4840
rand, or user var. Therefore, if the slave skip counter is 1, we
4841
just say that this event should be skipped by ignoring it, meaning
4842
that we do not change the value of the slave skip counter since it
4843
will be decreased by the following insert event.
4845
return continue_group(rli);
4847
#endif /* !MYSQL_CLIENT */
4850
/**************************************************************************
4851
Slave_log_event methods
4852
**************************************************************************/
4854
#ifdef HAVE_REPLICATION
4856
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
4858
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
4860
if (print_event_info->short_form)
4862
print_header(&cache, print_event_info, FALSE);
4863
my_b_printf(&cache, "\n# %s", "Unknown event\n");
4867
#ifndef MYSQL_CLIENT
4868
void Slave_log_event::pack_info(Protocol *protocol)
4870
char buf[256+HOSTNAME_LENGTH], *pos;
4871
pos= strmov(buf, "host=");
4872
pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
4873
pos= strmov(pos, ",port=");
4874
pos= int10_to_str((long) master_port, pos, 10);
4875
pos= strmov(pos, ",log=");
4876
pos= strmov(pos, master_log);
4877
pos= strmov(pos, ",pos=");
4878
pos= longlong10_to_str(master_pos, pos, 10);
4879
protocol->store(buf, pos-buf, &my_charset_bin);
4881
#endif /* !MYSQL_CLIENT */
4884
#ifndef MYSQL_CLIENT
4887
re-write this better without holding both locks at the same time
4889
Slave_log_event::Slave_log_event(THD* thd_arg,
4890
Relay_log_info* rli)
4891
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
4893
DBUG_ENTER("Slave_log_event");
4894
if (!rli->inited) // QQ When can this happen ?
4897
Master_info* mi = rli->mi;
4898
// TODO: re-write this better without holding both locks at the same time
4899
pthread_mutex_lock(&mi->data_lock);
4900
pthread_mutex_lock(&rli->data_lock);
4901
master_host_len = strlen(mi->host);
4902
master_log_len = strlen(rli->group_master_log_name);
4903
// on OOM, just do not initialize the structure and print the error
4904
if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
4907
master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
4908
memcpy(master_host, mi->host, master_host_len + 1);
4909
master_log = master_host + master_host_len + 1;
4910
memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
4911
master_port = mi->port;
4912
master_pos = rli->group_master_log_pos;
4913
DBUG_PRINT("info", ("master_log: %s pos: %lu", master_log,
4914
(ulong) master_pos));
4917
sql_print_error("Out of memory while recording slave event");
4918
pthread_mutex_unlock(&rli->data_lock);
4919
pthread_mutex_unlock(&mi->data_lock);
4922
#endif /* !MYSQL_CLIENT */
4925
Slave_log_event::~Slave_log_event()
4927
my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
4932
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4934
Write_on_release_cache cache(&print_event_info->head_cache, file);
4937
if (print_event_info->short_form)
4939
print_header(&cache, print_event_info, FALSE);
4940
my_b_printf(&cache, "\n\
4941
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
4942
master_host, master_port, master_log, llstr(master_pos, llbuff));
4944
#endif /* MYSQL_CLIENT */
4947
int Slave_log_event::get_data_size()
4949
return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
4953
#ifndef MYSQL_CLIENT
4954
bool Slave_log_event::write(IO_CACHE* file)
4956
ulong event_length= get_data_size();
4957
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
4958
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
4959
// log and host are already there
4961
return (write_header(file, event_length) ||
4962
my_b_safe_write(file, (uchar*) mem_pool, event_length));
4967
void Slave_log_event::init_from_mem_pool(int data_size)
4969
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
4970
master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
4971
master_host = mem_pool + SL_MASTER_HOST_OFFSET;
4972
master_host_len = strlen(master_host);
4974
master_log = master_host + master_host_len + 1;
4975
if (master_log > mem_pool + data_size)
4980
master_log_len = strlen(master_log);
4984
/** This code is not used, so has not been updated to be format-tolerant. */
4985
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
4986
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
4988
if (event_len < LOG_EVENT_HEADER_LEN)
4990
event_len -= LOG_EVENT_HEADER_LEN;
4991
if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
4993
memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
4994
mem_pool[event_len] = 0;
4995
init_from_mem_pool(event_len);
4999
#ifndef MYSQL_CLIENT
5000
int Slave_log_event::do_apply_event(Relay_log_info const *rli)
5002
if (mysql_bin_log.is_open())
5003
mysql_bin_log.write(this);
5006
#endif /* !MYSQL_CLIENT */
5009
/**************************************************************************
5010
Stop_log_event methods
5011
**************************************************************************/
5014
Stop_log_event::print()
5018
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5020
Write_on_release_cache cache(&print_event_info->head_cache, file,
5021
Write_on_release_cache::FLUSH_F);
5023
if (print_event_info->short_form)
5026
print_header(&cache, print_event_info, FALSE);
5027
my_b_printf(&cache, "\tStop\n");
5029
#endif /* MYSQL_CLIENT */
5032
#ifndef MYSQL_CLIENT
5034
The master stopped. We used to clean up all temporary tables but
5035
this is useless as, as the master has shut down properly, it has
5036
written all DROP TEMPORARY TABLE (prepared statements' deletion is
5037
TODO only when we binlog prep stmts). We used to clean up
5038
slave_load_tmpdir, but this is useless as it has been cleared at the
5039
end of LOAD DATA INFILE. So we have nothing to do here. The place
5040
were we must do this cleaning is in
5041
Start_log_event_v3::do_apply_event(), not here. Because if we come
5042
here, the master was sane.
5044
int Stop_log_event::do_update_pos(Relay_log_info *rli)
5047
We do not want to update master_log pos because we get a rotate event
5048
before stop, so by now group_master_log_name is set to the next log.
5049
If we updated it, we will have incorrect master coordinates and this
5050
could give false triggers in MASTER_POS_WAIT() that we have reached
5051
the target position when in fact we have not.
5053
if (thd->options & OPTION_BEGIN)
5054
rli->inc_event_relay_log_pos();
5057
rli->inc_group_relay_log_pos(0);
5058
flush_relay_log_info(rli);
5063
#endif /* !MYSQL_CLIENT */
5064
#endif /* HAVE_REPLICATION */
5067
/**************************************************************************
5068
Create_file_log_event methods
5069
**************************************************************************/
5072
Create_file_log_event ctor
5075
#ifndef MYSQL_CLIENT
5076
Create_file_log_event::
5077
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
5078
const char* db_arg, const char* table_name_arg,
5079
List<Item>& fields_arg, enum enum_duplicates handle_dup,
5081
uchar* block_arg, uint block_len_arg, bool using_trans)
5082
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
5084
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
5085
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
5087
DBUG_ENTER("Create_file_log_event");
5088
sql_ex.force_new_format();
5094
Create_file_log_event::write_data_body()
5097
bool Create_file_log_event::write_data_body(IO_CACHE* file)
5100
if ((res= Load_log_event::write_data_body(file)) || fake_base)
5102
return (my_b_safe_write(file, (uchar*) "", 1) ||
5103
my_b_safe_write(file, (uchar*) block, block_len));
5108
Create_file_log_event::write_data_header()
5111
bool Create_file_log_event::write_data_header(IO_CACHE* file)
5114
uchar buf[CREATE_FILE_HEADER_LEN];
5115
if ((res= Load_log_event::write_data_header(file)) || fake_base)
5117
int4store(buf + CF_FILE_ID_OFFSET, file_id);
5118
return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
5123
Create_file_log_event::write_base()
5126
bool Create_file_log_event::write_base(IO_CACHE* file)
5129
fake_base= 1; // pretend we are Load event
5135
#endif /* !MYSQL_CLIENT */
5138
Create_file_log_event ctor
5141
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
5142
const Format_description_log_event* description_event)
5143
:Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
5145
DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
5147
uint header_len= description_event->common_header_len;
5148
uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
5149
uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
5150
if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
5151
copy_log_event(event_buf,len,
5152
((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
5153
load_header_len + header_len :
5154
(fake_base ? (header_len+load_header_len) :
5155
(header_len+load_header_len) +
5156
create_file_header_len)),
5159
if (description_event->binlog_version!=1)
5161
file_id= uint4korr(buf +
5163
load_header_len + CF_FILE_ID_OFFSET);
5165
Note that it's ok to use get_data_size() below, because it is computed
5166
with values we have already read from this event (because we called
5167
copy_log_event()); we are not using slave's format info to decode
5168
master's format, we are really using master's format info.
5169
Anyway, both formats should be identical (except the common_header_len)
5170
as these Load events are not changed between 4.0 and 5.0 (as logging of
5171
LOAD DATA INFILE does not use Load_log_event in 5.0).
5173
The + 1 is for \0 terminating fname
5175
block_offset= (description_event->common_header_len +
5176
Load_log_event::get_data_size() +
5177
create_file_header_len + 1);
5178
if (len < block_offset)
5180
block = (uchar*)buf + block_offset;
5181
block_len = len - block_offset;
5185
sql_ex.force_new_format();
5186
inited_from_old = 1;
5193
Create_file_log_event::print()
5197
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
5200
Write_on_release_cache cache(&print_event_info->head_cache, file);
5202
if (print_event_info->short_form)
5204
if (enable_local && check_fname_outside_temp_buf())
5205
Load_log_event::print(file, print_event_info);
5211
Load_log_event::print(file, print_event_info,
5212
!check_fname_outside_temp_buf());
5214
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
5215
SHOW BINLOG EVENTS we don't.
5217
my_b_printf(&cache, "#");
5220
my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
5224
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5226
print(file, print_event_info, 0);
5228
#endif /* MYSQL_CLIENT */
5232
Create_file_log_event::pack_info()
5235
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5236
void Create_file_log_event::pack_info(Protocol *protocol)
5238
char buf[NAME_LEN*2 + 30 + 21*2], *pos;
5239
pos= strmov(buf, "db=");
5240
memcpy(pos, db, db_len);
5241
pos= strmov(pos + db_len, ";table=");
5242
memcpy(pos, table_name, table_name_len);
5243
pos= strmov(pos + table_name_len, ";file_id=");
5244
pos= int10_to_str((long) file_id, pos, 10);
5245
pos= strmov(pos, ";block_len=");
5246
pos= int10_to_str((long) block_len, pos, 10);
5247
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5249
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5253
Create_file_log_event::do_apply_event()
5256
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5257
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
5259
char proc_info[17+FN_REFLEN+10], *fname_buf;
5265
bzero((char*)&file, sizeof(file));
5266
fname_buf= strmov(proc_info, "Making temp file ");
5267
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
5268
thd_proc_info(thd, proc_info);
5269
my_delete(fname_buf, MYF(0)); // old copy may exist already
5270
if ((fd= my_create(fname_buf, CREATE_MODE,
5271
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5272
MYF(MY_WME))) < 0 ||
5273
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
5274
MYF(MY_WME|MY_NABP)))
5276
rli->report(ERROR_LEVEL, my_errno,
5277
"Error in Create_file event: could not open file '%s'",
5282
// a trick to avoid allocating another buffer
5284
fname_len= (uint) (strmov(ext, ".data") - fname);
5285
if (write_base(&file))
5287
strmov(ext, ".info"); // to have it right in the error message
5288
rli->report(ERROR_LEVEL, my_errno,
5289
"Error in Create_file event: could not write to file '%s'",
5293
end_io_cache(&file);
5294
my_close(fd, MYF(0));
5296
// fname_buf now already has .data, not .info, because we did our trick
5297
my_delete(fname_buf, MYF(0)); // old copy may exist already
5298
if ((fd= my_create(fname_buf, CREATE_MODE,
5299
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5302
rli->report(ERROR_LEVEL, my_errno,
5303
"Error in Create_file event: could not open file '%s'",
5307
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
5309
rli->report(ERROR_LEVEL, my_errno,
5310
"Error in Create_file event: write to '%s' failed",
5314
error=0; // Everything is ok
5318
end_io_cache(&file);
5320
my_close(fd, MYF(0));
5321
thd_proc_info(thd, 0);
5324
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5327
/**************************************************************************
5328
Append_block_log_event methods
5329
**************************************************************************/
5332
Append_block_log_event ctor
5335
#ifndef MYSQL_CLIENT
5336
Append_block_log_event::Append_block_log_event(THD *thd_arg,
5341
:Log_event(thd_arg,0, using_trans), block(block_arg),
5342
block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
5349
Append_block_log_event ctor
5352
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
5353
const Format_description_log_event* description_event)
5354
:Log_event(buf, description_event),block(0)
5356
DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
5357
uint8 common_header_len= description_event->common_header_len;
5358
uint8 append_block_header_len=
5359
description_event->post_header_len[APPEND_BLOCK_EVENT-1];
5360
uint total_header_len= common_header_len+append_block_header_len;
5361
if (len < total_header_len)
5363
file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
5364
block= (uchar*)buf + total_header_len;
5365
block_len= len - total_header_len;
5371
Append_block_log_event::write()
5374
#ifndef MYSQL_CLIENT
5375
bool Append_block_log_event::write(IO_CACHE* file)
5377
uchar buf[APPEND_BLOCK_HEADER_LEN];
5378
int4store(buf + AB_FILE_ID_OFFSET, file_id);
5379
return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
5380
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
5381
my_b_safe_write(file, (uchar*) block, block_len));
5387
Append_block_log_event::print()
5391
void Append_block_log_event::print(FILE* file,
5392
PRINT_EVENT_INFO* print_event_info)
5394
Write_on_release_cache cache(&print_event_info->head_cache, file);
5396
if (print_event_info->short_form)
5398
print_header(&cache, print_event_info, FALSE);
5399
my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
5400
get_type_str(), file_id, block_len);
5402
#endif /* MYSQL_CLIENT */
5406
Append_block_log_event::pack_info()
5409
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5410
void Append_block_log_event::pack_info(Protocol *protocol)
5414
length= (uint) my_sprintf(buf,
5415
(buf, ";file_id=%u;block_len=%u", file_id,
5417
protocol->store(buf, length, &my_charset_bin);
5422
Append_block_log_event::get_create_or_append()
5425
int Append_block_log_event::get_create_or_append() const
5427
return 0; /* append to the file, fail if not exists */
5431
Append_block_log_event::do_apply_event()
5434
int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
5436
char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
5439
DBUG_ENTER("Append_block_log_event::do_apply_event");
5441
fname= strmov(proc_info, "Making temp file ");
5442
slave_load_file_stem(fname, file_id, server_id, ".data");
5443
thd_proc_info(thd, proc_info);
5444
if (get_create_or_append())
5446
my_delete(fname, MYF(0)); // old copy may exist already
5447
if ((fd= my_create(fname, CREATE_MODE,
5448
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5451
rli->report(ERROR_LEVEL, my_errno,
5452
"Error in %s event: could not create file '%s'",
5453
get_type_str(), fname);
5457
else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
5460
rli->report(ERROR_LEVEL, my_errno,
5461
"Error in %s event: could not open file '%s'",
5462
get_type_str(), fname);
5465
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
5467
rli->report(ERROR_LEVEL, my_errno,
5468
"Error in %s event: write to '%s' failed",
5469
get_type_str(), fname);
5476
my_close(fd, MYF(0));
5477
thd_proc_info(thd, 0);
5483
/**************************************************************************
5484
Delete_file_log_event methods
5485
**************************************************************************/
5488
Delete_file_log_event ctor
5491
#ifndef MYSQL_CLIENT
5492
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
5494
:Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
5500
Delete_file_log_event ctor
5503
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
5504
const Format_description_log_event* description_event)
5505
:Log_event(buf, description_event),file_id(0)
5507
uint8 common_header_len= description_event->common_header_len;
5508
uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
5509
if (len < (uint)(common_header_len + delete_file_header_len))
5511
file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
5516
Delete_file_log_event::write()
5519
#ifndef MYSQL_CLIENT
5520
bool Delete_file_log_event::write(IO_CACHE* file)
5522
uchar buf[DELETE_FILE_HEADER_LEN];
5523
int4store(buf + DF_FILE_ID_OFFSET, file_id);
5524
return (write_header(file, sizeof(buf)) ||
5525
my_b_safe_write(file, buf, sizeof(buf)));
5531
Delete_file_log_event::print()
5535
void Delete_file_log_event::print(FILE* file,
5536
PRINT_EVENT_INFO* print_event_info)
5538
Write_on_release_cache cache(&print_event_info->head_cache, file);
5540
if (print_event_info->short_form)
5542
print_header(&cache, print_event_info, FALSE);
5543
my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
5545
#endif /* MYSQL_CLIENT */
5548
Delete_file_log_event::pack_info()
5551
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5552
void Delete_file_log_event::pack_info(Protocol *protocol)
5556
length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
5557
protocol->store(buf, (int32) length, &my_charset_bin);
5562
Delete_file_log_event::do_apply_event()
5565
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5566
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
5568
char fname[FN_REFLEN+10];
5569
char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
5570
(void) my_delete(fname, MYF(MY_WME));
5571
strmov(ext, ".info");
5572
(void) my_delete(fname, MYF(MY_WME));
5575
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5578
/**************************************************************************
5579
Execute_load_log_event methods
5580
**************************************************************************/
5583
Execute_load_log_event ctor
5586
#ifndef MYSQL_CLIENT
5587
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
5590
:Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
5597
Execute_load_log_event ctor
5600
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
5601
const Format_description_log_event* description_event)
5602
:Log_event(buf, description_event), file_id(0)
5604
uint8 common_header_len= description_event->common_header_len;
5605
uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
5606
if (len < (uint)(common_header_len+exec_load_header_len))
5608
file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
5613
Execute_load_log_event::write()
5616
#ifndef MYSQL_CLIENT
5617
bool Execute_load_log_event::write(IO_CACHE* file)
5619
uchar buf[EXEC_LOAD_HEADER_LEN];
5620
int4store(buf + EL_FILE_ID_OFFSET, file_id);
5621
return (write_header(file, sizeof(buf)) ||
5622
my_b_safe_write(file, buf, sizeof(buf)));
5628
Execute_load_log_event::print()
5632
void Execute_load_log_event::print(FILE* file,
5633
PRINT_EVENT_INFO* print_event_info)
5635
Write_on_release_cache cache(&print_event_info->head_cache, file);
5637
if (print_event_info->short_form)
5639
print_header(&cache, print_event_info, FALSE);
5640
my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
5646
Execute_load_log_event::pack_info()
5649
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5650
void Execute_load_log_event::pack_info(Protocol *protocol)
5654
length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
5655
protocol->store(buf, (int32) length, &my_charset_bin);
5660
Execute_load_log_event::do_apply_event()
5663
int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
5665
char fname[FN_REFLEN+10];
5670
Load_log_event *lev= 0;
5672
ext= slave_load_file_stem(fname, file_id, server_id, ".info");
5673
if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
5674
MYF(MY_WME))) < 0 ||
5675
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
5676
MYF(MY_WME|MY_NABP)))
5678
rli->report(ERROR_LEVEL, my_errno,
5679
"Error in Exec_load event: could not open file '%s'",
5683
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
5684
(pthread_mutex_t*)0,
5685
rli->relay_log.description_event_for_exec)) ||
5686
lev->get_type_code() != NEW_LOAD_EVENT)
5688
rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
5689
"file '%s' appears corrupted", fname);
5695
lev->do_apply_event should use rli only for errors i.e. should
5696
not advance rli's position.
5698
lev->do_apply_event is the place where the table is loaded (it
5699
calls mysql_load()).
5702
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
5703
if (lev->do_apply_event(0,rli,1))
5706
We want to indicate the name of the file that could not be loaded
5708
But as we are here we are sure the error is in rli->last_slave_error and
5709
rli->last_slave_errno (example of error: duplicate entry for key), so we
5710
don't want to overwrite it with the filename.
5711
What we want instead is add the filename to the current error message.
5713
char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
5716
rli->report(ERROR_LEVEL, rli->last_error().number,
5717
"%s. Failed executing load from '%s'", tmp, fname);
5718
my_free(tmp,MYF(0));
5723
We have an open file descriptor to the .info file; we need to close it
5724
or Windows will refuse to delete the file in my_delete().
5728
my_close(fd, MYF(0));
5729
end_io_cache(&file);
5732
(void) my_delete(fname, MYF(MY_WME));
5733
memcpy(ext, ".data", 6);
5734
(void) my_delete(fname, MYF(MY_WME));
5741
my_close(fd, MYF(0));
5742
end_io_cache(&file);
5747
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5750
/**************************************************************************
5751
Begin_load_query_log_event methods
5752
**************************************************************************/
5754
#ifndef MYSQL_CLIENT
5755
Begin_load_query_log_event::
5756
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
5757
uint block_len_arg, bool using_trans)
5758
:Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
5761
file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
5766
Begin_load_query_log_event::
5767
Begin_load_query_log_event(const char* buf, uint len,
5768
const Format_description_log_event* desc_event)
5769
:Append_block_log_event(buf, len, desc_event)
5774
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5775
int Begin_load_query_log_event::get_create_or_append() const
5777
return 1; /* create the file */
5779
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5782
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5783
Log_event::enum_skip_reason
5784
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
5787
If the slave skip counter is 1, then we should not start executing
5790
return continue_group(rli);
5795
/**************************************************************************
5796
Execute_load_query_log_event methods
5797
**************************************************************************/
5800
#ifndef MYSQL_CLIENT
5801
Execute_load_query_log_event::
5802
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
5803
ulong query_length_arg, uint fn_pos_start_arg,
5804
uint fn_pos_end_arg,
5805
enum_load_dup_handling dup_handling_arg,
5806
bool using_trans, bool suppress_use,
5807
THD::killed_state killed_err_arg):
5808
Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
5809
suppress_use, killed_err_arg),
5810
file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
5811
fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
5814
#endif /* !MYSQL_CLIENT */
5817
Execute_load_query_log_event::
5818
Execute_load_query_log_event(const char* buf, uint event_len,
5819
const Format_description_log_event* desc_event):
5820
Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
5821
file_id(0), fn_pos_start(0), fn_pos_end(0)
5823
if (!Query_log_event::is_valid())
5826
buf+= desc_event->common_header_len;
5828
fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
5829
fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
5830
dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
5832
if (fn_pos_start > q_len || fn_pos_end > q_len ||
5833
dup_handling > LOAD_DUP_REPLACE)
5836
file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
5840
ulong Execute_load_query_log_event::get_post_header_size_for_derived()
5842
return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
5846
#ifndef MYSQL_CLIENT
5848
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
5850
uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
5851
int4store(buf, file_id);
5852
int4store(buf + 4, fn_pos_start);
5853
int4store(buf + 4 + 4, fn_pos_end);
5854
*(buf + 4 + 4 + 4)= (uchar) dup_handling;
5855
return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
5861
void Execute_load_query_log_event::print(FILE* file,
5862
PRINT_EVENT_INFO* print_event_info)
5864
print(file, print_event_info, 0);
5868
Prints the query as LOAD DATA LOCAL and with rewritten filename.
5870
void Execute_load_query_log_event::print(FILE* file,
5871
PRINT_EVENT_INFO* print_event_info,
5872
const char *local_fname)
5874
Write_on_release_cache cache(&print_event_info->head_cache, file);
5876
print_query_header(&cache, print_event_info);
5880
my_b_write(&cache, (uchar*) query, fn_pos_start);
5881
my_b_printf(&cache, " LOCAL INFILE \'");
5882
my_b_printf(&cache, local_fname);
5883
my_b_printf(&cache, "\'");
5884
if (dup_handling == LOAD_DUP_REPLACE)
5885
my_b_printf(&cache, " REPLACE");
5886
my_b_printf(&cache, " INTO");
5887
my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
5888
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5892
my_b_write(&cache, (uchar*) query, q_len);
5893
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5896
if (!print_event_info->short_form)
5897
my_b_printf(&cache, "# file_id: %d \n", file_id);
5902
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5903
void Execute_load_query_log_event::pack_info(Protocol *protocol)
5906
if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
5911
pos= strmov(buf, "use `");
5912
memcpy(pos, db, db_len);
5913
pos= strmov(pos+db_len, "`; ");
5917
memcpy(pos, query, q_len);
5920
pos= strmov(pos, " ;file_id=");
5921
pos= int10_to_str((long) file_id, pos, 10);
5922
protocol->store(buf, pos-buf, &my_charset_bin);
5923
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
5928
Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
5936
buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
5937
(FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
5939
DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf, MYF(0)); buf= NULL;);
5941
/* Replace filename and LOCAL keyword in query before executing it */
5944
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5945
ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
5950
memcpy(p, query, fn_pos_start);
5952
fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
5953
p= slave_load_file_stem(p, file_id, server_id, ".data");
5954
fname_end= p= strend(p); // Safer than p=p+5
5956
switch (dup_handling) {
5957
case LOAD_DUP_IGNORE:
5958
p= strmake(p, STRING_WITH_LEN(" IGNORE"));
5960
case LOAD_DUP_REPLACE:
5961
p= strmake(p, STRING_WITH_LEN(" REPLACE"));
5964
/* Ordinary load data */
5967
p= strmake(p, STRING_WITH_LEN(" INTO"));
5968
p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
5970
error= Query_log_event::do_apply_event(rli, buf, p-buf);
5972
/* Forging file name for deletion in same buffer */
5976
If there was an error the slave is going to stop, leave the
5977
file so that we can re-execute this event at START SLAVE.
5980
(void) my_delete(fname, MYF(MY_WME));
5982
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
5988
/**************************************************************************
5990
**************************************************************************/
5993
sql_ex_info::write_data()
5996
bool sql_ex_info::write_data(IO_CACHE* file)
6000
return (write_str(file, field_term, (uint) field_term_len) ||
6001
write_str(file, enclosed, (uint) enclosed_len) ||
6002
write_str(file, line_term, (uint) line_term_len) ||
6003
write_str(file, line_start, (uint) line_start_len) ||
6004
write_str(file, escaped, (uint) escaped_len) ||
6005
my_b_safe_write(file,(uchar*) &opt_flags,1));
6010
@todo This is sensitive to field padding. We should write a
6011
char[7], not an old_sql_ex. /sven
6014
old_ex.field_term= *field_term;
6015
old_ex.enclosed= *enclosed;
6016
old_ex.line_term= *line_term;
6017
old_ex.line_start= *line_start;
6018
old_ex.escaped= *escaped;
6019
old_ex.opt_flags= opt_flags;
6020
old_ex.empty_flags=empty_flags;
6021
return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
6030
const char *sql_ex_info::init(const char *buf, const char *buf_end,
6031
bool use_new_format)
6033
cached_new_format = use_new_format;
6038
The code below assumes that buf will not disappear from
6039
under our feet during the lifetime of the event. This assumption
6040
holds true in the slave thread if the log is in new format, but is not
6041
the case when we have old format because we will be reusing net buffer
6042
to read the actual file before we write out the Create_file event.
6044
if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
6045
read_str(&buf, buf_end, &enclosed, &enclosed_len) ||
6046
read_str(&buf, buf_end, &line_term, &line_term_len) ||
6047
read_str(&buf, buf_end, &line_start, &line_start_len) ||
6048
read_str(&buf, buf_end, &escaped, &escaped_len))
6054
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
6055
field_term = buf++; // Use first byte in string
6061
empty_flags= *buf++;
6062
if (empty_flags & FIELD_TERM_EMPTY)
6064
if (empty_flags & ENCLOSED_EMPTY)
6066
if (empty_flags & LINE_TERM_EMPTY)
6068
if (empty_flags & LINE_START_EMPTY)
6070
if (empty_flags & ESCAPED_EMPTY)
6077
/**************************************************************************
6078
Rows_log_event member functions
6079
**************************************************************************/
6081
#ifndef MYSQL_CLIENT
6082
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
6083
MY_BITMAP const *cols, bool is_transactional)
6084
: Log_event(thd_arg, 0, is_transactional),
6088
m_width(tbl_arg ? tbl_arg->s->fields : 1),
6089
m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
6090
#ifdef HAVE_REPLICATION
6091
, m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
6095
We allow a special form of dummy event when the table, and cols
6096
are null and the table id is ~0UL. This is a temporary
6097
solution, to be able to terminate a started statement in the
6098
binary log: the extraneous events will be removed in the future.
6100
DBUG_ASSERT(tbl_arg && tbl_arg->s && tid != ~0UL ||
6101
!tbl_arg && !cols && tid == ~0UL);
6103
if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
6104
set_flags(NO_FOREIGN_KEY_CHECKS_F);
6105
if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
6106
set_flags(RELAXED_UNIQUE_CHECKS_F);
6107
/* if bitmap_init fails, caught in is_valid() */
6108
if (likely(!bitmap_init(&m_cols,
6109
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
6113
DBUG_PRINT_BITSET("debug", "init cols: %s", cols);
6114
/* Cols can be zero if this is a dummy binrows event */
6115
if (likely(cols != NULL))
6117
memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
6118
create_last_word_mask(&m_cols);
6123
// Needed because bitmap_init() does not set it to null on failure
6129
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
6130
Log_event_type event_type,
6131
const Format_description_log_event
6133
: Log_event(buf, description_event),
6135
#ifndef MYSQL_CLIENT
6138
m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
6139
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6140
, m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
6143
DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
6144
uint8 const common_header_len= description_event->common_header_len;
6145
uint8 const post_header_len= description_event->post_header_len[event_type-1];
6147
DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
6148
"post_header_len: %d",
6149
event_len, common_header_len,
6152
const char *post_start= buf + common_header_len;
6153
post_start+= RW_MAPID_OFFSET;
6154
if (post_header_len == 6)
6156
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
6157
m_table_id= uint4korr(post_start);
6162
m_table_id= (ulong) uint6korr(post_start);
6163
post_start+= RW_FLAGS_OFFSET;
6166
m_flags= uint2korr(post_start);
6168
uchar const *const var_start=
6169
(const uchar *)buf + common_header_len + post_header_len;
6170
uchar const *const ptr_width= var_start;
6171
uchar *ptr_after_width= (uchar*) ptr_width;
6172
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
6173
m_width = net_field_length(&ptr_after_width);
6174
DBUG_PRINT("debug", ("m_width=%lu", m_width));
6175
/* if bitmap_init fails, catched in is_valid() */
6176
if (likely(!bitmap_init(&m_cols,
6177
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
6181
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
6182
memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
6183
create_last_word_mask(&m_cols);
6184
ptr_after_width+= (m_width + 7) / 8;
6185
DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
6189
// Needed because bitmap_init() does not set it to null on failure
6190
m_cols.bitmap= NULL;
6194
m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
6196
if (event_type == UPDATE_ROWS_EVENT)
6198
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
6200
/* if bitmap_init fails, caught in is_valid() */
6201
if (likely(!bitmap_init(&m_cols_ai,
6202
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
6206
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
6207
memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
6208
create_last_word_mask(&m_cols_ai);
6209
ptr_after_width+= (m_width + 7) / 8;
6210
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
6211
no_bytes_in_map(&m_cols_ai));
6215
// Needed because bitmap_init() does not set it to null on failure
6216
m_cols_ai.bitmap= 0;
6221
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
6223
size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
6224
DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
6225
m_table_id, m_flags, m_width, (ulong) data_size));
6227
m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
6228
if (likely((bool)m_rows_buf))
6230
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6231
m_curr_row= m_rows_buf;
6233
m_rows_end= m_rows_buf + data_size;
6234
m_rows_cur= m_rows_end;
6235
memcpy(m_rows_buf, ptr_rows_data, data_size);
6238
m_cols.bitmap= 0; // to not free it
6243
Rows_log_event::~Rows_log_event()
6245
if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
6246
m_cols.bitmap= 0; // so no my_free in bitmap_free
6247
bitmap_free(&m_cols); // To pair with bitmap_init().
6248
my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
6251
int Rows_log_event::get_data_size()
6253
int const type_code= get_type_code();
6255
uchar buf[sizeof(m_width)+1];
6256
uchar *end= net_store_length(buf, (m_width + 7) / 8);
6258
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
6259
return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
6260
(type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
6261
(m_rows_cur - m_rows_buf););
6262
int data_size= ROWS_HEADER_LEN;
6263
data_size+= no_bytes_in_map(&m_cols);
6264
data_size+= end - buf;
6266
if (type_code == UPDATE_ROWS_EVENT)
6267
data_size+= no_bytes_in_map(&m_cols_ai);
6269
data_size+= (m_rows_cur - m_rows_buf);
6274
#ifndef MYSQL_CLIENT
6275
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
6278
When the table has a primary key, we would probably want, by default, to
6279
log only the primary key value instead of the entire "before image". This
6280
would save binlog space. TODO
6282
DBUG_ENTER("Rows_log_event::do_add_row_data");
6283
DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data,
6287
If length is zero, there is nothing to write, so we just
6288
return. Note that this is not an optimization, since calling
6289
realloc() with size 0 means free().
6298
Don't print debug messages when running valgrind since they can
6299
trigger false warnings.
6302
DBUG_DUMP("row_data", row_data, min(length, 32));
6305
DBUG_ASSERT(m_rows_buf <= m_rows_cur);
6306
DBUG_ASSERT(!m_rows_buf || m_rows_end && m_rows_buf <= m_rows_end);
6307
DBUG_ASSERT(m_rows_cur <= m_rows_end);
6309
/* The cast will always work since m_rows_cur <= m_rows_end */
6310
if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
6312
size_t const block_size= 1024;
6313
my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
6314
my_ptrdiff_t const new_alloc=
6315
block_size * ((cur_size + length + block_size - 1) / block_size);
6317
uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
6318
MYF(MY_ALLOW_ZERO_PTR|MY_WME));
6319
if (unlikely(!new_buf))
6320
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
6322
/* If the memory moved, we need to move the pointers */
6323
if (new_buf != m_rows_buf)
6325
m_rows_buf= new_buf;
6326
m_rows_cur= m_rows_buf + cur_size;
6330
The end pointer should always be changed to point to the end of
6331
the allocated memory.
6333
m_rows_end= m_rows_buf + new_alloc;
6336
DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
6337
memcpy(m_rows_cur, row_data, length);
6338
m_rows_cur+= length;
6344
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6345
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
6347
DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
6350
If m_table_id == ~0UL, then we have a dummy event that does not
6351
contain any data. In that case, we just remove all tables in the
6352
tables_to_lock list, close the thread tables, and return with
6355
if (m_table_id == ~0UL)
6358
This one is supposed to be set: just an extra check so that
6359
nothing strange has happened.
6361
DBUG_ASSERT(get_flags(STMT_END_F));
6363
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6364
close_thread_tables(thd);
6370
'thd' has been set by exec_relay_log_event(), just before calling
6371
do_apply_event(). We still check here to prevent future coding
6374
DBUG_ASSERT(rli->sql_thd == thd);
6377
If there is no locks taken, this is the first binrow event seen
6378
after the table map events. We should then lock all the tables
6379
used in the transaction and proceed with execution of the actual
6384
bool need_reopen= 1; /* To execute the first lap of the loop below */
6387
lock_tables() reads the contents of thd->lex, so they must be
6388
initialized. Contrary to in
6389
Table_map_log_event::do_apply_event() we don't call
6390
mysql_init_query() as that may reset the binlog format.
6395
There are a few flags that are replicated with each row event.
6396
Make sure to set/clear them before executing the main body of
6399
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6400
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6402
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6404
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6405
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6407
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6408
/* A small test to verify that objects have consistent types */
6409
DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6412
while ((error= lock_tables(thd, rli->tables_to_lock,
6413
rli->tables_to_lock_count, &need_reopen)))
6417
if (thd->is_slave_error || thd->is_fatal_error)
6420
Error reporting borrowed from Query_log_event with many excessive
6421
simplifications (we don't honour --slave-skip-errors)
6423
uint actual_error= thd->main_da.sql_errno();
6424
rli->report(ERROR_LEVEL, actual_error,
6425
"Error '%s' in %s event: when locking tables",
6426
(actual_error ? thd->main_da.message():
6427
"unexpected success or fatal error"),
6429
thd->is_fatal_error= 1;
6433
rli->report(ERROR_LEVEL, error,
6434
"Error in %s event: when locking tables",
6437
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6442
So we need to reopen the tables.
6444
We need to flush the pending RBR event, since it keeps a
6445
pointer to an open table.
6447
ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
6448
the pending RBR event and reset the table pointer after the
6449
tables has been reopened.
6451
NOTE: For this new scheme there should be no pending event:
6452
need to add code to assert that is the case.
6454
thd->binlog_flush_pending_rows_event(false);
6455
TABLE_LIST *tables= rli->tables_to_lock;
6456
close_tables_for_reopen(thd, &tables);
6458
uint tables_count= rli->tables_to_lock_count;
6459
if ((error= open_tables(thd, &tables, &tables_count, 0)))
6461
if (thd->is_slave_error || thd->is_fatal_error)
6464
Error reporting borrowed from Query_log_event with many excessive
6465
simplifications (we don't honour --slave-skip-errors)
6467
uint actual_error= thd->main_da.sql_errno();
6468
rli->report(ERROR_LEVEL, actual_error,
6469
"Error '%s' on reopening tables",
6470
(actual_error ? thd->main_da.message() :
6471
"unexpected success or fatal error"));
6472
thd->is_slave_error= 1;
6474
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6480
When the open and locking succeeded, we check all tables to
6481
ensure that they still have the correct type.
6483
We can use a down cast here since we know that every table added
6484
to the tables_to_lock is a RPL_TABLE_LIST.
6488
RPL_TABLE_LIST *ptr= rli->tables_to_lock;
6489
for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
6491
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
6493
mysql_unlock_tables(thd, thd->lock);
6495
thd->is_slave_error= 1;
6496
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6497
DBUG_RETURN(ERR_BAD_TABLE_DEF);
6503
... and then we add all the tables to the table map and remove
6504
them from tables to lock.
6506
We also invalidate the query cache for all the tables, since
6507
they will now be changed.
6509
TODO [/Matz]: Maybe the query cache should not be invalidated
6510
here? It might be that a table is not changed, even though it
6511
was locked for the statement. We do know that each
6512
Rows_log_event contain at least one row, so after processing one
6513
Rows_log_event, we can invalidate the query cache for the
6516
for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
6518
const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
6524
m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
6529
table == NULL means that this table should not be replicated
6530
(this was set up by Table_map_log_event::do_apply_event()
6531
which tested replicate-* rules).
6535
It's not needed to set_time() but
6536
1) it continues the property that "Time" in SHOW PROCESSLIST shows how
6537
much slave is behind
6538
2) it will be needed when we allow replication from a table with no
6539
TIMESTAMP column to a table with one.
6540
So we call set_time(), like in SBR. Presently it changes nothing.
6542
thd->set_time((time_t)when);
6544
There are a few flags that are replicated with each row event.
6545
Make sure to set/clear them before executing the main body of
6548
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6549
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6551
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6553
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6554
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6556
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6558
if (slave_allow_batching)
6559
thd->options|= OPTION_ALLOW_BATCH;
6561
thd->options&= ~OPTION_ALLOW_BATCH;
6563
/* A small test to verify that objects have consistent types */
6564
DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6567
Now we are in a statement and will stay in a statement until we
6570
We set this flag here, before actually applying any rows, in
6571
case the SQL thread is stopped and we need to detect that we're
6572
inside a statement and halting abruptly might cause problems
6575
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
6577
if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
6578
set_flags(COMPLETE_ROWS_F);
6581
Set tables write and read sets.
6583
Read_set contains all slave columns (in case we are going to fetch
6584
a complete record from slave)
6586
Write_set equals the m_cols bitmap sent from master but it can be
6587
longer if slave has extra columns.
6590
DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols);
6592
bitmap_set_all(table->read_set);
6593
bitmap_set_all(table->write_set);
6594
if (!get_flags(COMPLETE_ROWS_F))
6595
bitmap_intersect(table->write_set,&m_cols);
6597
this->slave_exec_mode= slave_exec_mode_options; // fix the mode
6599
// Do event specific preparations
6600
error= do_before_row_operations(rli);
6602
// row processing loop
6604
while (error == 0 && m_curr_row < m_rows_end)
6606
/* in_use can have been set to NULL in close_tables_for_reopen */
6607
THD* old_thd= table->in_use;
6611
error= do_exec_row(rli);
6613
table->in_use = old_thd;
6619
The following list of "idempotent" errors
6620
means that an error from the list might happen
6621
because of idempotent (more than once)
6622
applying of a binlog file.
6623
Notice, that binlog has a ddl operation its
6624
second applying may cause
6626
case HA_ERR_TABLE_DEF_CHANGED:
6627
case HA_ERR_CANNOT_ADD_FOREIGN:
6629
which are not included into to the list.
6631
case HA_ERR_RECORD_CHANGED:
6632
case HA_ERR_RECORD_DELETED:
6633
case HA_ERR_KEY_NOT_FOUND:
6634
case HA_ERR_END_OF_FILE:
6635
case HA_ERR_FOUND_DUPP_KEY:
6636
case HA_ERR_FOUND_DUPP_UNIQUE:
6637
case HA_ERR_FOREIGN_DUPLICATE_KEY:
6638
case HA_ERR_NO_REFERENCED_ROW:
6639
case HA_ERR_ROW_IS_REFERENCED:
6641
DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
6642
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
6644
if (global_system_variables.log_warnings)
6645
slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
6647
RPL_LOG_NAME, (ulong) log_pos);
6653
thd->is_slave_error= 1;
6658
If m_curr_row_end was not set during event execution (e.g., because
6659
of errors) we can't proceed to the next row. If the error is transient
6660
(i.e., error==0 at this point) we must call unpack_current_row() to set
6664
DBUG_PRINT("info", ("error: %d", error));
6665
DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
6666
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
6668
if (!m_curr_row_end && !error)
6669
unpack_current_row(rli, &m_cols);
6671
// at this moment m_curr_row_end should be set
6672
DBUG_ASSERT(error || m_curr_row_end != NULL);
6673
DBUG_ASSERT(error || m_curr_row < m_curr_row_end);
6674
DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
6676
m_curr_row= m_curr_row_end;
6678
} // row processing loop
6680
DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
6681
const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
6682
error= do_after_row_operations(rli, error);
6685
DBUG_PRINT("info", ("Marked that we need to keep log"));
6686
thd->options|= OPTION_KEEP_LOG;
6691
We need to delay this clear until here bacause unpack_current_row() uses
6692
master-side table definitions stored in rli.
6694
if (rli->tables_to_lock && get_flags(STMT_END_F))
6695
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6696
/* reset OPTION_ALLOW_BATCH as not affect later events */
6697
thd->options&= ~OPTION_ALLOW_BATCH;
6700
{ /* error has occured during the transaction */
6701
slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
6702
get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
6707
If one day we honour --skip-slave-errors in row-based replication, and
6708
the error should be skipped, then we would clear mappings, rollback,
6709
close tables, but the slave SQL thread would not stop and then may
6710
assume the mapping is still available, the tables are still open...
6711
So then we should clear mappings/rollback/close here only if this is a
6713
For now we code, knowing that error is not skippable and so slave SQL
6714
thread is certainly going to stop.
6715
rollback at the caller along with sbr.
6717
thd->reset_current_stmt_binlog_row_based();
6718
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
6719
thd->is_slave_error= 1;
6724
This code would ideally be placed in do_update_pos() instead, but
6725
since we have no access to table there, we do the setting of
6726
last_event_start_time here instead.
6728
if (table && (table->s->primary_key == MAX_KEY) &&
6729
!cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS)
6732
------------ Temporary fix until WL#2975 is implemented ---------
6734
This event is not the last one (no STMT_END_F). If we stop now
6735
(in case of terminate_slave_thread()), how will we restart? We
6736
have to restart from Table_map_log_event, but as this table is
6737
not transactional, the rows already inserted will still be
6738
present, and idempotency is not guaranteed (no PK) so we risk
6739
that repeating leads to double insert. So we desperately try to
6740
continue, hope we'll eventually leave this buggy situation (by
6741
executing the final Rows_log_event). If we are in a hopeless
6742
wait (reached end of last relay log and nothing gets appended
6743
there), we timeout after one minute, and notify DBA about the
6744
problem. When WL#2975 is implemented, just remove the member
6745
Relay_log_info::last_event_start_time and all its occurrences.
6747
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
6753
Log_event::enum_skip_reason
6754
Rows_log_event::do_shall_skip(Relay_log_info *rli)
6757
If the slave skip counter is 1 and this event does not end a
6758
statement, then we should not start executing on the next event.
6759
Otherwise, we defer the decision to the normal skipping logic.
6761
if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
6762
return Log_event::EVENT_SKIP_IGNORE;
6764
return Log_event::do_shall_skip(rli);
6768
Rows_log_event::do_update_pos(Relay_log_info *rli)
6770
DBUG_ENTER("Rows_log_event::do_update_pos");
6773
DBUG_PRINT("info", ("flags: %s",
6774
get_flags(STMT_END_F) ? "STMT_END_F " : ""));
6776
if (get_flags(STMT_END_F))
6779
This is the end of a statement or transaction, so close (and
6780
unlock) the tables we opened when processing the
6781
Table_map_log_event starting the statement.
6783
OBSERVER. This will clear *all* mappings, not only those that
6784
are open for the table. There is not good handle for on-close
6787
NOTE. Even if we have no table ('table' == 0) we still need to be
6788
here, so that we increase the group relay log position. If we didn't, we
6789
could have a group relay log position which lags behind "forever"
6790
(assume the last master's transaction is ignored by the slave because of
6791
replicate-ignore rules).
6793
thd->binlog_flush_pending_rows_event(true);
6796
If this event is not in a transaction, the call below will, if some
6797
transactional storage engines are involved, commit the statement into
6798
them and flush the pending event to binlog.
6799
If this event is in a transaction, the call will do nothing, but a
6800
Xid_log_event will come next which will, if some transactional engines
6801
are involved, commit the transaction and flush the pending event to the
6804
error= ha_autocommit_or_rollback(thd, 0);
6807
Now what if this is not a transactional engine? we still need to
6808
flush the pending event to the binlog; we did it with
6809
thd->binlog_flush_pending_rows_event(). Note that we imitate
6810
what is done for real queries: a call to
6811
ha_autocommit_or_rollback() (sometimes only if involves a
6812
transactional engine), and a call to be sure to have the pending
6816
thd->reset_current_stmt_binlog_row_based();
6818
rli->cleanup_context(thd, 0);
6822
Indicate that a statement is finished.
6823
Step the group log position if we are not in a transaction,
6824
otherwise increase the event log position.
6826
rli->stmt_done(log_pos, when);
6829
Clear any errors pushed in thd->net.last_err* if for example "no key
6830
found" (as this is allowed). This is a safety measure; apparently
6831
those errors (e.g. when executing a Delete_rows_log_event of a
6832
non-existing row, like in rpl_row_mystery22.test,
6833
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
6834
do not become visible. We still prefer to wipe them out.
6839
rli->report(ERROR_LEVEL, error,
6840
"Error in %s event: commit of row events failed, "
6842
get_type_str(), m_table->s->db.str,
6843
m_table->s->table_name.str);
6847
rli->inc_event_relay_log_pos();
6853
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
6855
#ifndef MYSQL_CLIENT
6856
bool Rows_log_event::write_data_header(IO_CACHE *file)
6858
uchar buf[ROWS_HEADER_LEN]; // No need to init the buffer
6859
DBUG_ASSERT(m_table_id != ~0UL);
6860
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
6862
int4store(buf + 0, m_table_id);
6863
int2store(buf + 4, m_flags);
6864
return (my_b_safe_write(file, buf, 6));
6866
int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
6867
int2store(buf + RW_FLAGS_OFFSET, m_flags);
6868
return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
6871
bool Rows_log_event::write_data_body(IO_CACHE*file)
6874
Note that this should be the number of *bits*, not the number of
6877
uchar sbuf[sizeof(m_width)];
6878
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
6880
uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
6881
DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
6883
DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
6884
res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
6886
DBUG_PRINT_BITSET("debug", "writing cols: %s", &m_cols);
6887
res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
6888
no_bytes_in_map(&m_cols));
6890
TODO[refactor write]: Remove the "down cast" here (and elsewhere).
6892
if (get_type_code() == UPDATE_ROWS_EVENT)
6894
DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
6895
no_bytes_in_map(&m_cols_ai));
6896
res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
6897
no_bytes_in_map(&m_cols_ai));
6899
DBUG_DUMP("rows", m_rows_buf, data_size);
6900
res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
6907
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6908
void Rows_log_event::pack_info(Protocol *protocol)
6911
char const *const flagstr=
6912
get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
6913
size_t bytes= my_snprintf(buf, sizeof(buf),
6914
"table_id: %lu%s", m_table_id, flagstr);
6915
protocol->store(buf, bytes, &my_charset_bin);
6920
void Rows_log_event::print_helper(FILE *file,
6921
PRINT_EVENT_INFO *print_event_info,
6922
char const *const name)
6924
IO_CACHE *const head= &print_event_info->head_cache;
6925
IO_CACHE *const body= &print_event_info->body_cache;
6926
if (!print_event_info->short_form)
6928
bool const last_stmt_event= get_flags(STMT_END_F);
6929
print_header(head, print_event_info, !last_stmt_event);
6930
my_b_printf(head, "\t%s: table id %lu%s\n",
6932
last_stmt_event ? " flags: STMT_END_F" : "");
6933
print_base64(body, print_event_info, !last_stmt_event);
6936
if (get_flags(STMT_END_F))
6938
copy_event_cache_to_file_and_reinit(head, file);
6939
copy_event_cache_to_file_and_reinit(body, file);
6944
/**************************************************************************
6945
Table_map_log_event member functions and support functions
6946
**************************************************************************/
6949
@page How replication of field metadata works.
6951
When a table map is created, the master first calls
6952
Table_map_log_event::save_field_metadata() which calculates how many
6953
values will be in the field metadata. Only those fields that require the
6954
extra data are added. The method also loops through all of the fields in
6955
the table calling the method Field::save_field_metadata() which returns the
6956
values for the field that will be saved in the metadata and replicated to
6957
the slave. Once all fields have been processed, the table map is written to
6958
the binlog adding the size of the field metadata and the field metadata to
6959
the end of the body of the table map.
6961
When a table map is read on the slave, the field metadata is read from the
6962
table map and passed to the table_def class constructor which saves the
6963
field metadata from the table map into an array based on the type of the
6964
field. Field metadata values not present (those fields that do not use extra
6965
data) in the table map are initialized as zero (0). The array size is the
6966
same as the columns for the table on the slave.
6968
Additionally, values saved for field metadata on the master are saved as a
6969
string of bytes (uchar) in the binlog. A field may require 1 or more bytes
6970
to store the information. In cases where values require multiple bytes
6971
(e.g. values > 255), the endian-safe methods are used to properly encode
6972
the values on the master and decode them on the slave. When the field
6973
metadata values are captured on the slave, they are stored in an array of
6974
type uint16. This allows the least number of casts to prevent casting bugs
6975
when the field metadata is used in comparisons of field attributes. When
6976
the field metadata is used for calculating addresses in pointer math, the
6977
type used is uint32.
6980
#if !defined(MYSQL_CLIENT)
6982
Save the field metadata based on the real_type of the field.
6983
The metadata saved depends on the type of the field. Some fields
6984
store a single byte for pack_length() while others store two bytes
6985
for field_length (max length).
6990
We may want to consider changing the encoding of the information.
6991
Currently, the code attempts to minimize the number of bytes written to
6992
the tablemap. There are at least two other alternatives; 1) using
6993
net_store_length() to store the data allowing it to choose the number of
6994
bytes that are appropriate thereby making the code much easier to
6995
maintain (only 1 place to change the encoding), or 2) use a fixed number
6996
of bytes for each field. The problem with option 1 is that net_store_length()
6997
will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
6998
for fields like CHAR which can be no larger than 255 characters, the method
6999
will use 3 bytes when the value is > 250. Further, every value that is
7000
encoded using 2 parts (e.g., pack_length, field_length) will be numerically
7001
> 250 therefore will use 3 bytes for eah value. The problem with option 2
7002
is less wasteful for space but does waste 1 byte for every field that does
7005
int Table_map_log_event::save_field_metadata()
7007
DBUG_ENTER("Table_map_log_event::save_field_metadata");
7009
for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
7010
index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
7013
#endif /* !defined(MYSQL_CLIENT) */
7016
Constructor used to build an event for writing to the binary log.
7017
Mats says tbl->s lives longer than this event so it's ok to copy pointers
7018
(tbl->s->db etc) and not pointer content.
7020
#if !defined(MYSQL_CLIENT)
7021
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
7022
bool is_transactional, uint16 flags)
7023
: Log_event(thd, 0, true),
7025
m_dbnam(tbl->s->db.str),
7026
m_dblen(m_dbnam ? tbl->s->db.length : 0),
7027
m_tblnam(tbl->s->table_name.str),
7028
m_tbllen(tbl->s->table_name.length),
7029
m_colcnt(tbl->s->fields),
7034
m_field_metadata(0),
7035
m_field_metadata_size(0),
7039
DBUG_ASSERT(m_table_id != ~0UL);
7041
In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
7042
table.cc / alloc_table_share():
7043
Use the fact the key is db/0/table_name/0
7044
As we rely on this let's assert it.
7046
DBUG_ASSERT((tbl->s->db.str == 0) ||
7047
(tbl->s->db.str[tbl->s->db.length] == 0));
7048
DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
7051
m_data_size= TABLE_MAP_HEADER_LEN;
7052
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
7053
m_data_size+= m_dblen + 2; // Include length and terminating \0
7054
m_data_size+= m_tbllen + 2; // Include length and terminating \0
7055
m_data_size+= 1 + m_colcnt; // COLCNT and column types
7057
/* If malloc fails, caught in is_valid() */
7058
if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
7060
m_coltype= reinterpret_cast<uchar*>(m_memory);
7061
for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
7062
m_coltype[i]= m_table->field[i]->type();
7066
Calculate a bitmap for the results of maybe_null() for all columns.
7067
The bitmap is used to determine when there is a column from the master
7068
that is not on the slave and is null and thus not in the row data during
7071
uint num_null_bytes= (m_table->s->fields + 7) / 8;
7072
m_data_size+= num_null_bytes;
7073
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
7074
&m_null_bits, num_null_bytes,
7075
&m_field_metadata, (m_colcnt * 2),
7078
bzero(m_field_metadata, (m_colcnt * 2));
7081
Create an array for the field metadata and store it.
7083
m_field_metadata_size= save_field_metadata();
7084
DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
7087
Now set the size of the data to the size of the field metadata array
7088
plus one or two bytes for number of elements in the field metadata array.
7090
if (m_field_metadata_size > 255)
7091
m_data_size+= m_field_metadata_size + 2;
7093
m_data_size+= m_field_metadata_size + 1;
7095
bzero(m_null_bits, num_null_bytes);
7096
for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
7097
if (m_table->field[i]->maybe_null())
7098
m_null_bits[(i / 8)]+= 1 << (i % 8);
7101
#endif /* !defined(MYSQL_CLIENT) */
7104
Constructor used by slave to read the event from the binary log.
7106
#if defined(HAVE_REPLICATION)
7107
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
7108
const Format_description_log_event
7111
: Log_event(buf, description_event),
7112
#ifndef MYSQL_CLIENT
7115
m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
7116
m_colcnt(0), m_coltype(0),
7117
m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
7118
m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
7119
m_null_bits(0), m_meta_memory(NULL)
7121
unsigned int bytes_read= 0;
7122
DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
7124
uint8 common_header_len= description_event->common_header_len;
7125
uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
7126
DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
7127
event_len, common_header_len, post_header_len));
7130
Don't print debug messages when running valgrind since they can
7131
trigger false warnings.
7134
DBUG_DUMP("event buffer", (uchar*) buf, event_len);
7137
/* Read the post-header */
7138
const char *post_start= buf + common_header_len;
7140
post_start+= TM_MAPID_OFFSET;
7141
if (post_header_len == 6)
7143
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
7144
m_table_id= uint4korr(post_start);
7149
DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
7150
m_table_id= (ulong) uint6korr(post_start);
7151
post_start+= TM_FLAGS_OFFSET;
7154
DBUG_ASSERT(m_table_id != ~0UL);
7156
m_flags= uint2korr(post_start);
7158
/* Read the variable part of the event */
7159
const char *const vpart= buf + common_header_len + post_header_len;
7161
/* Extract the length of the various parts from the buffer */
7162
uchar const *const ptr_dblen= (uchar const*)vpart + 0;
7163
m_dblen= *(uchar*) ptr_dblen;
7165
/* Length of database name + counter + terminating null */
7166
uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
7167
m_tbllen= *(uchar*) ptr_tbllen;
7169
/* Length of table name + counter + terminating null */
7170
uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
7171
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
7172
m_colcnt= net_field_length(&ptr_after_colcnt);
7174
DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
7175
(ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
7176
(ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
7177
m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
7179
/* Allocate mem for all fields in one go. If fails, caught in is_valid() */
7180
m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
7181
&m_dbnam, (uint) m_dblen + 1,
7182
&m_tblnam, (uint) m_tbllen + 1,
7183
&m_coltype, (uint) m_colcnt,
7188
/* Copy the different parts into their memory */
7189
strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
7190
strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
7191
memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
7193
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
7194
bytes_read= ptr_after_colcnt - (uchar *)buf;
7195
DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
7196
if (bytes_read < event_len)
7198
m_field_metadata_size= net_field_length(&ptr_after_colcnt);
7199
DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
7200
uint num_null_bytes= (m_colcnt + 7) / 8;
7201
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
7202
&m_null_bits, num_null_bytes,
7203
&m_field_metadata, m_field_metadata_size,
7205
memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
7206
ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
7207
memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
7215
Table_map_log_event::~Table_map_log_event()
7217
my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
7218
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
7222
Return value is an error code, one of:
7224
-1 Failure to open table [from open_tables()]
7226
1 No room for more tables [from set_table()]
7227
2 Out of memory [from set_table()]
7228
3 Wrong table definition
7229
4 Daisy-chaining RBR with SBR not possible
7232
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7233
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
7235
RPL_TABLE_LIST *table_list;
7236
char *db_mem, *tname_mem;
7239
DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
7240
DBUG_ASSERT(rli->sql_thd == thd);
7242
/* Step the query id to mark what columns that are actually used. */
7243
pthread_mutex_lock(&LOCK_thread_count);
7244
thd->query_id= next_query_id();
7245
pthread_mutex_unlock(&LOCK_thread_count);
7247
if (!(memory= my_multi_malloc(MYF(MY_WME),
7248
&table_list, (uint) sizeof(RPL_TABLE_LIST),
7249
&db_mem, (uint) NAME_LEN + 1,
7250
&tname_mem, (uint) NAME_LEN + 1,
7252
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
7254
bzero(table_list, sizeof(*table_list));
7255
table_list->db = db_mem;
7256
table_list->alias= table_list->table_name = tname_mem;
7257
table_list->lock_type= TL_WRITE;
7258
table_list->next_global= table_list->next_local= 0;
7259
table_list->table_id= m_table_id;
7260
table_list->updating= 1;
7261
strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
7262
strmov(table_list->table_name, m_tblnam);
7266
if (!rpl_filter->db_ok(table_list->db) ||
7267
(rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
7269
my_free(memory, MYF(MY_WME));
7274
open_tables() reads the contents of thd->lex, so they must be
7275
initialized, so we should call lex_start(); to be even safer, we
7276
call mysql_init_query() which does a more complete set of inits.
7279
mysql_reset_thd_for_next_command(thd);
7281
Check if the slave is set to use SBR. If so, it should switch
7282
to using RBR until the end of the "statement", i.e., next
7283
STMT_END_F or next error.
7285
if (!thd->current_stmt_binlog_row_based &&
7286
mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
7288
thd->set_current_stmt_binlog_row_based();
7292
Open the table if it is not already open and add the table to
7293
table map. Note that for any table that should not be
7294
replicated, a filter is needed.
7296
The creation of a new TABLE_LIST is used to up-cast the
7297
table_list consisting of RPL_TABLE_LIST items. This will work
7298
since the only case where the argument to open_tables() is
7299
changed, is when thd->lex->query_tables == table_list, i.e.,
7300
when the statement requires prelocking. Since this is not
7301
executed when a statement is executed, this case will not occur.
7302
As a precaution, an assertion is added to ensure that the bad
7305
Either way, the memory in the list is *never* released
7306
internally in the open_tables() function, hence we take a copy
7307
of the pointer to make sure that it's not lost.
7310
DBUG_ASSERT(thd->lex->query_tables != table_list);
7311
TABLE_LIST *tmp_table_list= table_list;
7312
if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
7314
if (thd->is_slave_error || thd->is_fatal_error)
7317
Error reporting borrowed from Query_log_event with many excessive
7318
simplifications (we don't honour --slave-skip-errors)
7320
uint actual_error= thd->main_da.sql_errno();
7321
rli->report(ERROR_LEVEL, actual_error,
7322
"Error '%s' on opening table `%s`.`%s`",
7323
(actual_error ? thd->main_da.message() :
7324
"unexpected success or fatal error"),
7325
table_list->db, table_list->table_name);
7326
thd->is_slave_error= 1;
7331
m_table= table_list->table;
7334
This will fail later otherwise, the 'in_use' field should be
7335
set to the current thread.
7337
DBUG_ASSERT(m_table->in_use);
7340
Use placement new to construct the table_def instance in the
7341
memory allocated for it inside table_list.
7343
The memory allocated by the table_def structure (i.e., not the
7344
memory allocated *for* the table_def structure) is released
7345
inside Relay_log_info::clear_tables_to_lock() by calling the
7346
table_def destructor explicitly.
7348
new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt,
7349
m_field_metadata, m_field_metadata_size, m_null_bits);
7350
table_list->m_tabledef_valid= TRUE;
7353
We record in the slave's information that the table should be
7354
locked by linking the table into the list of tables to lock.
7356
table_list->next_global= table_list->next_local= rli->tables_to_lock;
7357
const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
7358
const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
7359
/* 'memory' is freed in clear_tables_to_lock */
7365
my_free(memory, MYF(MY_WME));
7369
Log_event::enum_skip_reason
7370
Table_map_log_event::do_shall_skip(Relay_log_info *rli)
7373
If the slave skip counter is 1, then we should not start executing
7376
return continue_group(rli);
7379
int Table_map_log_event::do_update_pos(Relay_log_info *rli)
7381
rli->inc_event_relay_log_pos();
7385
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
7387
#ifndef MYSQL_CLIENT
7388
bool Table_map_log_event::write_data_header(IO_CACHE *file)
7390
DBUG_ASSERT(m_table_id != ~0UL);
7391
uchar buf[TABLE_MAP_HEADER_LEN];
7392
DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
7394
int4store(buf + 0, m_table_id);
7395
int2store(buf + 4, m_flags);
7396
return (my_b_safe_write(file, buf, 6));
7398
int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
7399
int2store(buf + TM_FLAGS_OFFSET, m_flags);
7400
return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
7403
bool Table_map_log_event::write_data_body(IO_CACHE *file)
7405
DBUG_ASSERT(m_dbnam != NULL);
7406
DBUG_ASSERT(m_tblnam != NULL);
7407
/* We use only one byte per length for storage in event: */
7408
DBUG_ASSERT(m_dblen < 128);
7409
DBUG_ASSERT(m_tbllen < 128);
7411
uchar const dbuf[]= { (uchar) m_dblen };
7412
uchar const tbuf[]= { (uchar) m_tbllen };
7414
uchar cbuf[sizeof(m_colcnt)];
7415
uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
7416
DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
7419
Store the size of the field metadata.
7421
uchar mbuf[sizeof(m_field_metadata_size)];
7422
uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
7424
return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
7425
my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
7426
my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
7427
my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
7428
my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
7429
my_b_safe_write(file, m_coltype, m_colcnt) ||
7430
my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
7431
my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
7432
my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
7436
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7439
Print some useful information for the SHOW BINARY LOG information
7443
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7444
void Table_map_log_event::pack_info(Protocol *protocol)
7447
size_t bytes= my_snprintf(buf, sizeof(buf),
7448
"table_id: %lu (%s.%s)",
7449
m_table_id, m_dbnam, m_tblnam);
7450
protocol->store(buf, bytes, &my_charset_bin);
7459
void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
7461
if (!print_event_info->short_form)
7463
print_header(&print_event_info->head_cache, print_event_info, TRUE);
7464
my_b_printf(&print_event_info->head_cache,
7465
"\tTable_map: `%s`.`%s` mapped to number %lu\n",
7466
m_dbnam, m_tblnam, m_table_id);
7467
print_base64(&print_event_info->body_cache, print_event_info, TRUE);
7472
/**************************************************************************
7473
Write_rows_log_event member functions
7474
**************************************************************************/
7477
Constructor used to build an event for writing to the binary log.
7479
#if !defined(MYSQL_CLIENT)
7480
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
7482
bool is_transactional)
7483
: Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
7489
Constructor used by slave to read the event from the binary log.
7491
#ifdef HAVE_REPLICATION
7492
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
7493
const Format_description_log_event
7495
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
7500
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7502
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
7507
todo: to introduce a property for the event (handler?) which forces
7508
applying the event in the replace (idempotent) fashion.
7510
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
7513
We are using REPLACE semantics and not INSERT IGNORE semantics
7514
when writing rows, that is: new rows replace old rows. We need to
7515
inform the storage engine that it should use this behaviour.
7518
/* Tell the storage engine that we are using REPLACE semantics. */
7519
thd->lex->duplicates= DUP_REPLACE;
7522
Pretend we're executing a REPLACE command: this is needed for
7523
InnoDB since it is not (properly) checking the
7524
lex->duplicates flag.
7526
thd->lex->sql_command= SQLCOM_REPLACE;
7528
Do not raise the error flag in case of hitting to an unique attribute
7530
m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
7533
m_table->file->ha_start_bulk_insert(0);
7535
We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
7536
any TIMESTAMP column with data from the row but instead will use
7537
the event's current time.
7538
As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
7539
columns, we know that all TIMESTAMP columns on slave will receive explicit
7540
data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
7541
When we allow a table without TIMESTAMP to be replicated to a table having
7542
more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
7543
column to be replicated into a BIGINT column and the slave's table has a
7544
TIMESTAMP column, then the slave's TIMESTAMP column will take its value
7545
from set_time() which we called earlier (consistent with SBR). And then in
7546
some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
7547
analyze if explicit data is provided for slave's TIMESTAMP columns).
7549
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
7555
Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
7559
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
7561
m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
7562
m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
7564
resetting the extra with
7565
table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
7567
explanation: file->reset() performs this duty
7568
ultimately. Still todo: fix
7571
if ((local_error= m_table->file->ha_end_bulk_insert()))
7573
m_table->file->print_error(local_error, MYF(0));
7575
return error? error : local_error;
7578
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7581
Check if there are more UNIQUE keys after the given key.
7584
last_uniq_key(TABLE *table, uint keyno)
7586
while (++keyno < table->s->keys)
7587
if (table->key_info[keyno].flags & HA_NOSAME)
7593
Check if an error is a duplicate key error.
7595
This function is used to check if an error code is one of the
7596
duplicate key error, i.e., and error code for which it is sensible
7597
to do a <code>get_dup_key()</code> to retrieve the duplicate key.
7599
@param errcode The error code to check.
7601
@return <code>true</code> if the error code is such that
7602
<code>get_dup_key()</code> will return true, <code>false</code>
7606
is_duplicate_key_error(int errcode)
7610
case HA_ERR_FOUND_DUPP_KEY:
7611
case HA_ERR_FOUND_DUPP_UNIQUE:
7618
Write the current row into event's table.
7620
The row is located in the row buffer, pointed by @c m_curr_row member.
7621
Number of columns of the row is stored in @c m_width member (it can be
7622
different from the number of columns in the table to which we insert).
7623
Bitmap @c m_cols indicates which columns are present in the row. It is assumed
7624
that event's table is already open and pointed by @c m_table.
7626
If the same record already exists in the table it can be either overwritten
7627
or an error is reported depending on the value of @c overwrite flag
7628
(error reporting not yet implemented). Note that the matching record can be
7629
different from the row we insert if we use primary keys to identify records in
7632
The row to be inserted can contain values only for selected columns. The
7633
missing columns are filled with default values using @c prepare_record()
7634
function. If a matching record is found in the table and @c overwritte is
7635
true, the missing columns are taken from it.
7637
@param rli Relay log info (needed for row unpacking).
7639
Shall we overwrite if the row already exists or signal
7640
error (currently ignored).
7642
@returns Error code on failure, 0 on success.
7644
This method, if successful, sets @c m_curr_row_end pointer to point at the
7645
next row in the rows buffer. This is done when unpacking the row to be
7648
@note If a matching record is found, it is either updated using
7649
@c ha_update_row() or first deleted and then new record written.
7653
Rows_log_event::write_row(const Relay_log_info *const rli,
7654
const bool overwrite)
7656
DBUG_ENTER("write_row");
7657
DBUG_ASSERT(m_table != NULL && thd != NULL);
7659
TABLE *table= m_table; // pointer to event's table
7662
auto_afree_ptr<char> key(NULL);
7664
/* fill table->record[0] with default values */
7667
We only check if the columns have default values for non-NDB
7668
engines, for NDB we ignore the check since updates are sent as
7669
writes, causing errors when trying to prepare the record.
7671
TODO[ndb]: Elimiate this hard-coded dependency on NDB. Ideally,
7672
the engine should be able to set a flag that it want the default
7673
values filled in and one flag to handle the case that the default
7674
values should be checked. Maybe these two flags can be combined.
7676
if ((error= prepare_record(table, &m_cols, m_width,
7677
table->file->ht->db_type != DB_TYPE_NDBCLUSTER)))
7680
/* unpack row into table->record[0] */
7681
error= unpack_current_row(rli, &m_cols);
7683
// Temporary fix to find out why it fails [/Matz]
7684
memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
7687
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
7688
DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
7689
DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
7693
Try to write record. If a corresponding record already exists in the table,
7694
we try to change it using ha_update_row() if possible. Otherwise we delete
7695
it and repeat the whole process again.
7697
TODO: Add safety measures against infinite looping.
7700
while ((error= table->file->ha_write_row(table->record[0])))
7702
if (error == HA_ERR_LOCK_DEADLOCK ||
7703
error == HA_ERR_LOCK_WAIT_TIMEOUT ||
7704
(keynum= table->file->get_dup_key(error)) < 0 ||
7707
DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
7709
Deadlock, waiting for lock or just an error from the handler
7710
such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
7711
Retrieval of the duplicate key number may fail
7712
- either because the error was not "duplicate key" error
7713
- or because the information which key is not available
7715
table->file->print_error(error, MYF(0));
7719
We need to retrieve the old row into record[1] to be able to
7720
either update or delete the offending record. We either:
7722
- use rnd_pos() with a row-id (available as dupp_row) to the
7723
offending row, if that is possible (MyISAM and Blackhole), or else
7725
- use index_read_idx() with the key that is duplicated, to
7726
retrieve the offending row.
7728
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
7730
DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
7731
if (table->file->inited && (error= table->file->ha_index_end()))
7733
if ((error= table->file->ha_rnd_init(FALSE)))
7736
error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
7737
table->file->ha_rnd_end();
7740
DBUG_PRINT("info",("rnd_pos() returns error %d",error));
7741
table->file->print_error(error, MYF(0));
7747
DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
7749
if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
7751
DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
7752
DBUG_RETURN(my_errno);
7755
if (key.get() == NULL)
7757
key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
7758
if (key.get() == NULL)
7760
DBUG_PRINT("info",("Can't allocate key buffer"));
7761
DBUG_RETURN(ENOMEM);
7765
key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
7767
error= table->file->index_read_idx_map(table->record[1], keynum,
7768
(const uchar*)key.get(),
7773
DBUG_PRINT("info",("index_read_idx() returns error %d",error));
7774
table->file->print_error(error, MYF(0));
7780
Now, record[1] should contain the offending row. That
7781
will enable us to update it or, alternatively, delete it (so
7782
that we can insert the new row afterwards).
7786
If row is incomplete we will use the record found to fill
7789
if (!get_flags(COMPLETE_ROWS_F))
7791
restore_record(table,record[1]);
7792
error= unpack_current_row(rli, &m_cols);
7796
DBUG_PRINT("debug",("preparing for update: before and after image"));
7797
DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
7798
DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
7802
REPLACE is defined as either INSERT or DELETE + INSERT. If
7803
possible, we can replace it with an UPDATE, but that will not
7804
work on InnoDB if FOREIGN KEY checks are necessary.
7806
I (Matz) am not sure of the reason for the last_uniq_key()
7807
check as, but I'm guessing that it's something along the
7810
Suppose that we got the duplicate key to be a key that is not
7811
the last unique key for the table and we perform an update:
7812
then there might be another key for which the unique check will
7813
fail, so we're better off just deleting the row and inserting
7816
if (last_uniq_key(table, keynum) &&
7817
!table->file->referenced_by_foreign_key())
7819
DBUG_PRINT("info",("Updating row using ha_update_row()"));
7820
error=table->file->ha_update_row(table->record[1],
7824
case HA_ERR_RECORD_IS_THE_SAME:
7825
DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
7826
" ha_update_row()"));
7833
DBUG_PRINT("info",("ha_update_row() returns error %d",error));
7834
table->file->print_error(error, MYF(0));
7841
DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
7842
if ((error= table->file->ha_delete_row(table->record[1])))
7844
DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
7845
table->file->print_error(error, MYF(0));
7848
/* Will retry ha_write_row() with the offending row removed. */
7858
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
7860
DBUG_ASSERT(m_table != NULL);
7862
write_row(rli, /* if 1 then overwrite */
7863
bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
7865
if (error && !thd->is_error())
7868
my_error(ER_UNKNOWN_ERROR, MYF(0));
7874
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
7877
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
7879
Rows_log_event::print_helper(file, print_event_info, "Write_rows");
7883
/**************************************************************************
7884
Delete_rows_log_event member functions
7885
**************************************************************************/
7887
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7889
Compares table->record[0] and table->record[1]
7891
Returns TRUE if different.
7893
static bool record_compare(TABLE *table)
7896
Need to set the X bit and the filler bits in both records since
7897
there are engines that do not set it correctly.
7899
In addition, since MyISAM checks that one hasn't tampered with the
7900
record, it is necessary to restore the old bytes into the record
7901
after doing the comparison.
7903
TODO[record format ndb]: Remove it once NDB returns correct
7904
records. Check that the other engines also return correct records.
7907
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
7908
DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
7911
uchar saved_x[2], saved_filler[2];
7913
if (table->s->null_bytes > 0)
7915
for (int i = 0 ; i < 2 ; ++i)
7917
saved_x[i]= table->record[i][0];
7918
saved_filler[i]= table->record[i][table->s->null_bytes - 1];
7919
table->record[i][0]|= 1U;
7920
table->record[i][table->s->null_bytes - 1]|=
7921
256U - (1U << table->s->last_null_bit_pos);
7925
if (table->s->blob_fields + table->s->varchar_fields == 0)
7927
result= cmp_record(table,record[1]);
7928
goto record_compare_exit;
7931
/* Compare null bits */
7932
if (memcmp(table->null_flags,
7933
table->null_flags+table->s->rec_buff_length,
7934
table->s->null_bytes))
7936
result= TRUE; // Diff in NULL value
7937
goto record_compare_exit;
7940
/* Compare updated fields */
7941
for (Field **ptr=table->field ; *ptr ; ptr++)
7943
if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
7946
goto record_compare_exit;
7950
record_compare_exit:
7952
Restore the saved bytes.
7954
TODO[record format ndb]: Remove this code once NDB returns the
7955
correct record format.
7957
if (table->s->null_bytes > 0)
7959
for (int i = 0 ; i < 2 ; ++i)
7961
table->record[i][0]= saved_x[i];
7962
table->record[i][table->s->null_bytes - 1]= saved_filler[i];
7970
Locate the current row in event's table.
7972
The current row is pointed by @c m_curr_row. Member @c m_width tells how many
7973
columns are there in the row (this can be differnet from the number of columns
7974
in the table). It is assumed that event's table is already open and pointed
7977
If a corresponding record is found in the table it is stored in
7978
@c m_table->record[0]. Note that when record is located based on a primary
7979
key, it is possible that the record found differs from the row being located.
7981
If no key is specified or table does not have keys, a table scan is used to
7982
find the row. In that case the row should be complete and contain values for
7983
all columns. However, it can still be shorter than the table, i.e. the table
7984
can contain extra columns not present in the row. It is also possible that
7985
the table has fewer columns than the row being located.
7987
@returns Error code on failure, 0 on success.
7989
@post In case of success @c m_table->record[0] contains the record found.
7990
Also, the internal "cursor" of the table is positioned at the record found.
7992
@note If the engine allows random access of the records, a combination of
7993
@c position() and @c rnd_pos() will be used.
7996
int Rows_log_event::find_row(const Relay_log_info *rli)
7998
DBUG_ENTER("Rows_log_event::find_row");
8000
DBUG_ASSERT(m_table && m_table->in_use != NULL);
8002
TABLE *table= m_table;
8005
/* unpack row - missing fields get default values */
8006
prepare_record(table, &m_cols, m_width, FALSE /* don't check errors */);
8007
error= unpack_current_row(rli, &m_cols);
8009
// Temporary fix to find out why it fails [/Matz]
8010
memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
8013
DBUG_PRINT("info",("looking for the following record"));
8014
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
8015
DBUG_DUMP("read_set", (uchar*) table->read_set->bitmap, (table->read_set->n_bits + 7) / 8);
8018
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
8019
table->s->primary_key < MAX_KEY)
8022
Use a more efficient method to fetch the record given by
8023
table->record[0] if the engine allows it. We first compute a
8024
row reference using the position() member function (it will be
8025
stored in table->file->ref) and the use rnd_pos() to position
8026
the "cursor" (i.e., record[0] in this case) at the correct row.
8028
TODO: Add a check that the correct record has been fetched by
8029
comparing with the original record. Take into account that the
8030
record on the master and slave can be of different
8031
length. Something along these lines should work:
8033
ADD>>> store_record(table,record[1]);
8034
int error= table->file->rnd_pos(table->record[0], table->file->ref);
8035
ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
8036
table->s->reclength) == 0);
8039
DBUG_PRINT("info",("locating record using primary key (position)"));
8040
int error= table->file->rnd_pos_by_record(table->record[0]);
8041
table->file->ha_rnd_end();
8044
DBUG_PRINT("info",("rnd_pos returns error %d",error));
8045
table->file->print_error(error, MYF(0));
8050
// We can't use position() - try other methods.
8053
Save copy of the record in table->record[1]. It might be needed
8054
later if linear search is used to find exact match.
8056
store_record(table,record[1]);
8058
if (table->s->keys > 0)
8060
DBUG_PRINT("info",("locating record using primary key (index_read)"));
8062
/* We have a key: search the table using the index */
8063
if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
8065
DBUG_PRINT("info",("ha_index_init returns error %d",error));
8066
table->file->print_error(error, MYF(0));
8070
/* Fill key data for the row */
8073
key_copy(m_key, table->record[0], table->key_info, 0);
8076
Don't print debug messages when running valgrind since they can
8077
trigger false warnings.
8080
DBUG_DUMP("key data", m_key, table->key_info->key_length);
8084
We need to set the null bytes to ensure that the filler bit are
8085
all set when returning. There are storage engines that just set
8086
the necessary bits on the bytes and don't set the filler bits
8089
my_ptrdiff_t const pos=
8090
table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
8091
table->record[0][pos]= 0xFF;
8093
if ((error= table->file->index_read_map(table->record[0], m_key,
8095
HA_READ_KEY_EXACT)))
8097
DBUG_PRINT("info",("no record matching the key found in the table"));
8098
table->file->print_error(error, MYF(0));
8099
table->file->ha_index_end();
8104
Don't print debug messages when running valgrind since they can
8105
trigger false warnings.
8108
DBUG_PRINT("info",("found first matching record"));
8109
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
8112
Below is a minor "optimization". If the key (i.e., key number
8113
0) has the HA_NOSAME flag set, we know that we have found the
8114
correct record (since there can be no duplicates); otherwise, we
8115
have to compare the record with the one found to see if it is
8118
CAVEAT! This behaviour is essential for the replication of,
8119
e.g., the mysql.proc table since the correct record *shall* be
8120
found using the primary key *only*. There shall be no
8121
comparison of non-PK columns to decide if the correct record is
8122
found. I can see no scenario where it would be incorrect to
8123
chose the row to change only using a PK or an UNNI.
8125
if (table->key_info->flags & HA_NOSAME)
8127
table->file->ha_index_end();
8132
In case key is not unique, we still have to iterate over records found
8133
and find the one which is identical to the row given. A copy of the
8134
record we are looking for is stored in record[1].
8136
DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
8138
while (record_compare(table))
8141
We need to set the null bytes to ensure that the filler bit
8142
are all set when returning. There are storage engines that
8143
just set the necessary bits on the bytes and don't set the
8144
filler bits correctly.
8146
TODO[record format ndb]: Remove this code once NDB returns the
8147
correct record format.
8149
if (table->s->null_bytes > 0)
8151
table->record[0][table->s->null_bytes - 1]|=
8152
256U - (1U << table->s->last_null_bit_pos);
8155
if ((error= table->file->index_next(table->record[0])))
8157
DBUG_PRINT("info",("no record matching the given row found"));
8158
table->file->print_error(error, MYF(0));
8159
table->file->ha_index_end();
8165
Have to restart the scan to be able to fetch the next row.
8167
table->file->ha_index_end();
8171
DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
8173
int restart_count= 0; // Number of times scanning has restarted from top
8175
/* We don't have a key: search the table using rnd_next() */
8176
if ((error= table->file->ha_rnd_init(1)))
8178
DBUG_PRINT("info",("error initializing table scan"
8179
" (ha_rnd_init returns %d)",error));
8180
table->file->print_error(error, MYF(0));
8184
/* Continue until we find the right record or have made a full loop */
8187
error= table->file->rnd_next(table->record[0]);
8192
case HA_ERR_RECORD_DELETED:
8195
case HA_ERR_END_OF_FILE:
8196
if (++restart_count < 2)
8197
table->file->ha_rnd_init(1);
8201
DBUG_PRINT("info", ("Failed to get next record"
8202
" (rnd_next returns %d)",error));
8203
table->file->print_error(error, MYF(0));
8204
table->file->ha_rnd_end();
8208
while (restart_count < 2 && record_compare(table));
8211
Note: above record_compare will take into accout all record fields
8212
which might be incorrect in case a partial row was given in the event
8216
Have to restart the scan to be able to fetch the next row.
8218
if (restart_count == 2)
8220
DBUG_PRINT("info", ("Record not found"));
8224
DBUG_DUMP("record found", table->record[0], table->s->reclength);
8226
table->file->ha_rnd_end();
8228
DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
8232
table->default_column_bitmaps();
8235
table->default_column_bitmaps();
8242
Constructor used to build an event for writing to the binary log.
8245
#ifndef MYSQL_CLIENT
8246
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
8248
bool is_transactional)
8249
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
8252
#endif /* #if !defined(MYSQL_CLIENT) */
8255
Constructor used by slave to read the event from the binary log.
8257
#ifdef HAVE_REPLICATION
8258
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
8259
const Format_description_log_event
8261
: Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
8266
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
8269
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
8271
if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
8272
m_table->s->primary_key < MAX_KEY)
8275
We don't need to allocate any memory for m_key since it is not used.
8280
if (m_table->s->keys > 0)
8282
// Allocate buffer for key searches
8283
m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
8285
return HA_ERR_OUT_OF_MEM;
8292
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
8295
/*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
8296
m_table->file->ha_index_or_rnd_end();
8297
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
8303
int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
8306
DBUG_ASSERT(m_table != NULL);
8308
if (!(error= find_row(rli)))
8311
Delete the record found, located in record[0]
8313
error= m_table->file->ha_delete_row(m_table->record[0]);
8318
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
8321
void Delete_rows_log_event::print(FILE *file,
8322
PRINT_EVENT_INFO* print_event_info)
8324
Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
8329
/**************************************************************************
8330
Update_rows_log_event member functions
8331
**************************************************************************/
8334
Constructor used to build an event for writing to the binary log.
8336
#if !defined(MYSQL_CLIENT)
8337
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
8339
bool is_transactional)
8340
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
8342
init(tbl_arg->write_set);
8345
void Update_rows_log_event::init(MY_BITMAP const *cols)
8347
/* if bitmap_init fails, caught in is_valid() */
8348
if (likely(!bitmap_init(&m_cols_ai,
8349
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
8353
/* Cols can be zero if this is a dummy binrows event */
8354
if (likely(cols != NULL))
8356
memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
8357
create_last_word_mask(&m_cols_ai);
8361
#endif /* !defined(MYSQL_CLIENT) */
8364
Update_rows_log_event::~Update_rows_log_event()
8366
if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
8367
m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
8368
bitmap_free(&m_cols_ai); // To pair with bitmap_init().
8373
Constructor used by slave to read the event from the binary log.
8375
#ifdef HAVE_REPLICATION
8376
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
8378
Format_description_log_event
8380
: Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
8385
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
8388
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
8390
if (m_table->s->keys > 0)
8392
// Allocate buffer for key searches
8393
m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
8395
return HA_ERR_OUT_OF_MEM;
8398
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
8404
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
8407
/*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
8408
m_table->file->ha_index_or_rnd_end();
8409
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
8416
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
8418
DBUG_ASSERT(m_table != NULL);
8420
int error= find_row(rli);
8424
We need to read the second image in the event of error to be
8425
able to skip to the next pair of updates
8427
m_curr_row= m_curr_row_end;
8428
unpack_current_row(rli, &m_cols_ai);
8433
This is the situation after locating BI:
8435
===|=== before image ====|=== after image ===|===
8437
m_curr_row m_curr_row_end
8439
BI found in the table is stored in record[0]. We copy it to record[1]
8440
and unpack AI to record[0].
8443
store_record(m_table,record[1]);
8445
m_curr_row= m_curr_row_end;
8446
error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
8449
Now we have the right row to update. The old row (the one we're
8450
looking for) is in record[1] and the new row is in record[0].
8454
Don't print debug messages when running valgrind since they can
8455
trigger false warnings.
8457
DBUG_PRINT("info",("Updating row in table"));
8458
DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
8459
DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
8462
// Temporary fix to find out why it fails [/Matz]
8463
memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
8464
memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
8466
error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
8467
if (error == HA_ERR_RECORD_IS_THE_SAME)
8473
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
8476
void Update_rows_log_event::print(FILE *file,
8477
PRINT_EVENT_INFO* print_event_info)
8479
Rows_log_event::print_helper(file, print_event_info, "Update_rows");
8484
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
8485
const Format_description_log_event *descr_event)
8486
: Log_event(buf, descr_event)
8488
DBUG_ENTER("Incident_log_event::Incident_log_event");
8489
uint8 const common_header_len=
8490
descr_event->common_header_len;
8491
uint8 const post_header_len=
8492
descr_event->post_header_len[INCIDENT_EVENT-1];
8494
DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
8495
event_len, common_header_len, post_header_len));
8497
m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
8498
char const *ptr= buf + common_header_len + post_header_len;
8499
char const *const str_end= buf + event_len;
8500
uint8 len= 0; // Assignment to keep compiler happy
8501
const char *str= NULL; // Assignment to keep compiler happy
8502
read_str(&ptr, str_end, &str, &len);
8503
m_message.str= const_cast<char*>(str);
8504
m_message.length= len;
8505
DBUG_PRINT("info", ("m_incident: %d", m_incident));
8510
Incident_log_event::~Incident_log_event()
8516
Incident_log_event::description() const
8518
static const char *const description[]= {
8519
"NOTHING", // Not used
8523
DBUG_PRINT("info", ("m_incident: %d", m_incident));
8525
DBUG_ASSERT(0 <= m_incident);
8526
DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
8528
return description[m_incident];
8532
#ifndef MYSQL_CLIENT
8533
void Incident_log_event::pack_info(Protocol *protocol)
8537
if (m_message.length > 0)
8538
bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
8539
m_incident, description());
8541
bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
8542
m_incident, description(), m_message.str);
8543
protocol->store(buf, bytes, &my_charset_bin);
8550
Incident_log_event::print(FILE *file,
8551
PRINT_EVENT_INFO *print_event_info)
8553
if (print_event_info->short_form)
8556
Write_on_release_cache cache(&print_event_info->head_cache, file);
8557
print_header(&cache, print_event_info, FALSE);
8558
my_b_printf(&cache, "\n# Incident: %s", description());
8562
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8564
Incident_log_event::do_apply_event(Relay_log_info const *rli)
8566
DBUG_ENTER("Incident_log_event::do_apply_event");
8567
rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
8568
ER(ER_SLAVE_INCIDENT),
8570
m_message.length > 0 ? m_message.str : "<none>");
8576
Incident_log_event::write_data_header(IO_CACHE *file)
8578
DBUG_ENTER("Incident_log_event::write_data_header");
8579
DBUG_PRINT("enter", ("m_incident: %d", m_incident));
8580
uchar buf[sizeof(int16)];
8581
int2store(buf, (int16) m_incident);
8582
DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
8586
Incident_log_event::write_data_body(IO_CACHE *file)
8588
DBUG_ENTER("Incident_log_event::write_data_body");
8589
DBUG_RETURN(write_str(file, m_message.str, m_message.length));
8592
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8593
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
8594
const Format_description_log_event* description_event)
8595
:Log_event(buf, description_event)
8597
uint8 header_size= description_event->common_header_len;
8598
ident_len = event_len - header_size;
8599
set_if_smaller(ident_len,FN_REFLEN-1);
8600
log_ident= buf + header_size;
8607
The default values for these variables should be values that are
8608
*incorrect*, i.e., values that cannot occur in an event. This way,
8609
they will always be printed for the first event.
8611
st_print_event_info::st_print_event_info()
8612
:flags2_inited(0), sql_mode_inited(0),
8613
auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
8614
lc_time_names_number(~0),
8615
charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
8616
thread_id(0), thread_id_printed(false),
8617
base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
8620
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
8621
program's startup, but these explicit bzero() is for the day someone
8622
creates dynamic instances.
8624
bzero(db, sizeof(db));
8625
bzero(charset, sizeof(charset));
8626
bzero(time_zone_str, sizeof(time_zone_str));
8629
myf const flags = MYF(MY_WME | MY_NABP);
8630
open_cached_file(&head_cache, NULL, NULL, 0, flags);
8631
open_cached_file(&body_cache, NULL, NULL, 0, flags);