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 */
17
#ifndef DRIZZLE_CLIENT
19
#include <drizzled/server_includes.h>
22
#include "rpl_filter.h"
23
#include "rpl_utility.h"
24
#include "rpl_record.h"
25
#include <mysys/my_dir.h>
26
#include <drizzled/drizzled_error_messages.h>
28
#endif /* !DRIZZLE_CLIENT */
30
#include <mysys/base64.h>
31
#include <mysys/my_bitmap.h>
33
#include <libdrizzle/gettext.h>
35
#define log_cs &my_charset_latin1
37
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
41
Size of buffer for printing a double in format %.<PREC>g
43
optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
44
exponent digits + '\0'
46
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
49
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
50
static const char *HA_ERR(int i)
53
case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
54
case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
55
case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
56
case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
57
case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
58
case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
59
case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
60
case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
61
case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
62
case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
63
case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
64
case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
65
case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
66
case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
67
case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
68
case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
69
case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
70
case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
71
case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
72
case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
73
case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
74
case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
75
case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
76
case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
77
case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
78
case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
79
case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
80
case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
81
case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
82
case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
83
case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
84
case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
85
case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
86
case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
87
case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
88
case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
89
case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
90
case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
91
case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
92
case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
93
case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
94
case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
95
case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
96
case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
97
case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
98
case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
99
case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
100
case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
101
case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
102
case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
108
Error reporting facility for Rows_log_event::do_apply_event
110
@param level error, warning or info
111
@param ha_error HA_ERR_ code
112
@param rli pointer to the active Relay_log_info instance
113
@param thd pointer to the slave thread's thd
114
@param table pointer to the event's table object
115
@param type the type of the event
116
@param log_name the master binlog file name
117
@param pos the master binlog file pos (the next after the event)
120
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
121
Relay_log_info const *rli, THD *thd,
122
Table *table, const char * type,
123
const char *log_name, ulong pos)
125
const char *handler_error= HA_ERR(ha_error);
126
char buff[MAX_SLAVE_ERRMSG], *slider;
127
const char *buff_end= buff + sizeof(buff);
129
List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
133
for (err= it++, slider= buff; err && slider < buff_end - 1;
134
slider += len, err= it++)
136
len= snprintf(slider, buff_end - slider,
137
" %s, Error_code: %d;", err->msg, err->code);
140
rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
141
"Could not execute %s event on table %s.%s;"
142
"%s handler error %s; "
143
"the event's master log %s, end_log_pos %lu",
144
type, table->s->db.str,
145
table->s->table_name.str,
147
handler_error == NULL? "<unknown>" : handler_error,
153
Cache that will automatically be written to a dedicated file on
159
class Write_on_release_cache
167
typedef unsigned short flag_set;
173
Write_on_release_cache
174
cache Pointer to cache to use
175
file File to write cache to upon destruction
176
flags Flags for the cache
180
Class used to guarantee copy of cache to file before exiting the
181
current block. On successful copy of the cache, the cache will
182
be reinited as a WRITE_CACHE.
184
Currently, a pointer to the cache is provided in the
185
constructor, but it would be possible to create a subclass
186
holding the IO_CACHE itself.
188
Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
189
: m_cache(cache), m_file(file), m_flags(flags)
191
reinit_io_cache(m_cache, WRITE_CACHE, 0L, false, true);
194
~Write_on_release_cache()
196
copy_event_cache_to_file_and_reinit(m_cache, m_file);
197
if (m_flags | FLUSH_F)
202
Return a pointer to the internal IO_CACHE.
209
Function to return a pointer to the internal cache, so that the
210
object can be treated as a IO_CACHE and used with the my_b_*
214
A pointer to the internal IO_CACHE.
216
IO_CACHE *operator&()
222
// Hidden, to prevent usage.
223
Write_on_release_cache(Write_on_release_cache const&);
230
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
236
#ifdef DRIZZLE_CLIENT
237
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
239
const char* end = str + len;
240
my_b_printf(cache, "\'");
244
switch ((c=*str++)) {
245
case '\n': my_b_printf(cache, "\\n"); break;
246
case '\r': my_b_printf(cache, "\\r"); break;
247
case '\\': my_b_printf(cache, "\\\\"); break;
248
case '\b': my_b_printf(cache, "\\b"); break;
249
case '\t': my_b_printf(cache, "\\t"); break;
250
case '\'': my_b_printf(cache, "\\'"); break;
251
case 0 : my_b_printf(cache, "\\0"); break;
253
my_b_printf(cache, "%c", c);
257
my_b_printf(cache, "\'");
259
#endif /* DRIZZLE_CLIENT */
261
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
263
static void clear_all_errors(THD *thd, Relay_log_info *rli)
265
thd->is_slave_error = 0;
272
Ignore error code specified on command line.
275
inline int ignored_error_code(int err_code)
277
return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
278
(use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
287
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
288
static char *pretty_print_str(char *packet, const char *str, int len)
290
const char *end= str + len;
296
switch ((c=*str++)) {
297
case '\n': *pos++= '\\'; *pos++= 'n'; break;
298
case '\r': *pos++= '\\'; *pos++= 'r'; break;
299
case '\\': *pos++= '\\'; *pos++= '\\'; break;
300
case '\b': *pos++= '\\'; *pos++= 'b'; break;
301
case '\t': *pos++= '\\'; *pos++= 't'; break;
302
case '\'': *pos++= '\\'; *pos++= '\''; break;
303
case 0 : *pos++= '\\'; *pos++= '0'; break;
312
#endif /* !DRIZZLE_CLIENT */
315
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
318
Creates a temporary name for load data infile:.
320
@param buf Store new filename here
321
@param file_id File_id (part of file name)
322
@param event_server_id Event_id (part of file name)
323
@param ext Extension for file name
326
Pointer to start of extension
329
static char *slave_load_file_stem(char *buf, uint file_id,
330
int event_server_id, const char *ext)
333
fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
337
buf = int10_to_str(::server_id, buf, 10);
339
buf = int10_to_str(event_server_id, buf, 10);
341
res= int10_to_str(file_id, buf, 10);
342
stpcpy(res, ext); // Add extension last
343
return res; // Pointer to extension
348
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
351
Delete all temporary files used for SQL_LOAD.
354
static void cleanup_load_tmpdir()
359
char fname[FN_REFLEN], prefbuf[31], *p;
361
if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
365
When we are deleting temporary files, we should only remove
366
the files associated with the server id of our server.
367
We don't use event_server_id here because since we've disabled
368
direct binlogging of Create_file/Append_file/Exec_load events
369
we cannot meet Start_log event in the middle of events from one
372
p= strmake(prefbuf, STRING_WITH_LEN("SQL_LOAD-"));
373
p= int10_to_str(::server_id, p, 10);
377
for (i=0 ; i < (uint)dirp->number_off_files; i++)
379
file=dirp->dir_entry+i;
380
if (is_prefix(file->name, prefbuf))
382
fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
383
my_delete(fname, MYF(0));
396
static bool write_str(IO_CACHE *file, const char *str, uint length)
399
tmp[0]= (uchar) length;
400
return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
401
my_b_safe_write(file, (uchar*) str, length));
409
static inline int read_str(const char **buf, const char *buf_end,
410
const char **str, uint8_t *len)
412
if (*buf + ((uint) (uchar) **buf) >= buf_end)
414
*len= (uint8_t) **buf;
416
(*buf)+= (uint) *len+1;
422
Transforms a string into "" or its expression in 0x... form.
425
char *str_to_hex(char *to, const char *from, uint len)
431
to= octet2hex(to, from, len);
434
to= stpcpy(to, "\"\"");
435
return to; // pointer to end 0 of 'to'
438
#ifndef DRIZZLE_CLIENT
441
Append a version of the 'from' string suitable for use in a query to
442
the 'to' string. To generate a correct escaping, the character set
443
information in 'csinfo' is used.
447
append_query_string(const CHARSET_INFO * const csinfo,
448
String const *from, String *to)
451
uint32_t const orig_len= to->length();
452
if (to->reserve(orig_len + from->length()*2+3))
455
beg= to->c_ptr_quick() + to->length();
457
if (csinfo->escape_with_backslash_is_dangerous)
458
ptr= str_to_hex(ptr, from->ptr(), from->length());
462
ptr+= escape_string_for_drizzle(csinfo, ptr, 0,
463
from->ptr(), from->length());
466
to->length(orig_len + ptr - beg);
473
Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
474
commands just before it prints a query.
477
#ifdef DRIZZLE_CLIENT
479
static void print_set_option(IO_CACHE* file, uint32_t bits_changed,
480
uint32_t option, uint32_t flags, const char* name,
483
if (bits_changed & option)
486
my_b_printf(file,", ");
487
my_b_printf(file,"%s=%d", name, test(flags & option));
493
/**************************************************************************
494
Log_event methods (= the parent class of all events)
495
**************************************************************************/
499
returns the human readable name of the event's type
502
const char* Log_event::get_type_str(Log_event_type type)
505
case START_EVENT_V3: return "Start_v3";
506
case STOP_EVENT: return "Stop";
507
case QUERY_EVENT: return "Query";
508
case ROTATE_EVENT: return "Rotate";
509
case INTVAR_EVENT: return "Intvar";
510
case LOAD_EVENT: return "Load";
511
case NEW_LOAD_EVENT: return "New_load";
512
case SLAVE_EVENT: return "Slave";
513
case CREATE_FILE_EVENT: return "Create_file";
514
case APPEND_BLOCK_EVENT: return "Append_block";
515
case DELETE_FILE_EVENT: return "Delete_file";
516
case EXEC_LOAD_EVENT: return "Exec_load";
517
case RAND_EVENT: return "RAND";
518
case XID_EVENT: return "Xid";
519
case USER_VAR_EVENT: return "User var";
520
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
521
case TABLE_MAP_EVENT: return "Table_map";
522
case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
523
case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
524
case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
525
case WRITE_ROWS_EVENT: return "Write_rows";
526
case UPDATE_ROWS_EVENT: return "Update_rows";
527
case DELETE_ROWS_EVENT: return "Delete_rows";
528
case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
529
case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
530
case INCIDENT_EVENT: return "Incident";
531
default: return "Unknown"; /* impossible */
535
const char* Log_event::get_type_str()
537
return get_type_str(get_type_code());
542
Log_event::Log_event()
545
#ifndef DRIZZLE_CLIENT
546
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
547
:log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
549
server_id= thd->server_id;
550
when= thd->start_time;
551
cache_stmt= using_trans;
556
This minimal constructor is for when you are not even sure that there
557
is a valid THD. For example in the server when we are shutting down or
558
flushing logs after receiving a SIGHUP (then we must write a Rotate to
559
the binlog but we have no THD, so we need this minimal constructor).
562
Log_event::Log_event()
563
:temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
566
server_id= ::server_id;
568
We can't call my_time() here as this would cause a call before
574
#endif /* !DRIZZLE_CLIENT */
578
Log_event::Log_event()
581
Log_event::Log_event(const char* buf,
582
const Format_description_log_event* description_event)
583
:temp_buf(0), cache_stmt(0)
585
#ifndef DRIZZLE_CLIENT
588
when = uint4korr(buf);
589
server_id = uint4korr(buf + SERVER_ID_OFFSET);
590
data_written= uint4korr(buf + EVENT_LEN_OFFSET);
591
if (description_event->binlog_version==1)
598
log_pos= uint4korr(buf + LOG_POS_OFFSET);
600
If the log is 4.0 (so here it can only be a 4.0 relay log read by
601
the SQL thread or a 4.0 master binlog read by the I/O thread),
602
log_pos is the beginning of the event: we transform it into the end
603
of the event, which is more useful.
604
But how do you know that the log is 4.0: you know it if
605
description_event is version 3 *and* you are not reading a
606
Format_desc (remember that mysqlbinlog starts by assuming that 5.0
607
logs are in 4.0 format, until it finds a Format_desc).
609
if (description_event->binlog_version==3 &&
610
buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
613
If log_pos=0, don't change it. log_pos==0 is a marker to mean
614
"don't change rli->group_master_log_pos" (see
615
inc_group_relay_log_pos()). As it is unreal log_pos, adding the
616
event len's is nonsense. For example, a fake Rotate event should
617
not have its log_pos (which is 0) changed or it will modify
618
Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
619
value of (a non-zero offset which does not exist in the master's
620
binlog, so which will cause problems if the user uses this value
623
log_pos+= data_written; /* purecov: inspected */
626
flags= uint2korr(buf + FLAGS_OFFSET);
627
if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
628
(buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
631
These events always have a header which stops here (i.e. their
635
Initialization to zero of all other Log_event members as they're
636
not specified. Currently there are no such members; in the future
637
there will be an event UID (but Format_description and Rotate
638
don't need this UID, as they are not propagated through
639
--log-slave-updates (remember the UID is used to not play a query
640
twice when you have two masters which are slaves of a 3rd master).
645
/* otherwise, go on with reading the header from buf (nothing now) */
648
#ifndef DRIZZLE_CLIENT
649
#ifdef HAVE_REPLICATION
651
int Log_event::do_update_pos(Relay_log_info *rli)
654
rli is null when (as far as I (Guilhem) know) the caller is
655
Load_log_event::do_apply_event *and* that one is called from
656
Execute_load_log_event::do_apply_event. In this case, we don't
657
do anything here ; Execute_load_log_event::do_apply_event will
658
call Log_event::do_apply_event again later with the proper rli.
659
Strictly speaking, if we were sure that rli is null only in the
660
case discussed above, 'if (rli)' is useless here. But as we are
661
not 100% sure, keep it for now.
663
Matz: I don't think we will need this check with this refactoring.
668
bug#29309 simulation: resetting the flag to force
669
wrong behaviour of artificial event to update
670
rli->last_master_timestamp for only one time -
671
the first FLUSH LOGS in the test.
673
if (debug_not_change_ts_if_art_event == 1
674
&& is_artificial_event())
675
debug_not_change_ts_if_art_event= 0;
676
rli->stmt_done(log_pos,
677
is_artificial_event() &&
678
debug_not_change_ts_if_art_event > 0 ? 0 : when);
679
if (debug_not_change_ts_if_art_event == 0)
680
debug_not_change_ts_if_art_event= 2;
682
return 0; // Cannot fail currently
686
Log_event::enum_skip_reason
687
Log_event::do_shall_skip(Relay_log_info *rli)
689
if ((server_id == ::server_id && !rli->replicate_same_server_id) || (rli->slave_skip_counter == 1 && rli->is_in_group()))
690
return EVENT_SKIP_IGNORE;
691
else if (rli->slave_skip_counter > 0)
692
return EVENT_SKIP_COUNT;
694
return EVENT_SKIP_NOT;
699
Log_event::pack_info()
702
void Log_event::pack_info(Protocol *protocol)
704
protocol->store("", &my_charset_bin);
709
Only called by SHOW BINLOG EVENTS
711
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
713
const char *p= strrchr(log_name, FN_LIBCHAR);
714
const char *event_type;
718
protocol->prepare_for_resend();
719
protocol->store(log_name, &my_charset_bin);
720
protocol->store((uint64_t) pos);
721
event_type = get_type_str();
722
protocol->store(event_type, strlen(event_type), &my_charset_bin);
723
protocol->store((uint32_t) server_id);
724
protocol->store((uint64_t) log_pos);
726
return protocol->write();
728
#endif /* HAVE_REPLICATION */
732
init_show_field_list() prepares the column names and types for the
733
output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
737
void Log_event::init_show_field_list(List<Item>* field_list)
739
field_list->push_back(new Item_empty_string("Log_name", 20));
740
field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
741
DRIZZLE_TYPE_LONGLONG));
742
field_list->push_back(new Item_empty_string("Event_type", 20));
743
field_list->push_back(new Item_return_int("Server_id", 10,
745
field_list->push_back(new Item_return_int("End_log_pos",
746
MY_INT32_NUM_DECIMAL_DIGITS,
747
DRIZZLE_TYPE_LONGLONG));
748
field_list->push_back(new Item_empty_string("Info", 20));
755
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
757
uchar header[LOG_EVENT_HEADER_LEN];
760
/* Store number of bytes that will be written by this event */
761
data_written= event_data_length + sizeof(header);
764
log_pos != 0 if this is relay-log event. In this case we should not
768
if (is_artificial_event())
771
We should not do any cleanup on slave when reading this. We
772
mark this by setting log_pos to 0. Start_log_event_v3() will
773
detect this on reading and set artificial_event=1 for the event.
780
Calculate position of end of event
782
Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
783
work well. So this will give slightly wrong positions for the
784
Format_desc/Rotate/Stop events which the slave writes to its
785
relay log. For example, the initial Format_desc will have
786
end_log_pos=91 instead of 95. Because after writing the first 4
787
bytes of the relay log, my_b_tell() still reports 0. Because
788
my_b_append() does not update the counter which my_b_tell()
789
later uses (one should probably use my_b_append_tell() to work
790
around this). To get right positions even when writing to the
791
relay log, we use the (new) my_b_safe_tell().
793
Note that this raises a question on the correctness of all these
794
assert(my_b_tell()=rli->event_relay_log_pos).
796
If in a transaction, the log_pos which we calculate below is not
797
very good (because then my_b_safe_tell() returns start position
798
of the BEGIN, so it's like the statement was at the BEGIN's
799
place), but it's not a very serious problem (as the slave, when
800
it is in a transaction, does not take those end_log_pos into
801
account (as it calls inc_event_relay_log_pos()). To be fixed
802
later, so that it looks less strange. But not bug.
805
log_pos= my_b_safe_tell(file)+data_written;
808
now= (ulong) get_time(); // Query start time
811
Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
812
FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
813
LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
814
because we read them before knowing the format).
817
int4store(header, now); // timestamp
818
header[EVENT_TYPE_OFFSET]= get_type_code();
819
int4store(header+ SERVER_ID_OFFSET, server_id);
820
int4store(header+ EVENT_LEN_OFFSET, data_written);
821
int4store(header+ LOG_POS_OFFSET, log_pos);
822
int2store(header+ FLAGS_OFFSET, flags);
824
return(my_b_safe_write(file, header, sizeof(header)) != 0);
829
This needn't be format-tolerant, because we only read
830
LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
833
int Log_event::read_log_event(IO_CACHE* file, String* packet,
834
pthread_mutex_t* log_lock)
838
char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
841
pthread_mutex_lock(log_lock);
842
if (my_b_read(file, (uchar*) buf, sizeof(buf)))
845
If the read hits eof, we must report it as eof so the caller
846
will know it can go into cond_wait to be woken up on the next
850
result= LOG_READ_EOF;
852
result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
855
data_len= uint4korr(buf + EVENT_LEN_OFFSET);
856
if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
857
data_len > current_thd->variables.max_allowed_packet)
859
result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
864
/* Append the log event header to packet */
865
if (packet->append(buf, sizeof(buf)))
867
/* Failed to allocate packet */
868
result= LOG_READ_MEM;
871
data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
874
/* Append rest of event, read directly from file into packet */
875
if (packet->append(file, data_len))
878
Fatal error occured when appending rest of the event
879
to packet, possible failures:
880
1. EOF occured when reading from file, it's really an error
881
as data_len is >=0 there's supposed to be more bytes available.
882
file->error will have been set to number of bytes left to read
883
2. Read was interrupted, file->error would normally be set to -1
884
3. Failed to allocate memory for packet, my_errno
885
will be ENOMEM(file->error shuold be 0, but since the
886
memory allocation occurs before the call to read it might
889
result= (my_errno == ENOMEM ? LOG_READ_MEM :
890
(file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
891
/* Implicit goto end; */
897
pthread_mutex_unlock(log_lock);
900
#endif /* !DRIZZLE_CLIENT */
902
#ifndef DRIZZLE_CLIENT
903
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
904
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
910
#ifndef DRIZZLE_CLIENT
913
Allocates memory; The caller is responsible for clean-up.
915
Log_event* Log_event::read_log_event(IO_CACHE* file,
916
pthread_mutex_t* log_lock,
917
const Format_description_log_event
920
Log_event* Log_event::read_log_event(IO_CACHE* file,
921
const Format_description_log_event
925
assert(description_event != 0);
926
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
928
First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
929
check the event for sanity and to know its length; no need to really parse
930
it. We say "at most" because this could be a 3.23 master, which has header
931
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
932
"minimal" over the set {MySQL >=4.0}).
934
uint header_size= min(description_event->common_header_len,
935
LOG_EVENT_MINIMAL_HEADER_LEN);
938
if (my_b_read(file, (uchar *) head, header_size))
942
No error here; it could be that we are at the file's end. However
943
if the next my_b_read() fails (below), it will be an error as we
944
were able to read the first bytes.
948
uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
950
const char *error= 0;
952
#ifndef max_allowed_packet
953
THD *thd=current_thd;
954
uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
957
if (data_len > max_allowed_packet)
959
error = "Event too big";
963
if (data_len < header_size)
965
error = "Event too small";
969
// some events use the extra byte to null-terminate strings
970
if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
972
error = "Out of memory";
976
memcpy(buf, head, header_size);
977
if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
979
error = "read error";
982
if ((res= read_log_event(buf, data_len, &error, description_event)))
983
res->register_temp_buf(buf);
990
sql_print_error(_("Error in Log_event::read_log_event(): "
991
"'%s', data_len: %d, event_type: %d"),
992
error,data_len,head[EVENT_TYPE_OFFSET]);
993
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
995
The SQL slave thread will check if file->error<0 to know
996
if there was an I/O error. Even if there is no "low-level" I/O errors
997
with 'file', any of the high-level above errors is worrying
998
enough to stop the SQL thread now ; as we are skipping the current event,
999
going on with reading and successfully executing other events can
1000
only corrupt the slave's databases. So stop.
1009
Binlog format tolerance is in (buf, event_len, description_event)
1013
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1015
const Format_description_log_event *description_event)
1018
assert(description_event != 0);
1020
/* Check the integrity */
1021
if (event_len < EVENT_LEN_OFFSET ||
1022
buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
1023
(uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1025
*error="Sanity check failed"; // Needed to free buffer
1026
return(NULL); // general sanity check - will fail on a partial read
1029
uint event_type= buf[EVENT_TYPE_OFFSET];
1030
if (event_type > description_event->number_of_event_types &&
1031
event_type != FORMAT_DESCRIPTION_EVENT)
1034
It is unsafe to use the description_event if its post_header_len
1035
array does not include the event type.
1042
In some previuos versions (see comment in
1043
Format_description_log_event::Format_description_log_event(char*,...)),
1044
event types were assigned different id numbers than in the
1045
present version. In order to replicate from such versions to the
1046
present version, we must map those event type id's to our event
1047
type id's. The mapping is done with the event_type_permutation
1048
array, which was set up when the Format_description_log_event
1051
if (description_event->event_type_permutation)
1052
event_type= description_event->event_type_permutation[event_type];
1054
switch(event_type) {
1056
ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1059
ev = new Load_log_event(buf, event_len, description_event);
1061
case NEW_LOAD_EVENT:
1062
ev = new Load_log_event(buf, event_len, description_event);
1065
ev = new Rotate_log_event(buf, event_len, description_event);
1067
case SLAVE_EVENT: /* can never happen (unused event) */
1068
ev = new Slave_log_event(buf, event_len);
1070
case CREATE_FILE_EVENT:
1071
ev = new Create_file_log_event(buf, event_len, description_event);
1073
case APPEND_BLOCK_EVENT:
1074
ev = new Append_block_log_event(buf, event_len, description_event);
1076
case DELETE_FILE_EVENT:
1077
ev = new Delete_file_log_event(buf, event_len, description_event);
1079
case EXEC_LOAD_EVENT:
1080
ev = new Execute_load_log_event(buf, event_len, description_event);
1082
case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1083
ev = new Start_log_event_v3(buf, description_event);
1086
ev = new Stop_log_event(buf, description_event);
1089
ev = new Intvar_log_event(buf, description_event);
1092
ev = new Xid_log_event(buf, description_event);
1095
ev = new Rand_log_event(buf, description_event);
1097
case USER_VAR_EVENT:
1098
ev = new User_var_log_event(buf, description_event);
1100
case FORMAT_DESCRIPTION_EVENT:
1101
ev = new Format_description_log_event(buf, event_len, description_event);
1103
#if defined(HAVE_REPLICATION)
1104
case WRITE_ROWS_EVENT:
1105
ev = new Write_rows_log_event(buf, event_len, description_event);
1107
case UPDATE_ROWS_EVENT:
1108
ev = new Update_rows_log_event(buf, event_len, description_event);
1110
case DELETE_ROWS_EVENT:
1111
ev = new Delete_rows_log_event(buf, event_len, description_event);
1113
case TABLE_MAP_EVENT:
1114
ev = new Table_map_log_event(buf, event_len, description_event);
1117
case BEGIN_LOAD_QUERY_EVENT:
1118
ev = new Begin_load_query_log_event(buf, event_len, description_event);
1120
case EXECUTE_LOAD_QUERY_EVENT:
1121
ev= new Execute_load_query_log_event(buf, event_len, description_event);
1123
case INCIDENT_EVENT:
1124
ev = new Incident_log_event(buf, event_len, description_event);
1133
is_valid() are small event-specific sanity tests which are
1134
important; for example there are some my_malloc() in constructors
1135
(e.g. Query_log_event::Query_log_event(char*...)); when these
1136
my_malloc() fail we can't return an error out of the constructor
1137
(because constructor is "void") ; so instead we leave the pointer we
1138
wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1139
Same for Format_description_log_event, member 'post_header_len'.
1141
if (!ev || !ev->is_valid())
1144
#ifdef DRIZZLE_CLIENT
1145
if (!force_opt) /* then mysqlbinlog dies */
1147
*error= "Found invalid event in binary log";
1150
ev= new Unknown_log_event(buf, description_event);
1152
*error= "Found invalid event in binary log";
1159
#ifdef DRIZZLE_CLIENT
1162
Log_event::print_header()
1165
void Log_event::print_header(IO_CACHE* file,
1166
PRINT_EVENT_INFO* print_event_info,
1167
bool is_more __attribute__((unused)))
1170
my_off_t hexdump_from= print_event_info->hexdump_from;
1172
my_b_printf(file, "#");
1173
print_timestamp(file);
1174
my_b_printf(file, " server id %d end_log_pos %s ", server_id,
1175
llstr(log_pos,llbuff));
1177
/* mysqlbinlog --hexdump */
1178
if (print_event_info->hexdump_from)
1180
my_b_printf(file, "\n");
1181
uchar *ptr= (uchar*)temp_buf;
1183
uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1186
/* Header len * 4 >= header len * (2 chars + space + extra space) */
1187
char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
1188
char *c, char_string[16+1]= {0};
1190
/* Pretty-print event common header if header is exactly 19 bytes */
1191
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1193
char emit_buf[256]; // Enough for storing one line
1194
my_b_printf(file, "# Position Timestamp Type Master ID "
1195
"Size Master Pos Flags \n");
1196
int const bytes_written=
1197
snprintf(emit_buf, sizeof(emit_buf),
1198
"# %8.8lx %02x %02x %02x %02x %02x "
1199
"%02x %02x %02x %02x %02x %02x %02x %02x "
1200
"%02x %02x %02x %02x %02x %02x\n",
1201
(unsigned long) hexdump_from,
1202
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1203
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1204
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1205
assert(bytes_written >= 0);
1206
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1207
my_b_write(file, (uchar*) emit_buf, bytes_written);
1208
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1209
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1212
/* Rest of event (without common header) */
1213
for (i= 0, c= char_string, h=hex_string;
1217
snprintf(h, 4, "%02x ", *ptr);
1220
*c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1225
my_b_printf() does not support full printf() formats, so we
1226
have to do it this way.
1228
TODO: Rewrite my_b_printf() to support full printf() syntax.
1231
int const bytes_written=
1232
snprintf(emit_buf, sizeof(emit_buf),
1233
"# %8.8lx %-48.48s |%16s|\n",
1234
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1235
hex_string, char_string);
1236
assert(bytes_written >= 0);
1237
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1238
my_b_write(file, (uchar*) emit_buf, bytes_written);
1244
else if (i % 8 == 7) *h++ = ' ';
1251
int const bytes_written=
1252
snprintf(emit_buf, sizeof(emit_buf),
1253
"# %8.8lx %-48.48s |%s|\n",
1254
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
1255
hex_string, char_string);
1256
assert(bytes_written >= 0);
1257
assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1258
my_b_write(file, (uchar*) emit_buf, bytes_written);
1261
need a # to prefix the rest of printouts for example those of
1262
Rows_log_event::print_helper().
1264
my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1270
void Log_event::print_base64(IO_CACHE* file,
1271
PRINT_EVENT_INFO* print_event_info,
1274
const uchar *ptr= (const uchar *)temp_buf;
1275
uint32_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
1277
size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
1278
char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
1280
fprintf(stderr, "\nError: Out of memory. "
1281
"Could not print correct binlog event.\n");
1285
if (base64_encode(ptr, (size_t) size, tmp_str))
1290
if (my_b_tell(file) == 0)
1291
my_b_printf(file, "\nBINLOG '\n");
1293
my_b_printf(file, "%s\n", tmp_str);
1296
my_b_printf(file, "'%s\n", print_event_info->delimiter);
1298
my_free(tmp_str, MYF(0));
1304
Log_event::print_timestamp()
1307
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
1312
#ifdef DRIZZLE_SERVER // This is always false
1314
localtime_r(ts,(res= &tm_tmp));
1319
my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
1329
#endif /* DRIZZLE_CLIENT */
1332
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
1333
inline Log_event::enum_skip_reason
1334
Log_event::continue_group(Relay_log_info *rli)
1336
if (rli->slave_skip_counter == 1)
1337
return Log_event::EVENT_SKIP_IGNORE;
1338
return Log_event::do_shall_skip(rli);
1342
/**************************************************************************
1343
Query_log_event methods
1344
**************************************************************************/
1346
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
1349
This (which is used only for SHOW BINLOG EVENTS) could be updated to
1350
print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1351
only an information, it does not produce suitable queries to replay (for
1352
example it does not print LOAD DATA INFILE).
1357
void Query_log_event::pack_info(Protocol *protocol)
1359
// TODO: show the catalog ??
1361
if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
1364
if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1367
pos= stpcpy(buf, "use `");
1368
memcpy(pos, db, db_len);
1369
pos= stpcpy(pos+db_len, "`; ");
1373
memcpy(pos, query, q_len);
1376
protocol->store(buf, pos-buf, &my_charset_bin);
1377
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1381
#ifndef DRIZZLE_CLIENT
1384
Utility function for the next method (Query_log_event::write()) .
1386
static void write_str_with_code_and_len(char **dst, const char *src,
1391
*((*dst)++)= (uchar) len;
1392
memcpy(*dst, src, len);
1398
Query_log_event::write().
1401
In this event we have to modify the header to have the correct
1402
EVENT_LEN_OFFSET as we don't yet know how many status variables we
1406
bool Query_log_event::write(IO_CACHE* file)
1409
@todo if catalog can be of length FN_REFLEN==512, then we are not
1410
replicating it correctly, since the length is stored in a byte
1413
uchar buf[QUERY_HEADER_LEN+
1414
1+4+ // code of flags2 and flags2
1415
1+8+ // code of sql_mode and sql_mode
1416
1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1417
1+4+ // code of autoinc and the 2 autoinc variables
1418
1+6+ // code of charset and charset
1419
1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
1420
1+2+ // code of lc_time_names and lc_time_names_number
1421
1+2 // code of charset_database and charset_database_number
1422
], *start, *start_of_status;
1426
return 1; // Something wrong with event
1429
We want to store the thread id:
1430
(- as an information for the user when he reads the binlog)
1431
- if the query uses temporary table: for the slave SQL thread to know to
1432
which master connection the temp table belongs.
1433
Now imagine we (write()) are called by the slave SQL thread (we are
1434
logging a query executed by this thread; the slave runs with
1435
--log-slave-updates). Then this query will be logged with
1436
thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
1437
the same name were created simultaneously on the master (in the master
1439
CREATE TEMPORARY TABLE t; (thread 1)
1440
CREATE TEMPORARY TABLE t; (thread 2)
1442
then in the slave's binlog there will be
1443
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
1444
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
1445
which is bad (same thread id!).
1447
To avoid this, we log the thread's thread id EXCEPT for the SQL
1448
slave thread for which we log the original (master's) thread id.
1449
Now this moves the bug: what happens if the thread id on the
1450
master was 10 and when the slave replicates the query, a
1451
connection number 10 is opened by a normal client on the slave,
1452
and updates a temp table of the same name? We get a problem
1453
again. To avoid this, in the handling of temp tables (sql_base.cc)
1454
we use thread_id AND server_id. TODO when this is merged into
1455
4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
1456
and is a session variable: that's to make mysqlbinlog work with
1457
temp tables. We probably need to introduce
1459
SET PSEUDO_SERVER_ID
1460
for mysqlbinlog in 4.1. mysqlbinlog would print:
1461
SET PSEUDO_SERVER_ID=
1462
SET PSEUDO_THREAD_ID=
1463
for each query using temp tables.
1465
int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
1466
int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
1467
buf[Q_DB_LEN_OFFSET] = (char) db_len;
1468
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
1471
You MUST always write status vars in increasing order of code. This
1472
guarantees that a slightly older slave will be able to parse those he
1475
start_of_status= start= buf+QUERY_HEADER_LEN;
1478
*start++= Q_FLAGS2_CODE;
1479
int4store(start, flags2);
1482
if (sql_mode_inited)
1484
*start++= Q_SQL_MODE_CODE;
1485
int8store(start, (uint64_t)sql_mode);
1488
if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1490
write_str_with_code_and_len((char **)(&start),
1491
catalog, catalog_len, Q_CATALOG_NZ_CODE);
1493
In 5.0.x where x<4 masters we used to store the end zero here. This was
1494
a waste of one byte so we don't do it in x>=4 masters. We change code to
1495
Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
1496
of this x>=4 master segfault (expecting a zero when there is
1497
none). Remaining compatibility problems are: the older slave will not
1498
find the catalog; but it is will not crash, and it's not an issue
1499
that it does not find the catalog as catalogs were not used in these
1500
older MySQL versions (we store it in binlog and read it from relay log
1501
but do nothing useful with it). What is an issue is that the older slave
1502
will stop processing the Q_* blocks (and jumps to the db/query) as soon
1503
as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
1504
Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
1505
various ways. Documented that you should not mix alpha/beta versions if
1506
they are not exactly the same version, with example of 5.0.3->5.0.2 and
1507
5.0.4->5.0.3. If replication is from older to new, the new will
1508
recognize Q_CATALOG_CODE and have no problem.
1511
if (auto_increment_increment != 1 || auto_increment_offset != 1)
1513
*start++= Q_AUTO_INCREMENT;
1514
int2store(start, auto_increment_increment);
1515
int2store(start+2, auto_increment_offset);
1520
*start++= Q_CHARSET_CODE;
1521
memcpy(start, charset, 6);
1526
/* In the TZ sys table, column Name is of length 64 so this should be ok */
1527
assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1528
*start++= Q_TIME_ZONE_CODE;
1529
*start++= time_zone_len;
1530
memcpy(start, time_zone_str, time_zone_len);
1531
start+= time_zone_len;
1533
if (lc_time_names_number)
1535
assert(lc_time_names_number <= 0xFFFF);
1536
*start++= Q_LC_TIME_NAMES_CODE;
1537
int2store(start, lc_time_names_number);
1540
if (charset_database_number)
1542
assert(charset_database_number <= 0xFFFF);
1543
*start++= Q_CHARSET_DATABASE_CODE;
1544
int2store(start, charset_database_number);
1548
Here there could be code like
1549
if (command-line-option-which-says-"log_this_variable" && inited)
1551
*start++= Q_THIS_VARIABLE_CODE;
1552
int4store(start, this_variable);
1557
/* Store length of status variables */
1558
status_vars_len= (uint) (start-start_of_status);
1559
assert(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
1560
int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
1563
Calculate length of whole event
1564
The "1" below is the \0 in the db's length
1566
event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1568
return (write_header(file, event_length) ||
1569
my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1570
write_post_header_for_derived(file) ||
1571
my_b_safe_write(file, (uchar*) start_of_status,
1572
(uint) (start-start_of_status)) ||
1573
my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
1574
my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1578
The simplest constructor that could possibly work. This is used for
1579
creating static objects that have a special meaning and are invisible
1582
Query_log_event::Query_log_event()
1583
:Log_event(), data_buf(0)
1590
Query_log_event::Query_log_event()
1591
thd_arg - thread handle
1592
query_arg - array of char representing the query
1593
query_length - size of the `query_arg' array
1594
using_trans - there is a modified transactional table
1595
suppress_use - suppress the generation of 'USE' statements
1596
killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
1597
if the value is different from the default, the arg
1598
is set to the current thd->killed value.
1599
A caller might need to masquerade thd->killed with
1602
Creates an event for binlogging
1603
The value for local `killed_status' can be supplied by caller.
1605
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
1606
ulong query_length, bool using_trans,
1608
THD::killed_state killed_status_arg)
1610
(thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1612
(suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1614
data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1615
db(thd_arg->db), q_len((uint32_t) query_length),
1616
thread_id(thd_arg->thread_id),
1617
/* save the original thread id; we already know the server id */
1618
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1619
flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1621
auto_increment_increment(thd_arg->variables.auto_increment_increment),
1622
auto_increment_offset(thd_arg->variables.auto_increment_offset),
1623
lc_time_names_number(thd_arg->variables.lc_time_names->number),
1624
charset_database_number(0)
1628
if (killed_status_arg == THD::KILLED_NO_VALUE)
1629
killed_status_arg= thd_arg->killed;
1632
(killed_status_arg == THD::NOT_KILLED) ?
1633
(thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1634
(thd_arg->killed_errno());
1637
exec_time = (ulong) (end_time - thd_arg->start_time);
1639
@todo this means that if we have no catalog, then it is replicated
1640
as an existing catalog of length zero. is that safe? /sven
1642
catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
1643
/* status_vars_len is set just before writing the event */
1644
db_len = (db) ? (uint32_t) strlen(db) : 0;
1645
if (thd_arg->variables.collation_database != thd_arg->db_charset)
1646
charset_database_number= thd_arg->variables.collation_database->number;
1649
If we don't use flags2 for anything else than options contained in
1650
thd_arg->options, it would be more efficient to flags2=thd_arg->options
1651
(OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1652
But it's likely that we don't want to use 32 bits for 3 bits; in the future
1653
we will probably want to reclaim the 29 bits. So we need the &.
1655
flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1656
assert(thd_arg->variables.character_set_client->number < 256*256);
1657
assert(thd_arg->variables.collation_connection->number < 256*256);
1658
assert(thd_arg->variables.collation_server->number < 256*256);
1659
assert(thd_arg->variables.character_set_client->mbminlen == 1);
1660
int2store(charset, thd_arg->variables.character_set_client->number);
1661
int2store(charset+2, thd_arg->variables.collation_connection->number);
1662
int2store(charset+4, thd_arg->variables.collation_server->number);
1663
if (thd_arg->time_zone_used)
1666
Note that our event becomes dependent on the Time_zone object
1667
representing the time zone. Fortunately such objects are never deleted
1668
or changed during mysqld's lifetime.
1670
time_zone_len= thd_arg->variables.time_zone->get_name()->length();
1671
time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
1676
#endif /* DRIZZLE_CLIENT */
1679
/* 2 utility functions for the next method */
1682
Read a string with length from memory.
1684
This function reads the string-with-length stored at
1685
<code>src</code> and extract the length into <code>*len</code> and
1686
a pointer to the start of the string into <code>*dst</code>. The
1687
string can then be copied using <code>memcpy()</code> with the
1688
number of bytes given in <code>*len</code>.
1690
@param src Pointer to variable holding a pointer to the memory to
1691
read the string from.
1692
@param dst Pointer to variable holding a pointer where the actual
1693
string starts. Starting from this position, the string
1694
can be copied using @c memcpy().
1695
@param len Pointer to variable where the length will be stored.
1696
@param end One-past-the-end of the memory where the string is
1699
@return Zero if the entire string can be copied successfully,
1700
@c UINT_MAX if the length could not be read from memory
1701
(that is, if <code>*src >= end</code>), otherwise the
1702
number of bytes that are missing to read the full
1703
string, which happends <code>*dst + *len >= end</code>.
1706
get_str_len_and_pointer(const Log_event::Byte **src,
1709
const Log_event::Byte *end)
1712
return -1; // Will be UINT_MAX in two-complement arithmetics
1716
if (*src + length >= end)
1717
return *src + length - end + 1; // Number of bytes missing
1718
*dst= (char *)*src + 1; // Will be copied later
1725
static void copy_str_and_move(const char **src,
1726
Log_event::Byte **dst,
1729
memcpy(*dst, *src, len);
1730
*src= (const char *)*dst;
1737
Macro to check that there is enough space to read from memory.
1739
@param PTR Pointer to memory
1740
@param END End of memory
1741
@param CNT Number of bytes that should be read.
1743
#define CHECK_SPACE(PTR,END,CNT) \
1745
assert((PTR) + (CNT) <= (END)); \
1746
if ((PTR) + (CNT) > (END)) { \
1754
This is used by the SQL slave thread to prepare the event before execution.
1756
Query_log_event::Query_log_event(const char* buf, uint event_len,
1757
const Format_description_log_event
1759
Log_event_type event_type)
1760
:Log_event(buf, description_event), data_buf(0), query(NullS),
1761
db(NullS), catalog_len(0), status_vars_len(0),
1762
flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1763
auto_increment_increment(1), auto_increment_offset(1),
1764
time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1768
uint8_t common_header_len, post_header_len;
1769
Log_event::Byte *start;
1770
const Log_event::Byte *end;
1773
common_header_len= description_event->common_header_len;
1774
post_header_len= description_event->post_header_len[event_type-1];
1777
We test if the event's length is sensible, and if so we compute data_len.
1778
We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
1779
We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
1781
if (event_len < (uint)(common_header_len + post_header_len))
1783
data_len = event_len - (common_header_len + post_header_len);
1784
buf+= common_header_len;
1786
slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
1787
exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
1788
db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
1789
error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
1792
5.0 format starts here.
1793
Depending on the format, we may or not have affected/warnings etc
1794
The remnent post-header to be parsed has length:
1796
tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
1799
status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
1801
Check if status variable length is corrupt and will lead to very
1802
wrong data. We could be even more strict and require data_len to
1803
be even bigger, but this will suffice to catch most corruption
1804
errors that can lead to a crash.
1806
if (status_vars_len > min(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
1811
data_len-= status_vars_len;
1815
We have parsed everything we know in the post header for QUERY_EVENT,
1816
the rest of post header is either comes from older version MySQL or
1817
dedicated to derived events (e.g. Execute_load_query...)
1820
/* variable-part: the status vars; only in MySQL 5.0 */
1822
start= (Log_event::Byte*) (buf+post_header_len);
1823
end= (const Log_event::Byte*) (start+status_vars_len);
1824
for (const Log_event::Byte* pos= start; pos < end;)
1828
CHECK_SPACE(pos, end, 4);
1830
flags2= uint4korr(pos);
1833
case Q_SQL_MODE_CODE:
1835
CHECK_SPACE(pos, end, 8);
1837
sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is uint64_t
1841
case Q_CATALOG_NZ_CODE:
1842
if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
1848
case Q_AUTO_INCREMENT:
1849
CHECK_SPACE(pos, end, 4);
1850
auto_increment_increment= uint2korr(pos);
1851
auto_increment_offset= uint2korr(pos+2);
1854
case Q_CHARSET_CODE:
1856
CHECK_SPACE(pos, end, 6);
1858
memcpy(charset, pos, 6);
1862
case Q_TIME_ZONE_CODE:
1864
if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1871
case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
1872
CHECK_SPACE(pos, end, 1);
1873
if ((catalog_len= *pos))
1874
catalog= (char*) pos+1; // Will be copied later
1875
CHECK_SPACE(pos, end, catalog_len + 2);
1876
pos+= catalog_len+2; // leap over end 0
1877
catalog_nz= 0; // catalog has end 0 in event
1879
case Q_LC_TIME_NAMES_CODE:
1880
CHECK_SPACE(pos, end, 2);
1881
lc_time_names_number= uint2korr(pos);
1884
case Q_CHARSET_DATABASE_CODE:
1885
CHECK_SPACE(pos, end, 2);
1886
charset_database_number= uint2korr(pos);
1890
/* That's why you must write status vars in growing order of code */
1891
pos= (const uchar*) end; // Break loop
1895
if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
1900
if (catalog_len) // If catalog is given
1903
@todo we should clean up and do only copy_str_and_move; it
1904
works for both cases. Then we can remove the catalog_nz
1907
if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
1908
copy_str_and_move(&catalog, &start, catalog_len);
1911
memcpy(start, catalog, catalog_len+1); // copy end 0
1912
catalog= (const char *)start;
1913
start+= catalog_len+1;
1917
copy_str_and_move(&time_zone_str, &start, time_zone_len);
1920
if time_zone_len or catalog_len are 0, then time_zone and catalog
1921
are uninitialized at this point. shouldn't they point to the
1922
zero-length null-terminated strings we allocated space for in the
1923
my_alloc call above? /sven
1926
/* A 2nd variable part; this is common to all versions */
1927
memcpy(start, end, data_len); // Copy db and query
1928
start[data_len]= '\0'; // End query with \0 (For safetly)
1930
query= (char *)(start + db_len + 1);
1931
q_len= data_len - db_len -1;
1936
#ifdef DRIZZLE_CLIENT
1938
Query_log_event::print().
1941
print the catalog ??
1943
void Query_log_event::print_query_header(IO_CACHE* file,
1944
PRINT_EVENT_INFO* print_event_info)
1946
// TODO: print the catalog ??
1947
char buff[40],*end; // Enough for SET TIMESTAMP
1948
bool different_db= 1;
1951
if (!print_event_info->short_form)
1953
print_header(file, print_event_info, false);
1954
my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
1955
get_type_str(), (ulong) thread_id, (ulong) exec_time,
1959
if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
1961
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
1962
memcpy(print_event_info->db, db, db_len + 1);
1963
if (db[0] && different_db)
1964
my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
1967
end=int10_to_str((long) when, stpcpy(buff,"SET TIMESTAMP="),10);
1968
end= stpcpy(end, print_event_info->delimiter);
1970
my_b_write(file, (uchar*) buff, (uint) (end-buff));
1971
if ((!print_event_info->thread_id_printed ||
1972
((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
1973
thread_id != print_event_info->thread_id)))
1975
// If --short-form, print deterministic value instead of pseudo_thread_id.
1976
my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
1977
short_form ? 999999999 : (ulong)thread_id,
1978
print_event_info->delimiter);
1979
print_event_info->thread_id= thread_id;
1980
print_event_info->thread_id_printed= 1;
1984
If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
1985
print (remember we don't produce mixed relay logs so there cannot be
1986
5.0 events before that one so there is nothing to reset).
1988
if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
1990
/* tmp is a bitmask of bits which have changed. */
1991
if (likely(print_event_info->flags2_inited))
1992
/* All bits which have changed */
1993
tmp= (print_event_info->flags2) ^ flags2;
1994
else /* that's the first Query event we read */
1996
print_event_info->flags2_inited= 1;
1997
tmp= ~((uint32_t)0); /* all bits have changed */
2000
if (unlikely(tmp)) /* some bits have changed */
2003
my_b_printf(file, "SET ");
2004
print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
2005
"@@session.foreign_key_checks", &need_comma);
2006
print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
2007
"@@session.sql_auto_is_null", &need_comma);
2008
print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
2009
"@@session.unique_checks", &need_comma);
2010
my_b_printf(file,"%s\n", print_event_info->delimiter);
2011
print_event_info->flags2= flags2;
2016
Now the session variables;
2017
it's more efficient to pass SQL_MODE as a number instead of a
2018
comma-separated list.
2019
FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
2020
variables (they have no global version; they're not listed in
2021
sql_class.h), The tests below work for pure binlogs or pure relay
2022
logs. Won't work for mixed relay logs but we don't create mixed
2023
relay logs (that is, there is no relay log with a format change
2024
except within the 3 first events, which mysqlbinlog handles
2025
gracefully). So this code should always be good.
2028
if (print_event_info->auto_increment_increment != auto_increment_increment ||
2029
print_event_info->auto_increment_offset != auto_increment_offset)
2031
my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
2032
auto_increment_increment,auto_increment_offset,
2033
print_event_info->delimiter);
2034
print_event_info->auto_increment_increment= auto_increment_increment;
2035
print_event_info->auto_increment_offset= auto_increment_offset;
2038
/* TODO: print the catalog when we feature SET CATALOG */
2040
if (likely(charset_inited) &&
2041
(unlikely(!print_event_info->charset_inited ||
2042
memcmp(print_event_info->charset, charset, 6))))
2044
const CHARSET_INFO * const cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
2047
/* for mysql client */
2048
my_b_printf(file, "/*!\\C %s */%s\n",
2049
cs_info->csname, print_event_info->delimiter);
2051
my_b_printf(file,"SET "
2052
"@@session.character_set_client=%d,"
2053
"@@session.collation_connection=%d,"
2054
"@@session.collation_server=%d"
2057
uint2korr(charset+2),
2058
uint2korr(charset+4),
2059
print_event_info->delimiter);
2060
memcpy(print_event_info->charset, charset, 6);
2061
print_event_info->charset_inited= 1;
2065
if (memcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
2067
my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
2068
time_zone_str, print_event_info->delimiter);
2069
memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
2072
if (lc_time_names_number != print_event_info->lc_time_names_number)
2074
my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
2075
lc_time_names_number, print_event_info->delimiter);
2076
print_event_info->lc_time_names_number= lc_time_names_number;
2078
if (charset_database_number != print_event_info->charset_database_number)
2080
if (charset_database_number)
2081
my_b_printf(file, "SET @@session.collation_database=%d%s\n",
2082
charset_database_number, print_event_info->delimiter);
2084
my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
2085
print_event_info->delimiter);
2086
print_event_info->charset_database_number= charset_database_number;
2091
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2093
Write_on_release_cache cache(&print_event_info->head_cache, file);
2095
print_query_header(&cache, print_event_info);
2096
my_b_write(&cache, (uchar*) query, q_len);
2097
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
2099
#endif /* DRIZZLE_CLIENT */
2103
Query_log_event::do_apply_event()
2106
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2108
int Query_log_event::do_apply_event(Relay_log_info const *rli)
2110
return do_apply_event(rli, query, q_len);
2116
Compare the values of "affected rows" around here. Something
2119
if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
2121
sql_print_error("Slave: did not get the expected number of affected \
2122
rows running query from master - expected %d, got %d (this numbers \
2123
should have matched modulo 4294967296).", 0, ...);
2124
thd->query_error = 1;
2127
We may also want an option to tell the slave to ignore "affected"
2128
mismatch. This mismatch could be implemented with a new ER_ code, and
2129
to ignore it you would use --slave-skip-errors...
2131
int Query_log_event::do_apply_event(Relay_log_info const *rli,
2132
const char *query_arg, uint32_t q_len_arg)
2135
int expected_error,actual_error= 0;
2137
Colleagues: please never free(thd->catalog) in MySQL. This would
2138
lead to bugs as here thd->catalog is a part of an alloced block,
2139
not an entire alloced block (see
2140
Query_log_event::do_apply_event()). Same for thd->db. Thank
2143
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
2144
new_db.length= db_len;
2145
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2146
thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
2147
thd->variables.auto_increment_increment= auto_increment_increment;
2148
thd->variables.auto_increment_offset= auto_increment_offset;
2151
InnoDB internally stores the master log position it has executed so far,
2152
i.e. the position just after the COMMIT event.
2153
When InnoDB will want to store, the positions in rli won't have
2154
been updated yet, so group_master_log_* will point to old BEGIN
2155
and event_master_log* will point to the beginning of current COMMIT.
2156
But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
2157
END of the current log event (COMMIT). We save it in rli so that InnoDB can
2160
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
2162
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2163
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
2166
Note: We do not need to execute reset_one_shot_variables() if this
2168
Reason: The db stored in binlog events is the same for SET and for
2169
its companion query. If the SET is ignored because of
2170
db_ok(), the companion query will also be ignored, and if
2171
the companion query is ignored in the db_ok() test of
2172
::do_apply_event(), then the companion SET also have so
2173
we don't need to reset_one_shot_variables().
2175
if (rpl_filter->db_ok(thd->db))
2177
thd->set_time((time_t)when);
2178
thd->query_length= q_len_arg;
2179
thd->query= (char*)query_arg;
2180
VOID(pthread_mutex_lock(&LOCK_thread_count));
2181
thd->query_id = next_query_id();
2182
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2183
thd->variables.pseudo_thread_id= thread_id; // for temp tables
2185
if (ignored_error_code((expected_error= error_code)) ||
2186
!check_expected_error(thd,rli,expected_error))
2190
all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
2191
must take their value from flags2.
2193
thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2195
else, we are in a 3.23/4.0 binlog; we previously received a
2196
Rotate_log_event which reset thd->options and sql_mode etc, so
2201
if (rli->cached_charset_compare(charset))
2203
/* Verify that we support the charsets found in the event. */
2204
if (!(thd->variables.character_set_client=
2205
get_charset(uint2korr(charset), MYF(MY_WME))) ||
2206
!(thd->variables.collation_connection=
2207
get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
2208
!(thd->variables.collation_server=
2209
get_charset(uint2korr(charset+4), MYF(MY_WME))))
2212
We updated the thd->variables with nonsensical values (0). Let's
2213
set them to something safe (i.e. which avoids crash), and we'll
2214
stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
2217
set_slave_thread_default_charset(thd, rli);
2218
goto compare_errors;
2220
thd->update_charset(); // for the charset change to take effect
2225
String tmp(time_zone_str, time_zone_len, &my_charset_bin);
2226
if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
2228
my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
2229
thd->variables.time_zone= global_system_variables.time_zone;
2230
goto compare_errors;
2233
if (lc_time_names_number)
2235
if (!(thd->variables.lc_time_names=
2236
my_locale_by_number(lc_time_names_number)))
2238
my_printf_error(ER_UNKNOWN_ERROR,
2239
"Unknown locale: '%d'", MYF(0), lc_time_names_number);
2240
thd->variables.lc_time_names= &my_locale_en_US;
2241
goto compare_errors;
2245
thd->variables.lc_time_names= &my_locale_en_US;
2246
if (charset_database_number)
2248
const CHARSET_INFO *cs;
2249
if (!(cs= get_charset(charset_database_number, MYF(0))))
2252
int10_to_str((int) charset_database_number, buf, -10);
2253
my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
2254
goto compare_errors;
2256
thd->variables.collation_database= cs;
2259
thd->variables.collation_database= thd->db_charset;
2261
/* Execute the query (note that we bypass dispatch_command()) */
2262
const char* found_semicolon= NULL;
2263
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
2264
log_slow_statement(thd);
2269
The query got a really bad error on the master (thread killed etc),
2270
which could be inconsistent. Parse it to test the table names: if the
2271
replicate-*-do|ignore-table rules say "this query must be ignored" then
2272
we exit gracefully; otherwise we warn about the bad error and tell DBA
2275
if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
2276
clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
2279
rli->report(ERROR_LEVEL, expected_error,
2281
Query partially completed on the master (error on master: %d) \
2282
and was aborted. There is a chance that your master is inconsistent at this \
2283
point. If you are sure that your master is ok, run this query manually on the \
2284
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
2285
START SLAVE; . Query: '%s'", expected_error, thd->query);
2286
thd->is_slave_error= 1;
2291
/* If the query was not ignored, it is printed to the general log */
2292
if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
2293
general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
2298
If we expected a non-zero error code, and we don't get the same error
2299
code, and none of them should be ignored.
2301
actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
2302
if ((expected_error != actual_error) &&
2304
!ignored_error_code(actual_error) &&
2305
!ignored_error_code(expected_error))
2307
rli->report(ERROR_LEVEL, 0,
2309
Query caused different errors on master and slave. \
2310
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
2311
Default database: '%s'. Query: '%s'",
2312
ER_SAFE(expected_error),
2314
actual_error ? thd->main_da.message() : "no error",
2316
print_slave_db_safe(db), query_arg);
2317
thd->is_slave_error= 1;
2320
If we get the same error code as expected, or they should be ignored.
2322
else if (expected_error == actual_error ||
2323
ignored_error_code(actual_error))
2325
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2326
thd->killed= THD::NOT_KILLED;
2329
Other cases: mostly we expected no error and get one.
2331
else if (thd->is_slave_error || thd->is_fatal_error)
2333
rli->report(ERROR_LEVEL, actual_error,
2334
"Error '%s' on query. Default database: '%s'. Query: '%s'",
2335
(actual_error ? thd->main_da.message() :
2336
"unexpected success or fatal error"),
2337
print_slave_db_safe(thd->db), query_arg);
2338
thd->is_slave_error= 1;
2342
TODO: compare the values of "affected rows" around here. Something
2344
if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
2346
sql_print_error("Slave: did not get the expected number of affected \
2347
rows running query from master - expected %d, got %d (this numbers \
2348
should have matched modulo 4294967296).", 0, ...);
2349
thd->is_slave_error = 1;
2351
We may also want an option to tell the slave to ignore "affected"
2352
mismatch. This mismatch could be implemented with a new ER_ code, and
2353
to ignore it you would use --slave-skip-errors...
2355
To do the comparison we need to know the value of "affected" which the
2356
above mysql_parse() computed. And we need to know the value of
2357
"affected" in the master's binlog. Both will be implemented later. The
2358
important thing is that we now have the format ready to log the values
2359
of "affected" in the binlog. So we can release 5.0.0 before effectively
2360
logging "affected" and effectively comparing it.
2362
} /* End of if (db_ok(... */
2365
VOID(pthread_mutex_lock(&LOCK_thread_count));
2367
Probably we have set thd->query, thd->db, thd->catalog to point to places
2368
in the data_buf of this event. Now the event is going to be deleted
2369
probably, so data_buf will be freed, so the thd->... listed above will be
2370
pointers to freed memory.
2371
So we must set them to 0, so that those bad pointers values are not later
2372
used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
2373
don't suffer from these assignments to 0 as DROP TEMPORARY
2374
Table uses the db.table syntax.
2377
thd->set_db(NULL, 0); /* will free the current database */
2378
thd->query= 0; // just to be sure
2379
thd->query_length= 0;
2380
VOID(pthread_mutex_unlock(&LOCK_thread_count));
2381
close_thread_tables(thd);
2383
As a disk space optimization, future masters will not log an event for
2384
LAST_INSERT_ID() if that function returned 0 (and thus they will be able
2385
to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
2386
variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
2387
resetting below we are ready to support that.
2389
thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
2390
thd->first_successful_insert_id_in_prev_stmt= 0;
2391
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
2392
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2393
return thd->is_slave_error;
2396
int Query_log_event::do_update_pos(Relay_log_info *rli)
2399
Note that we will not increment group* positions if we are just
2400
after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
2401
from its following updating query.
2403
if (thd->one_shot_set)
2405
rli->inc_event_relay_log_pos();
2409
return Log_event::do_update_pos(rli);
2413
Log_event::enum_skip_reason
2414
Query_log_event::do_shall_skip(Relay_log_info *rli)
2416
assert(query && q_len > 0);
2418
if (rli->slave_skip_counter > 0)
2420
if (strcmp("BEGIN", query) == 0)
2422
thd->options|= OPTION_BEGIN;
2423
return(Log_event::continue_group(rli));
2426
if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
2428
thd->options&= ~OPTION_BEGIN;
2429
return(Log_event::EVENT_SKIP_COUNT);
2432
return(Log_event::do_shall_skip(rli));
2438
/**************************************************************************
2439
Start_log_event_v3 methods
2440
**************************************************************************/
2442
#ifndef DRIZZLE_CLIENT
2443
Start_log_event_v3::Start_log_event_v3()
2444
:Log_event(), created(0), binlog_version(BINLOG_VERSION),
2445
artificial_event(0), dont_set_created(0)
2447
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2452
Start_log_event_v3::pack_info()
2455
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2456
void Start_log_event_v3::pack_info(Protocol *protocol)
2458
char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
2459
pos= stpcpy(buf, "Server ver: ");
2460
pos= stpcpy(pos, server_version);
2461
pos= stpcpy(pos, ", Binlog ver: ");
2462
pos= int10_to_str(binlog_version, pos, 10);
2463
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
2469
Start_log_event_v3::print()
2472
#ifdef DRIZZLE_CLIENT
2473
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2475
Write_on_release_cache cache(&print_event_info->head_cache, file,
2476
Write_on_release_cache::FLUSH_F);
2478
if (!print_event_info->short_form)
2480
print_header(&cache, print_event_info, false);
2481
my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
2482
binlog_version, server_version);
2483
print_timestamp(&cache);
2485
my_b_printf(&cache," at startup");
2486
my_b_printf(&cache, "\n");
2487
if (flags & LOG_EVENT_BINLOG_IN_USE_F)
2488
my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
2489
"Most probably mysqld crashed writing it.\n");
2491
if (!artificial_event && created)
2493
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
2495
This is for mysqlbinlog: like in replication, we want to delete the stale
2496
tmp files left by an unclean shutdown of mysqld (temporary tables)
2497
and rollback unfinished transaction.
2498
Probably this can be done with RESET CONNECTION (syntax to be defined).
2500
my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
2502
my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
2506
print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
2507
!print_event_info->short_form)
2509
my_b_printf(&cache, "BINLOG '\n");
2510
print_base64(&cache, print_event_info, false);
2511
print_event_info->printed_fd_event= true;
2515
#endif /* DRIZZLE_CLIENT */
2518
Start_log_event_v3::Start_log_event_v3()
2521
Start_log_event_v3::Start_log_event_v3(const char* buf,
2522
const Format_description_log_event
2524
:Log_event(buf, description_event)
2526
buf+= description_event->common_header_len;
2527
binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
2528
memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
2530
// prevent overrun if log is corrupted on disk
2531
server_version[ST_SERVER_VER_LEN-1]= 0;
2532
created= uint4korr(buf+ST_CREATED_OFFSET);
2533
/* We use log_pos to mark if this was an artificial event or not */
2534
artificial_event= (log_pos == 0);
2535
dont_set_created= 1;
2540
Start_log_event_v3::write()
2543
#ifndef DRIZZLE_CLIENT
2544
bool Start_log_event_v3::write(IO_CACHE* file)
2546
char buff[START_V3_HEADER_LEN];
2547
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2548
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2549
if (!dont_set_created)
2550
created= when= get_time();
2551
int4store(buff + ST_CREATED_OFFSET,created);
2552
return (write_header(file, sizeof(buff)) ||
2553
my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
2558
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2561
Start_log_event_v3::do_apply_event() .
2565
- To handle the case where the master died without having time to write
2566
DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
2567
TODO), we clean up all temporary tables that we got, if we are sure we
2571
- Remove all active user locks.
2572
Guilhem 2003-06: this is true but not urgent: the worst it can cause is
2573
the use of a bit of memory for a user lock which will not be used
2574
anymore. If the user lock is later used, the old one will be released. In
2575
other words, no deadlock problem.
2578
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
2580
switch (binlog_version)
2585
This can either be 4.x (then a Start_log_event_v3 is only at master
2586
startup so we are sure the master has restarted and cleared his temp
2587
tables; the event always has 'created'>0) or 5.0 (then we have to test
2592
close_temporary_tables(thd);
2593
cleanup_load_tmpdir();
2598
Now the older formats; in that case load_tmpdir is cleaned up by the I/O
2602
if (strncmp(rli->relay_log.description_event_for_exec->server_version,
2603
"3.23.57",7) >= 0 && created)
2606
Can distinguish, based on the value of 'created': this event was
2607
generated at master startup.
2609
close_temporary_tables(thd);
2612
Otherwise, can't distinguish a Start_log_event generated at
2613
master startup and one generated by master FLUSH LOGS, so cannot
2614
be sure temp tables have to be dropped. So do nothing.
2618
/* this case is impossible */
2623
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
2625
/***************************************************************************
2626
Format_description_log_event methods
2627
****************************************************************************/
2630
Format_description_log_event 1st ctor.
2632
Ctor. Can be used to create the event to write to the binary log (when the
2633
server starts or when FLUSH LOGS), or to create artificial events to parse
2634
binlogs from MySQL 3.23 or 4.x.
2635
When in a client, only the 2nd use is possible.
2637
@param binlog_version the binlog version for which we want to build
2638
an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
2639
x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
2640
old 4.0 (binlog version 2) is not supported;
2641
it should not be used for replication with
2645
Format_description_log_event::
2646
Format_description_log_event(uint8_t binlog_ver, const char* server_ver)
2647
:Start_log_event_v3(), event_type_permutation(0)
2649
binlog_version= binlog_ver;
2650
switch (binlog_ver) {
2651
case 4: /* MySQL 5.0 */
2652
memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2653
common_header_len= LOG_EVENT_HEADER_LEN;
2654
number_of_event_types= LOG_EVENT_TYPES;
2655
/* we'll catch my_malloc() error in is_valid() */
2656
post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
2659
This long list of assignments is not beautiful, but I see no way to
2660
make it nicer, as the right members are #defines, not array members, so
2661
it's impossible to write a loop.
2663
if (post_header_len)
2665
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
2666
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
2667
post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
2668
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
2669
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
2670
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
2671
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
2672
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
2673
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
2674
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
2675
post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
2676
post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2677
post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2678
post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
2679
post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
2680
post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
2681
post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
2682
post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
2687
case 3: /* 4.0.x x>=2 */
2689
We build an artificial (i.e. not sent by the master) event, which
2690
describes what those old master versions send.
2693
stpcpy(server_version, server_ver ? server_ver : "3.23");
2695
stpcpy(server_version, server_ver ? server_ver : "4.0");
2696
common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2697
LOG_EVENT_MINIMAL_HEADER_LEN;
2699
The first new event in binlog version 4 is Format_desc. So any event type
2700
after that does not exist in older versions. We use the events known by
2701
version 3, even if version 1 had only a subset of them (this is not a
2702
problem: it uses a few bytes for nothing but unifies code; it does not
2703
make the slave detect less corruptions).
2705
number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
2706
post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
2708
if (post_header_len)
2710
post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
2711
post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
2712
post_header_len[STOP_EVENT-1]= 0;
2713
post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
2714
post_header_len[INTVAR_EVENT-1]= 0;
2715
post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
2716
post_header_len[SLAVE_EVENT-1]= 0;
2717
post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
2718
post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
2719
post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
2720
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
2721
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
2722
post_header_len[RAND_EVENT-1]= 0;
2723
post_header_len[USER_VAR_EVENT-1]= 0;
2726
default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
2727
post_header_len= 0; /* will make is_valid() fail */
2730
calc_server_version_split();
2735
The problem with this constructor is that the fixed header may have a
2736
length different from this version, but we don't know this length as we
2737
have not read the Format_description_log_event which says it, yet. This
2738
length is in the post-header of the event, but we don't know where the
2741
So this type of event HAS to:
2742
- either have the header's length at the beginning (in the header, at a
2743
fixed position which will never be changed), not in the post-header. That
2744
would make the header be "shifted" compared to other events.
2745
- or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
2746
versions, so that we know for sure.
2748
I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
2749
it is sent before Format_description_log_event).
2752
Format_description_log_event::
2753
Format_description_log_event(const char* buf,
2756
Format_description_log_event*
2758
:Start_log_event_v3(buf, description_event), event_type_permutation(0)
2760
buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
2761
if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
2762
return; /* sanity check */
2763
number_of_event_types=
2764
event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
2765
/* If alloc fails, we'll detect it in is_valid() */
2766
post_header_len= (uint8_t*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2767
number_of_event_types*
2768
sizeof(*post_header_len), MYF(0));
2769
calc_server_version_split();
2772
In some previous versions, the events were given other event type
2773
id numbers than in the present version. When replicating from such
2774
a version, we therefore set up an array that maps those id numbers
2775
to the id numbers of the present server.
2777
If post_header_len is null, it means malloc failed, and is_valid
2778
will fail, so there is no need to do anything.
2780
The trees in which events have wrong id's are:
2782
mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
2783
mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
2784
mysql-5.1-wl2325-no-dd
2786
(this was found by grepping for two lines in sequence where the
2787
first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
2788
"TABLE_MAP_EVENT," in log_event.h in all trees)
2790
In these trees, the following server_versions existed since
2791
TABLE_MAP_EVENT was introduced:
2793
5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
2794
5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
2795
5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
2796
5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
2797
5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
2798
5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
2799
5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
2800
5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
2801
5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
2802
5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
2803
5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
2804
5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
2805
5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
2806
5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
2809
(this was found by grepping for "mysql," in all historical
2810
versions of configure.in in the trees listed above).
2812
There are 5.1.1-alpha versions that use the new event id's, so we
2813
do not test that version string. So replication from 5.1.1-alpha
2814
with the other event id's to a new version does not work.
2815
Moreover, we can safely ignore the part after drop[56]. This
2816
allows us to simplify the big list above to the following regexes:
2818
5\.1\.[1-5]-a_drop5.*
2820
5\.2\.[0-2]-a_drop6.*
2822
This is what we test for in the 'if' below.
2824
if (post_header_len &&
2825
server_version[0] == '5' && server_version[1] == '.' &&
2826
server_version[3] == '.' &&
2827
strncmp(server_version + 5, "-a_drop", 7) == 0 &&
2828
((server_version[2] == '1' &&
2829
server_version[4] >= '1' && server_version[4] <= '5' &&
2830
server_version[12] == '5') ||
2831
(server_version[2] == '1' &&
2832
server_version[4] == '4' &&
2833
server_version[12] == '6') ||
2834
(server_version[2] == '2' &&
2835
server_version[4] >= '0' && server_version[4] <= '2' &&
2836
server_version[12] == '6')))
2838
if (number_of_event_types != 22)
2840
/* this makes is_valid() return false. */
2841
my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2842
post_header_len= NULL;
2845
static const uint8_t perm[23]=
2847
UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
2848
INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
2849
APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
2851
RAND_EVENT, USER_VAR_EVENT,
2852
FORMAT_DESCRIPTION_EVENT,
2854
PRE_GA_WRITE_ROWS_EVENT,
2855
PRE_GA_UPDATE_ROWS_EVENT,
2856
PRE_GA_DELETE_ROWS_EVENT,
2858
BEGIN_LOAD_QUERY_EVENT,
2859
EXECUTE_LOAD_QUERY_EVENT,
2861
event_type_permutation= perm;
2863
Since we use (permuted) event id's to index the post_header_len
2864
array, we need to permute the post_header_len array too.
2866
uint8_t post_header_len_temp[23];
2867
for (int i= 1; i < 23; i++)
2868
post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
2869
for (int i= 0; i < 22; i++)
2870
post_header_len[i] = post_header_len_temp[i];
2875
#ifndef DRIZZLE_CLIENT
2876
bool Format_description_log_event::write(IO_CACHE* file)
2879
We don't call Start_log_event_v3::write() because this would make 2
2882
uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
2883
int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2884
memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2885
if (!dont_set_created)
2886
created= when= get_time();
2887
int4store(buff + ST_CREATED_OFFSET,created);
2888
buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
2889
memcpy(buff+ST_COMMON_HEADER_LEN_OFFSET+1, post_header_len,
2891
return (write_header(file, sizeof(buff)) ||
2892
my_b_safe_write(file, buff, sizeof(buff)));
2896
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2897
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2900
As a transaction NEVER spans on 2 or more binlogs:
2901
if we have an active transaction at this point, the master died
2902
while writing the transaction to the binary log, i.e. while
2903
flushing the binlog cache to the binlog. XA guarantees that master has
2904
rolled back. So we roll back.
2905
Note: this event could be sent by the master to inform us of the
2906
format of its binlog; in other words maybe it is not at its
2907
original place when it comes to us; we'll know this by checking
2908
log_pos ("artificial" events have log_pos == 0).
2910
if (!artificial_event && created && thd->transaction.all.ha_list)
2912
/* This is not an error (XA is safe), just an information */
2913
rli->report(INFORMATION_LEVEL, 0,
2914
"Rolling back unfinished transaction (no COMMIT "
2915
"or ROLLBACK in relay log). A probable cause is that "
2916
"the master died while writing the transaction to "
2917
"its binary log, thus rolled back too.");
2918
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2921
If this event comes from ourselves, there is no cleaning task to
2922
perform, we don't call Start_log_event_v3::do_apply_event()
2923
(this was just to update the log's description event).
2925
if (server_id != (uint32_t) ::server_id)
2928
If the event was not requested by the slave i.e. the master sent
2929
it while the slave asked for a position >4, the event will make
2930
rli->group_master_log_pos advance. Say that the slave asked for
2931
position 1000, and the Format_desc event's end is 96. Then in
2932
the beginning of replication rli->group_master_log_pos will be
2933
0, then 96, then jump to first really asked event (which is
2934
>96). So this is ok.
2936
return(Start_log_event_v3::do_apply_event(rli));
2941
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
2943
/* save the information describing this binlog */
2944
delete rli->relay_log.description_event_for_exec;
2945
rli->relay_log.description_event_for_exec= this;
2947
if (server_id == (uint32_t) ::server_id)
2950
We only increase the relay log position if we are skipping
2951
events and do not touch any group_* variables, nor flush the
2952
relay log info. If there is a crash, we will have to re-skip
2953
the events again, but that is a minor issue.
2955
If we do not skip stepping the group log position (and the
2956
server id was changed when restarting the server), it might well
2957
be that we start executing at a position that is invalid, e.g.,
2958
at a Rows_log_event or a Query_log_event preceeded by a
2959
Intvar_log_event instead of starting at a Table_map_log_event or
2960
the Intvar_log_event respectively.
2962
rli->inc_event_relay_log_pos();
2967
return Log_event::do_update_pos(rli);
2971
Log_event::enum_skip_reason
2972
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((unused)))
2974
return Log_event::EVENT_SKIP_NOT;
2981
Splits the event's 'server_version' string into three numeric pieces stored
2982
into 'server_version_split':
2983
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
2986
'server_version_split' is then used for lookups to find if the server which
2987
created this event has some known bug.
2989
void Format_description_log_event::calc_server_version_split()
2991
char *p= server_version, *r;
2993
for (uint i= 0; i<=2; i++)
2995
number= strtoul(p, &r, 10);
2996
server_version_split[i]= (uchar)number;
2997
assert(number < 256); // fit in uchar
2999
assert(!((i == 0) && (*r != '.'))); // should be true in practice
3001
p++; // skip the dot
3006
/**************************************************************************
3007
Load_log_event methods
3008
General note about Load_log_event: the binlogging of LOAD DATA INFILE is
3009
going to be changed in 5.0 (or maybe in 5.1; not decided yet).
3010
However, the 5.0 slave could still have to read such events (from a 4.x
3011
master), convert them (which just means maybe expand the header, when 5.0
3012
servers have a UID in events) (remember that whatever is after the header
3013
will be like in 4.x, as this event's format is not modified in 5.0 as we
3014
will use new types of events to log the new LOAD DATA INFILE features).
3015
To be able to read/convert, we just need to not assume that the common
3016
header is of length LOG_EVENT_HEADER_LEN (we must use the description
3018
Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
3019
between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
3020
positions displayed in SHOW SLAVE STATUS then are fine too).
3021
**************************************************************************/
3024
Load_log_event::pack_info()
3027
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3028
uint Load_log_event::get_query_buffer_length()
3031
5 + db_len + 3 + // "use DB; "
3032
18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
3034
9 + // " REPLACE or IGNORE "
3035
13 + table_name_len*2 + // "INTO Table `table`"
3036
21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
3037
23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
3038
12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
3039
21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
3040
19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
3041
15 + 22 + // " IGNORE xxx LINES"
3042
3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
3046
void Load_log_event::print_query(bool need_db, char *buf,
3047
char **end, char **fn_start, char **fn_end)
3051
if (need_db && db && db_len)
3053
pos= stpcpy(pos, "use `");
3054
memcpy(pos, db, db_len);
3055
pos= stpcpy(pos+db_len, "`; ");
3058
pos= stpcpy(pos, "LOAD DATA ");
3063
if (check_fname_outside_temp_buf())
3064
pos= stpcpy(pos, "LOCAL ");
3065
pos= stpcpy(pos, "INFILE '");
3066
memcpy(pos, fname, fname_len);
3067
pos= stpcpy(pos+fname_len, "' ");
3069
if (sql_ex.opt_flags & REPLACE_FLAG)
3070
pos= stpcpy(pos, " REPLACE ");
3071
else if (sql_ex.opt_flags & IGNORE_FLAG)
3072
pos= stpcpy(pos, " IGNORE ");
3074
pos= stpcpy(pos ,"INTO");
3079
pos= stpcpy(pos ," Table `");
3080
memcpy(pos, table_name, table_name_len);
3081
pos+= table_name_len;
3083
/* We have to create all optinal fields as the default is not empty */
3084
pos= stpcpy(pos, "` FIELDS TERMINATED BY ");
3085
pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
3086
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3087
pos= stpcpy(pos, " OPTIONALLY ");
3088
pos= stpcpy(pos, " ENCLOSED BY ");
3089
pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
3091
pos= stpcpy(pos, " ESCAPED BY ");
3092
pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
3094
pos= stpcpy(pos, " LINES TERMINATED BY ");
3095
pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
3096
if (sql_ex.line_start_len)
3098
pos= stpcpy(pos, " STARTING BY ");
3099
pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
3102
if ((long) skip_lines > 0)
3104
pos= stpcpy(pos, " IGNORE ");
3105
pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
3106
pos= stpcpy(pos," LINES ");
3112
const char *field= fields;
3113
pos= stpcpy(pos, " (");
3114
for (i = 0; i < num_fields; i++)
3121
memcpy(pos, field, field_lens[i]);
3122
pos+= field_lens[i];
3123
field+= field_lens[i] + 1;
3132
void Load_log_event::pack_info(Protocol *protocol)
3136
if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
3138
print_query(true, buf, &end, 0, 0);
3139
protocol->store(buf, end-buf, &my_charset_bin);
3140
my_free(buf, MYF(0));
3142
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
3145
#ifndef DRIZZLE_CLIENT
3148
Load_log_event::write_data_header()
3151
bool Load_log_event::write_data_header(IO_CACHE* file)
3153
char buf[LOAD_HEADER_LEN];
3154
int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
3155
int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
3156
int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
3157
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
3158
buf[L_DB_LEN_OFFSET] = (char)db_len;
3159
int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
3160
return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
3165
Load_log_event::write_data_body()
3168
bool Load_log_event::write_data_body(IO_CACHE* file)
3170
if (sql_ex.write_data(file))
3172
if (num_fields && fields && field_lens)
3174
if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
3175
my_b_safe_write(file, (uchar*)fields, field_block_len))
3178
return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
3179
my_b_safe_write(file, (uchar*)db, db_len + 1) ||
3180
my_b_safe_write(file, (uchar*)fname, fname_len));
3185
Load_log_event::Load_log_event()
3188
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
3189
const char *db_arg, const char *table_name_arg,
3190
List<Item> &fields_arg,
3191
enum enum_duplicates handle_dup,
3192
bool ignore, bool using_trans)
3194
thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
3196
thread_id(thd_arg->thread_id),
3197
slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3198
num_fields(0),fields(0),
3199
field_lens(0),field_block_len(0),
3200
table_name(table_name_arg ? table_name_arg : ""),
3201
db(db_arg), fname(ex->file_name), local_fname(false)
3205
exec_time = (ulong) (end_time - thd_arg->start_time);
3206
/* db can never be a zero pointer in 4.0 */
3207
db_len = (uint32_t) strlen(db);
3208
table_name_len = (uint32_t) strlen(table_name);
3209
fname_len = (fname) ? (uint) strlen(fname) : 0;
3210
sql_ex.field_term = (char*) ex->field_term->ptr();
3211
sql_ex.field_term_len = (uint8_t) ex->field_term->length();
3212
sql_ex.enclosed = (char*) ex->enclosed->ptr();
3213
sql_ex.enclosed_len = (uint8_t) ex->enclosed->length();
3214
sql_ex.line_term = (char*) ex->line_term->ptr();
3215
sql_ex.line_term_len = (uint8_t) ex->line_term->length();
3216
sql_ex.line_start = (char*) ex->line_start->ptr();
3217
sql_ex.line_start_len = (uint8_t) ex->line_start->length();
3218
sql_ex.escaped = (char*) ex->escaped->ptr();
3219
sql_ex.escaped_len = (uint8_t) ex->escaped->length();
3220
sql_ex.opt_flags = 0;
3221
sql_ex.cached_new_format = -1;
3224
sql_ex.opt_flags|= DUMPFILE_FLAG;
3225
if (ex->opt_enclosed)
3226
sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
3228
sql_ex.empty_flags= 0;
3230
switch (handle_dup) {
3232
sql_ex.opt_flags|= REPLACE_FLAG;
3234
case DUP_UPDATE: // Impossible here
3239
sql_ex.opt_flags|= IGNORE_FLAG;
3241
if (!ex->field_term->length())
3242
sql_ex.empty_flags |= FIELD_TERM_EMPTY;
3243
if (!ex->enclosed->length())
3244
sql_ex.empty_flags |= ENCLOSED_EMPTY;
3245
if (!ex->line_term->length())
3246
sql_ex.empty_flags |= LINE_TERM_EMPTY;
3247
if (!ex->line_start->length())
3248
sql_ex.empty_flags |= LINE_START_EMPTY;
3249
if (!ex->escaped->length())
3250
sql_ex.empty_flags |= ESCAPED_EMPTY;
3252
skip_lines = ex->skip_lines;
3254
List_iterator<Item> li(fields_arg);
3255
field_lens_buf.length(0);
3256
fields_buf.length(0);
3258
while ((item = li++))
3261
uchar len = (uchar) strlen(item->name);
3262
field_block_len += len + 1;
3263
fields_buf.append(item->name, len + 1);
3264
field_lens_buf.append((char*)&len, 1);
3267
field_lens = (const uchar*)field_lens_buf.ptr();
3268
fields = fields_buf.ptr();
3270
#endif /* !DRIZZLE_CLIENT */
3275
The caller must do buf[event_len] = 0 before he starts using the
3278
Load_log_event::Load_log_event(const char *buf, uint event_len,
3279
const Format_description_log_event *description_event)
3280
:Log_event(buf, description_event), num_fields(0), fields(0),
3281
field_lens(0),field_block_len(0),
3282
table_name(0), db(0), fname(0), local_fname(false)
3285
I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
3286
4.0->5.0 and 5.0->5.0 and it works.
3289
copy_log_event(buf, event_len,
3290
((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
3292
description_event->common_header_len :
3293
LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
3295
/* otherwise it's a derived class, will call copy_log_event() itself */
3301
Load_log_event::copy_log_event()
3304
int Load_log_event::copy_log_event(const char *buf, ulong event_len,
3306
const Format_description_log_event *description_event)
3309
char* buf_end = (char*)buf + event_len;
3310
/* this is the beginning of the post-header */
3311
const char* data_head = buf + description_event->common_header_len;
3312
slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
3313
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
3314
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
3315
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
3316
db_len = (uint)data_head[L_DB_LEN_OFFSET];
3317
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
3319
if ((int) event_len < body_offset)
3322
Sql_ex.init() on success returns the pointer to the first byte after
3323
the sql_ex structure, which is the start of field lengths array.
3325
if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
3327
buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
3330
data_len = event_len - body_offset;
3331
if (num_fields > data_len) // simple sanity check against corruption
3333
for (uint i = 0; i < num_fields; i++)
3334
field_block_len += (uint)field_lens[i] + 1;
3336
fields = (char*)field_lens + num_fields;
3337
table_name = fields + field_block_len;
3338
db = table_name + table_name_len + 1;
3339
fname = db + db_len + 1;
3340
fname_len = strlen(fname);
3341
// null termination is accomplished by the caller doing buf[event_len]=0
3348
Load_log_event::print()
3351
#ifdef DRIZZLE_CLIENT
3352
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3354
print(file, print_event_info, 0);
3358
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
3361
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
3363
if (!print_event_info->short_form)
3365
print_header(&cache, print_event_info, false);
3366
my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
3367
thread_id, exec_time);
3370
bool different_db= 1;
3374
If the database is different from the one of the previous statement, we
3375
need to print the "use" command, and we update the last_db.
3376
But if commented, the "use" is going to be commented so we should not
3379
if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
3381
memcpy(print_event_info->db, db, db_len + 1);
3384
if (db && db[0] && different_db)
3385
my_b_printf(&cache, "%suse %s%s\n",
3386
commented ? "# " : "",
3387
db, print_event_info->delimiter);
3389
if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
3390
my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
3391
commented ? "# " : "", (ulong)thread_id,
3392
print_event_info->delimiter);
3393
my_b_printf(&cache, "%sLOAD DATA ",
3394
commented ? "# " : "");
3395
if (check_fname_outside_temp_buf())
3396
my_b_printf(&cache, "LOCAL ");
3397
my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
3399
if (sql_ex.opt_flags & REPLACE_FLAG)
3400
my_b_printf(&cache," REPLACE ");
3401
else if (sql_ex.opt_flags & IGNORE_FLAG)
3402
my_b_printf(&cache," IGNORE ");
3404
my_b_printf(&cache, "INTO Table `%s`", table_name);
3405
my_b_printf(&cache, " FIELDS TERMINATED BY ");
3406
pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
3408
if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3409
my_b_printf(&cache," OPTIONALLY ");
3410
my_b_printf(&cache, " ENCLOSED BY ");
3411
pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
3413
my_b_printf(&cache, " ESCAPED BY ");
3414
pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
3416
my_b_printf(&cache," LINES TERMINATED BY ");
3417
pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
3420
if (sql_ex.line_start)
3422
my_b_printf(&cache," STARTING BY ");
3423
pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
3425
if ((long) skip_lines > 0)
3426
my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
3431
const char* field = fields;
3432
my_b_printf(&cache, " (");
3433
for (i = 0; i < num_fields; i++)
3436
my_b_printf(&cache, ",");
3437
my_b_printf(&cache, field);
3439
field += field_lens[i] + 1;
3441
my_b_printf(&cache, ")");
3444
my_b_printf(&cache, "%s\n", print_event_info->delimiter);
3447
#endif /* DRIZZLE_CLIENT */
3449
#ifndef DRIZZLE_CLIENT
3452
Load_log_event::set_fields()
3455
This function can not use the member variable
3456
for the database, since LOAD DATA INFILE on the slave
3457
can be for a different database than the current one.
3458
This is the reason for the affected_db argument to this method.
3461
void Load_log_event::set_fields(const char* affected_db,
3462
List<Item> &field_list,
3463
Name_resolution_context *context)
3466
const char* field = fields;
3467
for (i= 0; i < num_fields; i++)
3469
field_list.push_back(new Item_field(context,
3470
affected_db, table_name, field));
3471
field+= field_lens[i] + 1;
3474
#endif /* !DRIZZLE_CLIENT */
3477
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3479
Does the data loading job when executing a LOAD DATA on the slave.
3483
@param use_rli_only_for_errors If set to 1, rli is provided to
3484
Load_log_event::exec_event only for this
3485
function to have RPL_LOG_NAME and
3486
rli->last_slave_error, both being used by
3487
error reports. rli's position advancing
3488
is skipped (done by the caller which is
3489
Execute_load_log_event::exec_event).
3490
If set to 0, rli is provided for full use,
3491
i.e. for error reports and position
3495
fix this; this can be done by testing rules in
3496
Create_file_log_event::exec_event() and then discarding Append_block and
3499
this is a bug - this needs to be moved to the I/O thread
3507
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
3508
bool use_rli_only_for_errors)
3511
new_db.length= db_len;
3512
new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
3513
thd->set_db(new_db.str, new_db.length);
3514
assert(thd->query == 0);
3515
thd->query_length= 0; // Should not be needed
3516
thd->is_slave_error= 0;
3517
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
3519
/* see Query_log_event::do_apply_event() and BUG#13360 */
3520
assert(!rli->m_table_map.count());
3522
Usually lex_start() is called by mysql_parse(), but we need it here
3523
as the present method does not call mysql_parse().
3526
mysql_reset_thd_for_next_command(thd);
3528
if (!use_rli_only_for_errors)
3531
Saved for InnoDB, see comment in
3532
Query_log_event::do_apply_event()
3534
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
3538
We test replicate_*_db rules. Note that we have already prepared
3539
the file to load, even if we are going to ignore and delete it
3540
now. So it is possible that we did a lot of disk writes for
3541
nothing. In other words, a big LOAD DATA INFILE on the master will
3542
still consume a lot of space on the slave (space in the relay log
3543
+ space of temp files: twice the space of the file to load...)
3544
even if it will finally be ignored. TODO: fix this; this can be
3545
done by testing rules in Create_file_log_event::do_apply_event()
3546
and then discarding Append_block and al. Another way is do the
3547
filtering in the I/O thread (more efficient: no disk writes at
3551
Note: We do not need to execute reset_one_shot_variables() if this
3553
Reason: The db stored in binlog events is the same for SET and for
3554
its companion query. If the SET is ignored because of
3555
db_ok(), the companion query will also be ignored, and if
3556
the companion query is ignored in the db_ok() test of
3557
::do_apply_event(), then the companion SET also have so
3558
we don't need to reset_one_shot_variables().
3560
if (rpl_filter->db_ok(thd->db))
3562
thd->set_time((time_t)when);
3563
VOID(pthread_mutex_lock(&LOCK_thread_count));
3564
thd->query_id = next_query_id();
3565
VOID(pthread_mutex_unlock(&LOCK_thread_count));
3567
Initing thd->row_count is not necessary in theory as this variable has no
3568
influence in the case of the slave SQL thread (it is used to generate a
3569
"data truncated" warning but which is absorbed and never gets to the
3570
error log); still we init it to avoid a Valgrind message.
3572
drizzle_reset_errors(thd, 0);
3575
memset(&tables, 0, sizeof(tables));
3576
tables.db= thd->strmake(thd->db, thd->db_length);
3577
tables.alias = tables.table_name = (char*) table_name;
3578
tables.lock_type = TL_WRITE;
3581
// the table will be opened in mysql_load
3582
if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
3584
// TODO: this is a bug - this needs to be moved to the I/O thread
3586
skip_load_data_infile(net);
3592
enum enum_duplicates handle_dup;
3594
char *load_data_query;
3597
Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
3598
and written to slave's binlog if binlogging is on.
3600
if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
3603
This will set thd->fatal_error in case of OOM. So we surely will notice
3604
that something is wrong.
3609
print_query(false, load_data_query, &end, (char **)&thd->lex->fname_start,
3610
(char **)&thd->lex->fname_end);
3612
thd->query_length= end - load_data_query;
3613
thd->query= load_data_query;
3615
if (sql_ex.opt_flags & REPLACE_FLAG)
3617
handle_dup= DUP_REPLACE;
3619
else if (sql_ex.opt_flags & IGNORE_FLAG)
3622
handle_dup= DUP_ERROR;
3627
When replication is running fine, if it was DUP_ERROR on the
3628
master then we could choose IGNORE here, because if DUP_ERROR
3629
suceeded on master, and data is identical on the master and slave,
3630
then there should be no uniqueness errors on slave, so IGNORE is
3631
the same as DUP_ERROR. But in the unlikely case of uniqueness errors
3632
(because the data on the master and slave happen to be different
3633
(user error or bug), we want LOAD DATA to print an error message on
3634
the slave to discover the problem.
3636
If reading from net (a 3.23 master), mysql_load() will change this
3639
handle_dup= DUP_ERROR;
3642
We need to set thd->lex->sql_command and thd->lex->duplicates
3643
since InnoDB tests these variables to decide if this is a LOAD
3644
DATA ... REPLACE INTO ... statement even though mysql_parse()
3645
is not called. This is not needed in 5.0 since there the LOAD
3646
DATA ... statement is replicated using mysql_parse(), which
3647
sets the thd->lex fields correctly.
3649
thd->lex->sql_command= SQLCOM_LOAD;
3650
thd->lex->duplicates= handle_dup;
3652
sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
3653
String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
3654
String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
3655
String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
3656
String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
3657
String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
3658
ex.field_term= &field_term;
3659
ex.enclosed= &enclosed;
3660
ex.line_term= &line_term;
3661
ex.line_start= &line_start;
3662
ex.escaped= &escaped;
3664
ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
3665
if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
3666
ex.field_term->length(0);
3668
ex.skip_lines = skip_lines;
3669
List<Item> field_list;
3670
thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
3671
set_fields(tables.db, field_list, &thd->lex->select_lex.context);
3672
thd->variables.pseudo_thread_id= thread_id;
3675
// mysql_load will use thd->net to read the file
3676
thd->net.vio = net->vio;
3678
Make sure the client does not get confused about the packet sequence
3680
thd->net.pkt_nr = net->pkt_nr;
3683
It is safe to use tmp_list twice because we are not going to
3684
update it inside mysql_load().
3686
List<Item> tmp_list;
3687
if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
3688
handle_dup, ignore, net != 0))
3689
thd->is_slave_error= 1;
3690
if (thd->cuted_fields)
3692
/* log_pos is the position of the LOAD event in the master log */
3693
sql_print_warning(_("Slave: load data infile on table '%s' at "
3694
"log position %s in log '%s' produced %ld "
3695
"warning(s). Default database: '%s'"),
3697
llstr(log_pos,llbuff), RPL_LOG_NAME,
3698
(ulong) thd->cuted_fields,
3699
print_slave_db_safe(thd->db));
3702
net->pkt_nr= thd->net.pkt_nr;
3708
We will just ask the master to send us /dev/null if we do not
3709
want to load the data.
3710
TODO: this a bug - needs to be done in I/O thread
3713
skip_load_data_infile(net);
3718
const char *remember_db= thd->db;
3719
VOID(pthread_mutex_lock(&LOCK_thread_count));
3721
thd->set_db(NULL, 0); /* will free the current database */
3723
thd->query_length= 0;
3724
VOID(pthread_mutex_unlock(&LOCK_thread_count));
3725
close_thread_tables(thd);
3727
if (thd->is_slave_error)
3729
/* this err/sql_errno code is copy-paste from net_send_error() */
3732
if (thd->is_error())
3734
err= thd->main_da.message();
3735
sql_errno= thd->main_da.sql_errno();
3739
sql_errno=ER_UNKNOWN_ERROR;
3742
rli->report(ERROR_LEVEL, sql_errno,"\
3743
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
3744
err, (char*)table_name, print_slave_db_safe(remember_db));
3745
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3748
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3750
if (thd->is_fatal_error)
3753
snprintf(buf, sizeof(buf),
3754
"Running LOAD DATA INFILE on table '%-.64s'."
3755
" Default database: '%-.64s'",
3757
print_slave_db_safe(remember_db));
3759
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3760
ER(ER_SLAVE_FATAL_ERROR), buf);
3764
return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
3769
/**************************************************************************
3770
Rotate_log_event methods
3771
**************************************************************************/
3774
Rotate_log_event::pack_info()
3777
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3778
void Rotate_log_event::pack_info(Protocol *protocol)
3780
char buf1[256], buf[22];
3781
String tmp(buf1, sizeof(buf1), log_cs);
3783
tmp.append(new_log_ident, ident_len);
3784
tmp.append(STRING_WITH_LEN(";pos="));
3785
tmp.append(llstr(pos,buf));
3786
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3792
Rotate_log_event::print()
3795
#ifdef DRIZZLE_CLIENT
3796
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3799
Write_on_release_cache cache(&print_event_info->head_cache, file,
3800
Write_on_release_cache::FLUSH_F);
3802
if (print_event_info->short_form)
3804
print_header(&cache, print_event_info, false);
3805
my_b_printf(&cache, "\tRotate to ");
3807
my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
3808
my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
3810
#endif /* DRIZZLE_CLIENT */
3815
Rotate_log_event::Rotate_log_event() (2 constructors)
3819
#ifndef DRIZZLE_CLIENT
3820
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
3821
uint ident_len_arg, uint64_t pos_arg,
3823
:Log_event(), new_log_ident(new_log_ident_arg),
3824
pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3825
(uint) strlen(new_log_ident_arg)), flags(flags_arg)
3827
if (flags & DUP_NAME)
3828
new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
3834
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
3835
const Format_description_log_event* description_event)
3836
:Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
3838
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
3839
uint8_t header_size= description_event->common_header_len;
3840
uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
3842
if (event_len < header_size)
3845
pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
3846
ident_len = (uint)(event_len -
3847
(header_size+post_header_len));
3848
ident_offset = post_header_len;
3849
set_if_smaller(ident_len,FN_REFLEN-1);
3850
new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
3856
Rotate_log_event::write()
3859
#ifndef DRIZZLE_CLIENT
3860
bool Rotate_log_event::write(IO_CACHE* file)
3862
char buf[ROTATE_HEADER_LEN];
3863
int8store(buf + R_POS_OFFSET, pos);
3864
return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
3865
my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
3866
my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
3871
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3874
Got a rotate log event from the master.
3876
This is mainly used so that we can later figure out the logname and
3877
position for the master.
3879
We can't rotate the slave's BINlog as this will cause infinitive rotations
3880
in a A -> B -> A setup.
3881
The NOTES below is a wrong comment which will disappear when 4.1 is merged.
3886
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
3888
pthread_mutex_lock(&rli->data_lock);
3889
rli->event_relay_log_pos= my_b_tell(rli->cur_log);
3891
If we are in a transaction or in a group: the only normal case is
3892
when the I/O thread was copying a big transaction, then it was
3893
stopped and restarted: we have this in the relay log:
3901
In that case, we don't want to touch the coordinates which
3902
correspond to the beginning of the transaction. Starting from
3903
5.0.0, there also are some rotates from the slave itself, in the
3904
relay log, which shall not change the group positions.
3906
if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3907
!rli->is_in_group())
3909
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3910
rli->notify_group_master_log_name_update();
3911
rli->group_master_log_pos= pos;
3912
strmake(rli->group_relay_log_name, rli->event_relay_log_name,
3913
sizeof(rli->group_relay_log_name) - 1);
3914
rli->notify_group_relay_log_name_update();
3915
rli->group_relay_log_pos= rli->event_relay_log_pos;
3917
Reset thd->options and sql_mode etc, because this could be the signal of
3918
a master's downgrade from 5.0 to 4.0.
3919
However, no need to reset description_event_for_exec: indeed, if the next
3920
master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
3921
master is 4.0 then the events are in the slave's format (conversion).
3923
set_slave_thread_options(thd);
3924
set_slave_thread_default_charset(thd, rli);
3925
thd->variables.auto_increment_increment=
3926
thd->variables.auto_increment_offset= 1;
3928
pthread_mutex_unlock(&rli->data_lock);
3929
pthread_cond_broadcast(&rli->data_cond);
3930
flush_relay_log_info(rli);
3936
Log_event::enum_skip_reason
3937
Rotate_log_event::do_shall_skip(Relay_log_info *rli)
3939
enum_skip_reason reason= Log_event::do_shall_skip(rli);
3942
case Log_event::EVENT_SKIP_NOT:
3943
case Log_event::EVENT_SKIP_COUNT:
3944
return Log_event::EVENT_SKIP_NOT;
3946
case Log_event::EVENT_SKIP_IGNORE:
3947
return Log_event::EVENT_SKIP_IGNORE;
3950
return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
3956
/**************************************************************************
3957
Intvar_log_event methods
3958
**************************************************************************/
3961
Intvar_log_event::pack_info()
3964
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3965
void Intvar_log_event::pack_info(Protocol *protocol)
3967
char buf[256], *pos;
3968
pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
3970
pos= int64_t10_to_str(val, pos, -10);
3971
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3977
Intvar_log_event::Intvar_log_event()
3980
Intvar_log_event::Intvar_log_event(const char* buf,
3981
const Format_description_log_event* description_event)
3982
:Log_event(buf, description_event)
3984
buf+= description_event->common_header_len;
3985
type= buf[I_TYPE_OFFSET];
3986
val= uint8korr(buf+I_VAL_OFFSET);
3991
Intvar_log_event::get_var_type_name()
3994
const char* Intvar_log_event::get_var_type_name()
3997
case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
3998
case INSERT_ID_EVENT: return "INSERT_ID";
3999
default: /* impossible */ return "UNKNOWN";
4005
Intvar_log_event::write()
4008
#ifndef DRIZZLE_CLIENT
4009
bool Intvar_log_event::write(IO_CACHE* file)
4012
buf[I_TYPE_OFFSET]= (uchar) type;
4013
int8store(buf + I_VAL_OFFSET, val);
4014
return (write_header(file, sizeof(buf)) ||
4015
my_b_safe_write(file, buf, sizeof(buf)));
4021
Intvar_log_event::print()
4024
#ifdef DRIZZLE_CLIENT
4025
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4029
Write_on_release_cache cache(&print_event_info->head_cache, file,
4030
Write_on_release_cache::FLUSH_F);
4032
if (!print_event_info->short_form)
4034
print_header(&cache, print_event_info, false);
4035
my_b_printf(&cache, "\tIntvar\n");
4038
my_b_printf(&cache, "SET ");
4040
case LAST_INSERT_ID_EVENT:
4041
msg="LAST_INSERT_ID";
4043
case INSERT_ID_EVENT:
4046
case INVALID_INT_EVENT:
4047
default: // cannot happen
4051
my_b_printf(&cache, "%s=%s%s\n",
4052
msg, llstr(val,llbuff), print_event_info->delimiter);
4058
Intvar_log_event::do_apply_event()
4061
#if defined(HAVE_REPLICATION)&& !defined(DRIZZLE_CLIENT)
4062
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
4065
We are now in a statement until the associated query log event has
4068
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4071
case LAST_INSERT_ID_EVENT:
4072
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
4073
thd->first_successful_insert_id_in_prev_stmt= val;
4075
case INSERT_ID_EVENT:
4076
thd->force_one_auto_inc_interval(val);
4082
int Intvar_log_event::do_update_pos(Relay_log_info *rli)
4084
rli->inc_event_relay_log_pos();
4089
Log_event::enum_skip_reason
4090
Intvar_log_event::do_shall_skip(Relay_log_info *rli)
4093
It is a common error to set the slave skip counter to 1 instead of
4094
2 when recovering from an insert which used a auto increment,
4095
rand, or user var. Therefore, if the slave skip counter is 1, we
4096
just say that this event should be skipped by ignoring it, meaning
4097
that we do not change the value of the slave skip counter since it
4098
will be decreased by the following insert event.
4100
return continue_group(rli);
4106
/**************************************************************************
4107
Rand_log_event methods
4108
**************************************************************************/
4110
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4111
void Rand_log_event::pack_info(Protocol *protocol)
4113
char buf1[256], *pos;
4114
pos= stpcpy(buf1,"rand_seed1=");
4115
pos= int10_to_str((long) seed1, pos, 10);
4116
pos= stpcpy(pos, ",rand_seed2=");
4117
pos= int10_to_str((long) seed2, pos, 10);
4118
protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
4123
Rand_log_event::Rand_log_event(const char* buf,
4124
const Format_description_log_event* description_event)
4125
:Log_event(buf, description_event)
4127
buf+= description_event->common_header_len;
4128
seed1= uint8korr(buf+RAND_SEED1_OFFSET);
4129
seed2= uint8korr(buf+RAND_SEED2_OFFSET);
4133
#ifndef DRIZZLE_CLIENT
4134
bool Rand_log_event::write(IO_CACHE* file)
4137
int8store(buf + RAND_SEED1_OFFSET, seed1);
4138
int8store(buf + RAND_SEED2_OFFSET, seed2);
4139
return (write_header(file, sizeof(buf)) ||
4140
my_b_safe_write(file, buf, sizeof(buf)));
4145
#ifdef DRIZZLE_CLIENT
4146
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4148
Write_on_release_cache cache(&print_event_info->head_cache, file,
4149
Write_on_release_cache::FLUSH_F);
4151
char llbuff[22],llbuff2[22];
4152
if (!print_event_info->short_form)
4154
print_header(&cache, print_event_info, false);
4155
my_b_printf(&cache, "\tRand\n");
4157
my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
4158
llstr(seed1, llbuff),llstr(seed2, llbuff2),
4159
print_event_info->delimiter);
4161
#endif /* DRIZZLE_CLIENT */
4164
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4165
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
4168
We are now in a statement until the associated query log event has
4171
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4173
thd->rand.seed1= (ulong) seed1;
4174
thd->rand.seed2= (ulong) seed2;
4178
int Rand_log_event::do_update_pos(Relay_log_info *rli)
4180
rli->inc_event_relay_log_pos();
4185
Log_event::enum_skip_reason
4186
Rand_log_event::do_shall_skip(Relay_log_info *rli)
4189
It is a common error to set the slave skip counter to 1 instead of
4190
2 when recovering from an insert which used a auto increment,
4191
rand, or user var. Therefore, if the slave skip counter is 1, we
4192
just say that this event should be skipped by ignoring it, meaning
4193
that we do not change the value of the slave skip counter since it
4194
will be decreased by the following insert event.
4196
return continue_group(rli);
4199
#endif /* !DRIZZLE_CLIENT */
4202
/**************************************************************************
4203
Xid_log_event methods
4204
**************************************************************************/
4206
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4207
void Xid_log_event::pack_info(Protocol *protocol)
4209
char buf[128], *pos;
4210
pos= stpcpy(buf, "COMMIT /* xid=");
4211
pos= int64_t10_to_str(xid, pos, 10);
4212
pos= stpcpy(pos, " */");
4213
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4219
It's ok not to use int8store here,
4220
as long as xid_t::set(uint64_t) and
4221
xid_t::get_my_xid doesn't do it either.
4222
We don't care about actual values of xids as long as
4223
identical numbers compare identically
4227
Xid_log_event(const char* buf,
4228
const Format_description_log_event *description_event)
4229
:Log_event(buf, description_event)
4231
buf+= description_event->common_header_len;
4232
memcpy(&xid, buf, sizeof(xid));
4236
#ifndef DRIZZLE_CLIENT
4237
bool Xid_log_event::write(IO_CACHE* file)
4239
return write_header(file, sizeof(xid)) ||
4240
my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
4245
#ifdef DRIZZLE_CLIENT
4246
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4248
Write_on_release_cache cache(&print_event_info->head_cache, file,
4249
Write_on_release_cache::FLUSH_F);
4251
if (!print_event_info->short_form)
4254
int64_t10_to_str(xid, buf, 10);
4256
print_header(&cache, print_event_info, false);
4257
my_b_printf(&cache, "\tXid = %s\n", buf);
4259
my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
4261
#endif /* DRIZZLE_CLIENT */
4264
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4265
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4267
/* For a slave Xid_log_event is COMMIT */
4268
general_log_print(thd, COM_QUERY,
4269
"COMMIT /* implicit, from Xid_log_event */");
4270
return end_trans(thd, COMMIT);
4273
Log_event::enum_skip_reason
4274
Xid_log_event::do_shall_skip(Relay_log_info *rli)
4276
if (rli->slave_skip_counter > 0) {
4277
thd->options&= ~OPTION_BEGIN;
4278
return(Log_event::EVENT_SKIP_COUNT);
4280
return(Log_event::do_shall_skip(rli));
4282
#endif /* !DRIZZLE_CLIENT */
4285
/**************************************************************************
4286
User_var_log_event methods
4287
**************************************************************************/
4289
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4290
void User_var_log_event::pack_info(Protocol* protocol)
4293
uint val_offset= 4 + name_len;
4294
uint event_len= val_offset;
4298
if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
4300
stpcpy(buf + val_offset, "NULL");
4301
event_len= val_offset + 4;
4308
float8get(real_val, val);
4309
if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
4312
event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
4313
buf + val_offset, NULL);
4316
if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
4318
event_len= int64_t10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
4320
case DECIMAL_RESULT:
4322
if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
4325
String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
4327
binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
4329
my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
4330
event_len= str.length() + val_offset;
4334
/* 15 is for 'COLLATE' and other chars */
4335
buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
4337
const CHARSET_INFO *cs;
4340
if (!(cs= get_charset(charset_number, MYF(0))))
4342
stpcpy(buf+val_offset, "???");
4347
char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
4348
p= str_to_hex(p, val, val_len);
4349
p= strxmov(p, " COLLATE ", cs->name, NullS);
4361
memcpy(buf+2, name, name_len);
4362
buf[2+name_len]= '`';
4363
buf[3+name_len]= '=';
4364
protocol->store(buf, event_len, &my_charset_bin);
4365
my_free(buf, MYF(0));
4367
#endif /* !DRIZZLE_CLIENT */
4370
User_var_log_event::
4371
User_var_log_event(const char* buf,
4372
const Format_description_log_event* description_event)
4373
:Log_event(buf, description_event)
4375
buf+= description_event->common_header_len;
4376
name_len= uint4korr(buf);
4377
name= (char *) buf + UV_NAME_LEN_SIZE;
4378
buf+= UV_NAME_LEN_SIZE + name_len;
4379
is_null= (bool) *buf;
4382
type= STRING_RESULT;
4383
charset_number= my_charset_bin.number;
4389
type= (Item_result) buf[UV_VAL_IS_NULL];
4390
charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
4391
val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4392
UV_CHARSET_NUMBER_SIZE);
4393
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4394
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
4399
#ifndef DRIZZLE_CLIENT
4400
bool User_var_log_event::write(IO_CACHE* file)
4402
char buf[UV_NAME_LEN_SIZE];
4403
char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4404
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
4405
uchar buf2[(8 > DECIMAL_MAX_FIELD_SIZE + 2) ? 8 : DECIMAL_MAX_FIELD_SIZE +2], *pos= buf2;
4409
int4store(buf, name_len);
4411
if ((buf1[0]= is_null))
4414
val_len= 0; // Length of 'pos'
4419
int4store(buf1 + 2, charset_number);
4423
float8store(buf2, *(double*) val);
4426
int8store(buf2, *(int64_t*) val);
4428
case DECIMAL_RESULT:
4430
my_decimal *dec= (my_decimal *)val;
4431
dec->fix_buffer_pointer();
4432
buf2[0]= (char)(dec->intg + dec->frac);
4433
buf2[1]= (char)dec->frac;
4434
decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
4435
val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
4446
int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
4450
/* Length of the whole event */
4451
event_length= sizeof(buf)+ name_len + buf1_length + val_len;
4453
return (write_header(file, event_length) ||
4454
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
4455
my_b_safe_write(file, (uchar*) name, name_len) ||
4456
my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
4457
my_b_safe_write(file, pos, val_len));
4463
User_var_log_event::print()
4466
#ifdef DRIZZLE_CLIENT
4467
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4469
Write_on_release_cache cache(&print_event_info->head_cache, file,
4470
Write_on_release_cache::FLUSH_F);
4472
if (!print_event_info->short_form)
4474
print_header(&cache, print_event_info, false);
4475
my_b_printf(&cache, "\tUser_var\n");
4478
my_b_printf(&cache, "SET @`");
4479
my_b_write(&cache, (uchar*) name, (uint) (name_len));
4480
my_b_printf(&cache, "`");
4484
my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
4491
char real_buf[FMT_G_BUFSIZE(14)];
4492
float8get(real_val, val);
4493
sprintf(real_buf, "%.14g", real_val);
4494
my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
4498
int64_t10_to_str(uint8korr(val), int_buf, -10);
4499
my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
4501
case DECIMAL_RESULT:
4504
int str_len= sizeof(str_buf) - 1;
4505
int precision= (int)val[0];
4506
int scale= (int)val[1];
4507
decimal_digit_t dec_buf[10];
4512
bin2decimal((uchar*) val+2, &dec, precision, scale);
4513
decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
4514
str_buf[str_len]= 0;
4515
my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
4521
Let's express the string in hex. That's the most robust way. If we
4522
print it in character form instead, we need to escape it with
4523
character_set_client which we don't know (we will know it in 5.0, but
4524
in 4.1 we don't know it easily when we are printing
4525
User_var_log_event). Explanation why we would need to bother with
4526
character_set_client (quoting Bar):
4527
> Note, the parser doesn't switch to another unescaping mode after
4528
> it has met a character set introducer.
4529
> For example, if an SJIS client says something like:
4530
> SET @a= _ucs2 \0a\0b'
4531
> the string constant is still unescaped according to SJIS, not
4532
> according to UCS2.
4535
const CHARSET_INFO *cs;
4537
if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
4538
break; // no error, as we are 'void'
4539
str_to_hex(hex_str, val, val_len);
4541
For proper behaviour when mysqlbinlog|mysql, we need to explicitely
4542
specify the variable's collation. It will however cause problems when
4543
people want to mysqlbinlog|mysql into another server not supporting the
4544
character set. But there's not much to do about this and it's unlikely.
4546
if (!(cs= get_charset(charset_number, MYF(0))))
4548
Generate an unusable command (=> syntax error) is probably the best
4549
thing we can do here.
4551
my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
4553
my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
4554
cs->csname, hex_str, cs->name,
4555
print_event_info->delimiter);
4570
User_var_log_event::do_apply_event()
4573
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4574
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
4577
const CHARSET_INFO *charset;
4578
if (!(charset= get_charset(charset_number, MYF(MY_WME))))
4580
LEX_STRING user_var_name;
4581
user_var_name.str= name;
4582
user_var_name.length= name_len;
4587
We are now in a statement until the associated query log event has
4590
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4594
it= new Item_null();
4600
float8get(real_val, val);
4601
it= new Item_float(real_val, 0);
4602
val= (char*) &real_val; // Pointer to value in native format
4606
int_val= (int64_t) uint8korr(val);
4607
it= new Item_int(int_val);
4608
val= (char*) &int_val; // Pointer to value in native format
4611
case DECIMAL_RESULT:
4613
Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
4615
val= (char *)dec->val_decimal(NULL);
4616
val_len= sizeof(my_decimal);
4620
it= new Item_string(val, val_len, charset);
4628
Item_func_set_user_var e(user_var_name, it);
4630
Item_func_set_user_var can't substitute something else on its place =>
4631
0 can be passed as last argument (reference on item)
4633
e.fix_fields(thd, 0);
4635
A variable can just be considered as a table with
4636
a single record and with a single column. Thus, like
4637
a column value, it could always have IMPLICIT derivation.
4639
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
4640
free_root(thd->mem_root,0);
4645
int User_var_log_event::do_update_pos(Relay_log_info *rli)
4647
rli->inc_event_relay_log_pos();
4651
Log_event::enum_skip_reason
4652
User_var_log_event::do_shall_skip(Relay_log_info *rli)
4655
It is a common error to set the slave skip counter to 1 instead
4656
of 2 when recovering from an insert which used a auto increment,
4657
rand, or user var. Therefore, if the slave skip counter is 1, we
4658
just say that this event should be skipped by ignoring it, meaning
4659
that we do not change the value of the slave skip counter since it
4660
will be decreased by the following insert event.
4662
return continue_group(rli);
4664
#endif /* !DRIZZLE_CLIENT */
4667
/**************************************************************************
4668
Slave_log_event methods
4669
**************************************************************************/
4671
#ifdef HAVE_REPLICATION
4672
#ifdef DRIZZLE_CLIENT
4673
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
4675
Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
4677
if (print_event_info->short_form)
4679
print_header(&cache, print_event_info, false);
4680
my_b_printf(&cache, "\n# %s", "Unknown event\n");
4684
#ifndef DRIZZLE_CLIENT
4685
void Slave_log_event::pack_info(Protocol *protocol)
4687
char buf[256+HOSTNAME_LENGTH], *pos;
4688
pos= stpcpy(buf, "host=");
4689
pos= stpncpy(pos, master_host, HOSTNAME_LENGTH);
4690
pos= stpcpy(pos, ",port=");
4691
pos= int10_to_str((long) master_port, pos, 10);
4692
pos= stpcpy(pos, ",log=");
4693
pos= stpcpy(pos, master_log);
4694
pos= stpcpy(pos, ",pos=");
4695
pos= int64_t10_to_str(master_pos, pos, 10);
4696
protocol->store(buf, pos-buf, &my_charset_bin);
4698
#endif /* !DRIZZLE_CLIENT */
4701
#ifndef DRIZZLE_CLIENT
4704
re-write this better without holding both locks at the same time
4706
Slave_log_event::Slave_log_event(THD* thd_arg,
4707
Relay_log_info* rli)
4708
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
4710
if (!rli->inited) // QQ When can this happen ?
4713
Master_info* mi = rli->mi;
4714
// TODO: re-write this better without holding both locks at the same time
4715
pthread_mutex_lock(&mi->data_lock);
4716
pthread_mutex_lock(&rli->data_lock);
4717
master_host_len = strlen(mi->host);
4718
master_log_len = strlen(rli->group_master_log_name);
4719
// on OOM, just do not initialize the structure and print the error
4720
if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
4723
master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
4724
memcpy(master_host, mi->host, master_host_len + 1);
4725
master_log = master_host + master_host_len + 1;
4726
memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
4727
master_port = mi->port;
4728
master_pos = rli->group_master_log_pos;
4731
sql_print_error(_("Out of memory while recording slave event"));
4732
pthread_mutex_unlock(&rli->data_lock);
4733
pthread_mutex_unlock(&mi->data_lock);
4736
#endif /* !DRIZZLE_CLIENT */
4739
Slave_log_event::~Slave_log_event()
4741
my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
4745
#ifdef DRIZZLE_CLIENT
4746
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4748
Write_on_release_cache cache(&print_event_info->head_cache, file);
4751
if (print_event_info->short_form)
4753
print_header(&cache, print_event_info, false);
4754
my_b_printf(&cache, "\n\
4755
Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
4756
master_host, master_port, master_log, llstr(master_pos, llbuff));
4758
#endif /* DRIZZLE_CLIENT */
4761
int Slave_log_event::get_data_size()
4763
return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
4767
#ifndef DRIZZLE_CLIENT
4768
bool Slave_log_event::write(IO_CACHE* file)
4770
ulong event_length= get_data_size();
4771
int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
4772
int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
4773
// log and host are already there
4775
return (write_header(file, event_length) ||
4776
my_b_safe_write(file, (uchar*) mem_pool, event_length));
4781
void Slave_log_event::init_from_mem_pool(int data_size)
4783
master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
4784
master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
4785
master_host = mem_pool + SL_MASTER_HOST_OFFSET;
4786
master_host_len = strlen(master_host);
4788
master_log = master_host + master_host_len + 1;
4789
if (master_log > mem_pool + data_size)
4794
master_log_len = strlen(master_log);
4798
/** This code is not used, so has not been updated to be format-tolerant. */
4799
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
4800
:Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
4802
if (event_len < LOG_EVENT_HEADER_LEN)
4804
event_len -= LOG_EVENT_HEADER_LEN;
4805
if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
4807
memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
4808
mem_pool[event_len] = 0;
4809
init_from_mem_pool(event_len);
4813
#ifndef DRIZZLE_CLIENT
4814
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4816
if (mysql_bin_log.is_open())
4817
mysql_bin_log.write(this);
4820
#endif /* !DRIZZLE_CLIENT */
4823
/**************************************************************************
4824
Stop_log_event methods
4825
**************************************************************************/
4828
Stop_log_event::print()
4831
#ifdef DRIZZLE_CLIENT
4832
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4834
Write_on_release_cache cache(&print_event_info->head_cache, file,
4835
Write_on_release_cache::FLUSH_F);
4837
if (print_event_info->short_form)
4840
print_header(&cache, print_event_info, false);
4841
my_b_printf(&cache, "\tStop\n");
4843
#endif /* DRIZZLE_CLIENT */
4846
#ifndef DRIZZLE_CLIENT
4848
The master stopped. We used to clean up all temporary tables but
4849
this is useless as, as the master has shut down properly, it has
4850
written all DROP TEMPORARY Table (prepared statements' deletion is
4851
TODO only when we binlog prep stmts). We used to clean up
4852
slave_load_tmpdir, but this is useless as it has been cleared at the
4853
end of LOAD DATA INFILE. So we have nothing to do here. The place
4854
were we must do this cleaning is in
4855
Start_log_event_v3::do_apply_event(), not here. Because if we come
4856
here, the master was sane.
4858
int Stop_log_event::do_update_pos(Relay_log_info *rli)
4861
We do not want to update master_log pos because we get a rotate event
4862
before stop, so by now group_master_log_name is set to the next log.
4863
If we updated it, we will have incorrect master coordinates and this
4864
could give false triggers in MASTER_POS_WAIT() that we have reached
4865
the target position when in fact we have not.
4867
if (thd->options & OPTION_BEGIN)
4868
rli->inc_event_relay_log_pos();
4871
rli->inc_group_relay_log_pos(0);
4872
flush_relay_log_info(rli);
4877
#endif /* !DRIZZLE_CLIENT */
4878
#endif /* HAVE_REPLICATION */
4881
/**************************************************************************
4882
Create_file_log_event methods
4883
**************************************************************************/
4886
Create_file_log_event ctor
4889
#ifndef DRIZZLE_CLIENT
4890
Create_file_log_event::
4891
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
4892
const char* db_arg, const char* table_name_arg,
4893
List<Item>& fields_arg, enum enum_duplicates handle_dup,
4895
uchar* block_arg, uint block_len_arg, bool using_trans)
4896
:Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
4898
fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
4899
file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
4901
sql_ex.force_new_format();
4907
Create_file_log_event::write_data_body()
4910
bool Create_file_log_event::write_data_body(IO_CACHE* file)
4913
if ((res= Load_log_event::write_data_body(file)) || fake_base)
4915
return (my_b_safe_write(file, (uchar*) "", 1) ||
4916
my_b_safe_write(file, (uchar*) block, block_len));
4921
Create_file_log_event::write_data_header()
4924
bool Create_file_log_event::write_data_header(IO_CACHE* file)
4927
uchar buf[CREATE_FILE_HEADER_LEN];
4928
if ((res= Load_log_event::write_data_header(file)) || fake_base)
4930
int4store(buf + CF_FILE_ID_OFFSET, file_id);
4931
return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
4936
Create_file_log_event::write_base()
4939
bool Create_file_log_event::write_base(IO_CACHE* file)
4942
fake_base= 1; // pretend we are Load event
4948
#endif /* !DRIZZLE_CLIENT */
4951
Create_file_log_event ctor
4954
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
4955
const Format_description_log_event* description_event)
4956
:Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
4959
uint header_len= description_event->common_header_len;
4960
uint8_t load_header_len= description_event->post_header_len[LOAD_EVENT-1];
4961
uint8_t create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
4962
if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
4963
copy_log_event(event_buf,len,
4964
((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
4965
load_header_len + header_len :
4966
(fake_base ? (header_len+load_header_len) :
4967
(header_len+load_header_len) +
4968
create_file_header_len)),
4971
if (description_event->binlog_version!=1)
4973
file_id= uint4korr(buf +
4975
load_header_len + CF_FILE_ID_OFFSET);
4977
Note that it's ok to use get_data_size() below, because it is computed
4978
with values we have already read from this event (because we called
4979
copy_log_event()); we are not using slave's format info to decode
4980
master's format, we are really using master's format info.
4981
Anyway, both formats should be identical (except the common_header_len)
4982
as these Load events are not changed between 4.0 and 5.0 (as logging of
4983
LOAD DATA INFILE does not use Load_log_event in 5.0).
4985
The + 1 is for \0 terminating fname
4987
block_offset= (description_event->common_header_len +
4988
Load_log_event::get_data_size() +
4989
create_file_header_len + 1);
4990
if (len < block_offset)
4992
block = (uchar*)buf + block_offset;
4993
block_len = len - block_offset;
4997
sql_ex.force_new_format();
4998
inited_from_old = 1;
5005
Create_file_log_event::print()
5008
#ifdef DRIZZLE_CLIENT
5009
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
5012
Write_on_release_cache cache(&print_event_info->head_cache, file);
5014
if (print_event_info->short_form)
5016
if (enable_local && check_fname_outside_temp_buf())
5017
Load_log_event::print(file, print_event_info);
5023
Load_log_event::print(file, print_event_info,
5024
!check_fname_outside_temp_buf());
5026
That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
5027
SHOW BINLOG EVENTS we don't.
5029
my_b_printf(&cache, "#");
5032
my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
5036
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5038
print(file, print_event_info, 0);
5040
#endif /* DRIZZLE_CLIENT */
5044
Create_file_log_event::pack_info()
5047
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5048
void Create_file_log_event::pack_info(Protocol *protocol)
5050
char buf[NAME_LEN*2 + 30 + 21*2], *pos;
5051
pos= stpcpy(buf, "db=");
5052
memcpy(pos, db, db_len);
5053
pos= stpcpy(pos + db_len, ";table=");
5054
memcpy(pos, table_name, table_name_len);
5055
pos= stpcpy(pos + table_name_len, ";file_id=");
5056
pos= int10_to_str((long) file_id, pos, 10);
5057
pos= stpcpy(pos, ";block_len=");
5058
pos= int10_to_str((long) block_len, pos, 10);
5059
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5061
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5065
Create_file_log_event::do_apply_event()
5068
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5069
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
5071
char proc_info[17+FN_REFLEN+10], *fname_buf;
5077
memset(&file, 0, sizeof(file));
5078
fname_buf= stpcpy(proc_info, "Making temp file ");
5079
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
5080
thd_proc_info(thd, proc_info);
5081
my_delete(fname_buf, MYF(0)); // old copy may exist already
5082
if ((fd= my_create(fname_buf, CREATE_MODE,
5083
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5084
MYF(MY_WME))) < 0 ||
5085
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
5086
MYF(MY_WME|MY_NABP)))
5088
rli->report(ERROR_LEVEL, my_errno,
5089
"Error in Create_file event: could not open file '%s'",
5094
// a trick to avoid allocating another buffer
5096
fname_len= (uint) (stpcpy(ext, ".data") - fname);
5097
if (write_base(&file))
5099
stpcpy(ext, ".info"); // to have it right in the error message
5100
rli->report(ERROR_LEVEL, my_errno,
5101
"Error in Create_file event: could not write to file '%s'",
5105
end_io_cache(&file);
5106
my_close(fd, MYF(0));
5108
// fname_buf now already has .data, not .info, because we did our trick
5109
my_delete(fname_buf, MYF(0)); // old copy may exist already
5110
if ((fd= my_create(fname_buf, CREATE_MODE,
5111
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5114
rli->report(ERROR_LEVEL, my_errno,
5115
"Error in Create_file event: could not open file '%s'",
5119
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
5121
rli->report(ERROR_LEVEL, my_errno,
5122
"Error in Create_file event: write to '%s' failed",
5126
error=0; // Everything is ok
5130
end_io_cache(&file);
5132
my_close(fd, MYF(0));
5133
thd_proc_info(thd, 0);
5136
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5139
/**************************************************************************
5140
Append_block_log_event methods
5141
**************************************************************************/
5144
Append_block_log_event ctor
5147
#ifndef DRIZZLE_CLIENT
5148
Append_block_log_event::Append_block_log_event(THD *thd_arg,
5153
:Log_event(thd_arg,0, using_trans), block(block_arg),
5154
block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
5161
Append_block_log_event ctor
5164
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
5165
const Format_description_log_event* description_event)
5166
:Log_event(buf, description_event),block(0)
5168
uint8_t common_header_len= description_event->common_header_len;
5169
uint8_t append_block_header_len=
5170
description_event->post_header_len[APPEND_BLOCK_EVENT-1];
5171
uint total_header_len= common_header_len+append_block_header_len;
5172
if (len < total_header_len)
5174
file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
5175
block= (uchar*)buf + total_header_len;
5176
block_len= len - total_header_len;
5182
Append_block_log_event::write()
5185
#ifndef DRIZZLE_CLIENT
5186
bool Append_block_log_event::write(IO_CACHE* file)
5188
uchar buf[APPEND_BLOCK_HEADER_LEN];
5189
int4store(buf + AB_FILE_ID_OFFSET, file_id);
5190
return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
5191
my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
5192
my_b_safe_write(file, (uchar*) block, block_len));
5198
Append_block_log_event::print()
5201
#ifdef DRIZZLE_CLIENT
5202
void Append_block_log_event::print(FILE* file,
5203
PRINT_EVENT_INFO* print_event_info)
5205
Write_on_release_cache cache(&print_event_info->head_cache, file);
5207
if (print_event_info->short_form)
5209
print_header(&cache, print_event_info, false);
5210
my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
5211
get_type_str(), file_id, block_len);
5213
#endif /* DRIZZLE_CLIENT */
5217
Append_block_log_event::pack_info()
5220
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5221
void Append_block_log_event::pack_info(Protocol *protocol)
5225
length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
5227
protocol->store(buf, length, &my_charset_bin);
5232
Append_block_log_event::get_create_or_append()
5235
int Append_block_log_event::get_create_or_append() const
5237
return 0; /* append to the file, fail if not exists */
5241
Append_block_log_event::do_apply_event()
5244
int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
5246
char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
5250
fname= stpcpy(proc_info, "Making temp file ");
5251
slave_load_file_stem(fname, file_id, server_id, ".data");
5252
thd_proc_info(thd, proc_info);
5253
if (get_create_or_append())
5255
my_delete(fname, MYF(0)); // old copy may exist already
5256
if ((fd= my_create(fname, CREATE_MODE,
5257
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5260
rli->report(ERROR_LEVEL, my_errno,
5261
"Error in %s event: could not create file '%s'",
5262
get_type_str(), fname);
5266
else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
5269
rli->report(ERROR_LEVEL, my_errno,
5270
"Error in %s event: could not open file '%s'",
5271
get_type_str(), fname);
5274
if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
5276
rli->report(ERROR_LEVEL, my_errno,
5277
"Error in %s event: write to '%s' failed",
5278
get_type_str(), fname);
5285
my_close(fd, MYF(0));
5286
thd_proc_info(thd, 0);
5292
/**************************************************************************
5293
Delete_file_log_event methods
5294
**************************************************************************/
5297
Delete_file_log_event ctor
5300
#ifndef DRIZZLE_CLIENT
5301
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
5303
:Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
5309
Delete_file_log_event ctor
5312
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
5313
const Format_description_log_event* description_event)
5314
:Log_event(buf, description_event),file_id(0)
5316
uint8_t common_header_len= description_event->common_header_len;
5317
uint8_t delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
5318
if (len < (uint)(common_header_len + delete_file_header_len))
5320
file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
5325
Delete_file_log_event::write()
5328
#ifndef DRIZZLE_CLIENT
5329
bool Delete_file_log_event::write(IO_CACHE* file)
5331
uchar buf[DELETE_FILE_HEADER_LEN];
5332
int4store(buf + DF_FILE_ID_OFFSET, file_id);
5333
return (write_header(file, sizeof(buf)) ||
5334
my_b_safe_write(file, buf, sizeof(buf)));
5340
Delete_file_log_event::print()
5343
#ifdef DRIZZLE_CLIENT
5344
void Delete_file_log_event::print(FILE* file,
5345
PRINT_EVENT_INFO* print_event_info)
5347
Write_on_release_cache cache(&print_event_info->head_cache, file);
5349
if (print_event_info->short_form)
5351
print_header(&cache, print_event_info, false);
5352
my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
5354
#endif /* DRIZZLE_CLIENT */
5357
Delete_file_log_event::pack_info()
5360
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5361
void Delete_file_log_event::pack_info(Protocol *protocol)
5365
length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
5366
protocol->store(buf, (int32_t) length, &my_charset_bin);
5371
Delete_file_log_event::do_apply_event()
5374
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5375
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
5377
char fname[FN_REFLEN+10];
5378
char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
5379
(void) my_delete(fname, MYF(MY_WME));
5380
stpcpy(ext, ".info");
5381
(void) my_delete(fname, MYF(MY_WME));
5384
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5387
/**************************************************************************
5388
Execute_load_log_event methods
5389
**************************************************************************/
5392
Execute_load_log_event ctor
5395
#ifndef DRIZZLE_CLIENT
5396
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
5399
:Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
5406
Execute_load_log_event ctor
5409
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
5410
const Format_description_log_event* description_event)
5411
:Log_event(buf, description_event), file_id(0)
5413
uint8_t common_header_len= description_event->common_header_len;
5414
uint8_t exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
5415
if (len < (uint)(common_header_len+exec_load_header_len))
5417
file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
5422
Execute_load_log_event::write()
5425
#ifndef DRIZZLE_CLIENT
5426
bool Execute_load_log_event::write(IO_CACHE* file)
5428
uchar buf[EXEC_LOAD_HEADER_LEN];
5429
int4store(buf + EL_FILE_ID_OFFSET, file_id);
5430
return (write_header(file, sizeof(buf)) ||
5431
my_b_safe_write(file, buf, sizeof(buf)));
5437
Execute_load_log_event::print()
5440
#ifdef DRIZZLE_CLIENT
5441
void Execute_load_log_event::print(FILE* file,
5442
PRINT_EVENT_INFO* print_event_info)
5444
Write_on_release_cache cache(&print_event_info->head_cache, file);
5446
if (print_event_info->short_form)
5448
print_header(&cache, print_event_info, false);
5449
my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
5455
Execute_load_log_event::pack_info()
5458
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5459
void Execute_load_log_event::pack_info(Protocol *protocol)
5463
length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
5464
protocol->store(buf, (int32_t) length, &my_charset_bin);
5469
Execute_load_log_event::do_apply_event()
5472
int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
5474
char fname[FN_REFLEN+10];
5479
Load_log_event *lev= 0;
5481
ext= slave_load_file_stem(fname, file_id, server_id, ".info");
5482
if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
5483
MYF(MY_WME))) < 0 ||
5484
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
5485
MYF(MY_WME|MY_NABP)))
5487
rli->report(ERROR_LEVEL, my_errno,
5488
"Error in Exec_load event: could not open file '%s'",
5492
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
5493
(pthread_mutex_t*)0,
5494
rli->relay_log.description_event_for_exec)) ||
5495
lev->get_type_code() != NEW_LOAD_EVENT)
5497
rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
5498
"file '%s' appears corrupted", fname);
5504
lev->do_apply_event should use rli only for errors i.e. should
5505
not advance rli's position.
5507
lev->do_apply_event is the place where the table is loaded (it
5508
calls mysql_load()).
5511
const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
5512
if (lev->do_apply_event(0,rli,1))
5515
We want to indicate the name of the file that could not be loaded
5517
But as we are here we are sure the error is in rli->last_slave_error and
5518
rli->last_slave_errno (example of error: duplicate entry for key), so we
5519
don't want to overwrite it with the filename.
5520
What we want instead is add the filename to the current error message.
5522
char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
5525
rli->report(ERROR_LEVEL, rli->last_error().number,
5526
"%s. Failed executing load from '%s'", tmp, fname);
5527
my_free(tmp,MYF(0));
5532
We have an open file descriptor to the .info file; we need to close it
5533
or Windows will refuse to delete the file in my_delete().
5537
my_close(fd, MYF(0));
5538
end_io_cache(&file);
5541
(void) my_delete(fname, MYF(MY_WME));
5542
memcpy(ext, ".data", 6);
5543
(void) my_delete(fname, MYF(MY_WME));
5550
my_close(fd, MYF(0));
5551
end_io_cache(&file);
5556
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5559
/**************************************************************************
5560
Begin_load_query_log_event methods
5561
**************************************************************************/
5563
#ifndef DRIZZLE_CLIENT
5564
Begin_load_query_log_event::
5565
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
5566
uint block_len_arg, bool using_trans)
5567
:Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
5570
file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
5575
Begin_load_query_log_event::
5576
Begin_load_query_log_event(const char* buf, uint len,
5577
const Format_description_log_event* desc_event)
5578
:Append_block_log_event(buf, len, desc_event)
5583
#if defined( HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5584
int Begin_load_query_log_event::get_create_or_append() const
5586
return 1; /* create the file */
5588
#endif /* defined( HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5591
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
5592
Log_event::enum_skip_reason
5593
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
5596
If the slave skip counter is 1, then we should not start executing
5599
return continue_group(rli);
5604
/**************************************************************************
5605
Execute_load_query_log_event methods
5606
**************************************************************************/
5609
#ifndef DRIZZLE_CLIENT
5610
Execute_load_query_log_event::
5611
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
5612
ulong query_length_arg, uint fn_pos_start_arg,
5613
uint fn_pos_end_arg,
5614
enum_load_dup_handling dup_handling_arg,
5615
bool using_trans, bool suppress_use,
5616
THD::killed_state killed_err_arg):
5617
Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
5618
suppress_use, killed_err_arg),
5619
file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
5620
fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
5623
#endif /* !DRIZZLE_CLIENT */
5626
Execute_load_query_log_event::
5627
Execute_load_query_log_event(const char* buf, uint event_len,
5628
const Format_description_log_event* desc_event):
5629
Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
5630
file_id(0), fn_pos_start(0), fn_pos_end(0)
5632
if (!Query_log_event::is_valid())
5635
buf+= desc_event->common_header_len;
5637
fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
5638
fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
5639
dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
5641
if (fn_pos_start > q_len || fn_pos_end > q_len ||
5642
dup_handling > LOAD_DUP_REPLACE)
5645
file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
5649
ulong Execute_load_query_log_event::get_post_header_size_for_derived()
5651
return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
5655
#ifndef DRIZZLE_CLIENT
5657
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
5659
uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
5660
int4store(buf, file_id);
5661
int4store(buf + 4, fn_pos_start);
5662
int4store(buf + 4 + 4, fn_pos_end);
5663
*(buf + 4 + 4 + 4)= (uchar) dup_handling;
5664
return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
5669
#ifdef DRIZZLE_CLIENT
5670
void Execute_load_query_log_event::print(FILE* file,
5671
PRINT_EVENT_INFO* print_event_info)
5673
print(file, print_event_info, 0);
5677
Prints the query as LOAD DATA LOCAL and with rewritten filename.
5679
void Execute_load_query_log_event::print(FILE* file,
5680
PRINT_EVENT_INFO* print_event_info,
5681
const char *local_fname)
5683
Write_on_release_cache cache(&print_event_info->head_cache, file);
5685
print_query_header(&cache, print_event_info);
5689
my_b_write(&cache, (uchar*) query, fn_pos_start);
5690
my_b_printf(&cache, " LOCAL INFILE \'");
5691
my_b_printf(&cache, local_fname);
5692
my_b_printf(&cache, "\'");
5693
if (dup_handling == LOAD_DUP_REPLACE)
5694
my_b_printf(&cache, " REPLACE");
5695
my_b_printf(&cache, " INTO");
5696
my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
5697
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5701
my_b_write(&cache, (uchar*) query, q_len);
5702
my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5705
if (!print_event_info->short_form)
5706
my_b_printf(&cache, "# file_id: %d \n", file_id);
5711
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5712
void Execute_load_query_log_event::pack_info(Protocol *protocol)
5715
if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
5720
pos= stpcpy(buf, "use `");
5721
memcpy(pos, db, db_len);
5722
pos= stpcpy(pos+db_len, "`; ");
5726
memcpy(pos, query, q_len);
5729
pos= stpcpy(pos, " ;file_id=");
5730
pos= int10_to_str((long) file_id, pos, 10);
5731
protocol->store(buf, pos-buf, &my_charset_bin);
5732
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
5737
Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
5745
buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
5746
(FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
5748
/* Replace filename and LOCAL keyword in query before executing it */
5751
rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5752
ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
5757
memcpy(p, query, fn_pos_start);
5759
fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
5760
p= slave_load_file_stem(p, file_id, server_id, ".data");
5761
fname_end= p= strend(p); // Safer than p=p+5
5763
switch (dup_handling) {
5764
case LOAD_DUP_IGNORE:
5765
p= strmake(p, STRING_WITH_LEN(" IGNORE"));
5767
case LOAD_DUP_REPLACE:
5768
p= strmake(p, STRING_WITH_LEN(" REPLACE"));
5771
/* Ordinary load data */
5774
p= strmake(p, STRING_WITH_LEN(" INTO"));
5775
p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
5777
error= Query_log_event::do_apply_event(rli, buf, p-buf);
5779
/* Forging file name for deletion in same buffer */
5783
If there was an error the slave is going to stop, leave the
5784
file so that we can re-execute this event at START SLAVE.
5787
(void) my_delete(fname, MYF(MY_WME));
5789
my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
5795
/**************************************************************************
5797
**************************************************************************/
5800
sql_ex_info::write_data()
5803
bool sql_ex_info::write_data(IO_CACHE* file)
5807
return (write_str(file, field_term, (uint) field_term_len) ||
5808
write_str(file, enclosed, (uint) enclosed_len) ||
5809
write_str(file, line_term, (uint) line_term_len) ||
5810
write_str(file, line_start, (uint) line_start_len) ||
5811
write_str(file, escaped, (uint) escaped_len) ||
5812
my_b_safe_write(file,(uchar*) &opt_flags,1));
5817
@todo This is sensitive to field padding. We should write a
5818
char[7], not an old_sql_ex. /sven
5821
old_ex.field_term= *field_term;
5822
old_ex.enclosed= *enclosed;
5823
old_ex.line_term= *line_term;
5824
old_ex.line_start= *line_start;
5825
old_ex.escaped= *escaped;
5826
old_ex.opt_flags= opt_flags;
5827
old_ex.empty_flags=empty_flags;
5828
return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
5837
const char *sql_ex_info::init(const char *buf, const char *buf_end,
5838
bool use_new_format)
5840
cached_new_format = use_new_format;
5845
The code below assumes that buf will not disappear from
5846
under our feet during the lifetime of the event. This assumption
5847
holds true in the slave thread if the log is in new format, but is not
5848
the case when we have old format because we will be reusing net buffer
5849
to read the actual file before we write out the Create_file event.
5851
if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
5852
read_str(&buf, buf_end, &enclosed, &enclosed_len) ||
5853
read_str(&buf, buf_end, &line_term, &line_term_len) ||
5854
read_str(&buf, buf_end, &line_start, &line_start_len) ||
5855
read_str(&buf, buf_end, &escaped, &escaped_len))
5861
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
5862
field_term = buf++; // Use first byte in string
5868
empty_flags= *buf++;
5869
if (empty_flags & FIELD_TERM_EMPTY)
5871
if (empty_flags & ENCLOSED_EMPTY)
5873
if (empty_flags & LINE_TERM_EMPTY)
5875
if (empty_flags & LINE_START_EMPTY)
5877
if (empty_flags & ESCAPED_EMPTY)
5884
/**************************************************************************
5885
Rows_log_event member functions
5886
**************************************************************************/
5888
#ifndef DRIZZLE_CLIENT
5889
Rows_log_event::Rows_log_event(THD *thd_arg, Table *tbl_arg, ulong tid,
5890
MY_BITMAP const *cols, bool is_transactional)
5891
: Log_event(thd_arg, 0, is_transactional),
5895
m_width(tbl_arg ? tbl_arg->s->fields : 1),
5896
m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
5897
#ifdef HAVE_REPLICATION
5898
, m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
5902
We allow a special form of dummy event when the table, and cols
5903
are null and the table id is UINT32_MAX. This is a temporary
5904
solution, to be able to terminate a started statement in the
5905
binary log: the extraneous events will be removed in the future.
5907
assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
5909
if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
5910
set_flags(NO_FOREIGN_KEY_CHECKS_F);
5911
if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
5912
set_flags(RELAXED_UNIQUE_CHECKS_F);
5913
/* if bitmap_init fails, caught in is_valid() */
5914
if (likely(!bitmap_init(&m_cols,
5915
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
5919
/* Cols can be zero if this is a dummy binrows event */
5920
if (likely(cols != NULL))
5922
memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
5923
create_last_word_mask(&m_cols);
5928
// Needed because bitmap_init() does not set it to null on failure
5934
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
5935
Log_event_type event_type,
5936
const Format_description_log_event
5938
: Log_event(buf, description_event),
5940
#ifndef DRIZZLE_CLIENT
5943
m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
5944
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
5945
, m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
5948
uint8_t const common_header_len= description_event->common_header_len;
5949
uint8_t const post_header_len= description_event->post_header_len[event_type-1];
5951
const char *post_start= buf + common_header_len;
5952
post_start+= RW_MAPID_OFFSET;
5953
if (post_header_len == 6)
5955
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
5956
m_table_id= uint4korr(post_start);
5961
m_table_id= (ulong) uint6korr(post_start);
5962
post_start+= RW_FLAGS_OFFSET;
5965
m_flags= uint2korr(post_start);
5967
uchar const *const var_start=
5968
(const uchar *)buf + common_header_len + post_header_len;
5969
uchar const *const ptr_width= var_start;
5970
uchar *ptr_after_width= (uchar*) ptr_width;
5971
m_width = net_field_length(&ptr_after_width);
5972
/* if bitmap_init fails, catched in is_valid() */
5973
if (likely(!bitmap_init(&m_cols,
5974
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
5978
memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
5979
create_last_word_mask(&m_cols);
5980
ptr_after_width+= (m_width + 7) / 8;
5984
// Needed because bitmap_init() does not set it to null on failure
5985
m_cols.bitmap= NULL;
5989
m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
5991
if (event_type == UPDATE_ROWS_EVENT)
5993
/* if bitmap_init fails, caught in is_valid() */
5994
if (likely(!bitmap_init(&m_cols_ai,
5995
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
5999
memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
6000
create_last_word_mask(&m_cols_ai);
6001
ptr_after_width+= (m_width + 7) / 8;
6005
// Needed because bitmap_init() does not set it to null on failure
6006
m_cols_ai.bitmap= 0;
6011
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
6013
size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
6015
m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
6016
if (likely((bool)m_rows_buf))
6018
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6019
m_curr_row= m_rows_buf;
6021
m_rows_end= m_rows_buf + data_size;
6022
m_rows_cur= m_rows_end;
6023
memcpy(m_rows_buf, ptr_rows_data, data_size);
6026
m_cols.bitmap= 0; // to not free it
6031
Rows_log_event::~Rows_log_event()
6033
if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
6034
m_cols.bitmap= 0; // so no my_free in bitmap_free
6035
bitmap_free(&m_cols); // To pair with bitmap_init().
6036
my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
6039
int Rows_log_event::get_data_size()
6041
int const type_code= get_type_code();
6043
uchar buf[sizeof(m_width)+1];
6044
uchar *end= net_store_length(buf, (m_width + 7) / 8);
6046
int data_size= ROWS_HEADER_LEN;
6047
data_size+= no_bytes_in_map(&m_cols);
6048
data_size+= end - buf;
6050
if (type_code == UPDATE_ROWS_EVENT)
6051
data_size+= no_bytes_in_map(&m_cols_ai);
6053
data_size+= (m_rows_cur - m_rows_buf);
6058
#ifndef DRIZZLE_CLIENT
6059
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
6062
When the table has a primary key, we would probably want, by default, to
6063
log only the primary key value instead of the entire "before image". This
6064
would save binlog space. TODO
6068
If length is zero, there is nothing to write, so we just
6069
return. Note that this is not an optimization, since calling
6070
realloc() with size 0 means free().
6078
assert(m_rows_buf <= m_rows_cur);
6079
assert(!m_rows_buf || (m_rows_end && m_rows_buf <= m_rows_end));
6080
assert(m_rows_cur <= m_rows_end);
6082
/* The cast will always work since m_rows_cur <= m_rows_end */
6083
if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
6085
size_t const block_size= 1024;
6086
my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
6087
my_ptrdiff_t const new_alloc=
6088
block_size * ((cur_size + length + block_size - 1) / block_size);
6090
uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
6091
MYF(MY_ALLOW_ZERO_PTR|MY_WME));
6092
if (unlikely(!new_buf))
6093
return(HA_ERR_OUT_OF_MEM);
6095
/* If the memory moved, we need to move the pointers */
6096
if (new_buf != m_rows_buf)
6098
m_rows_buf= new_buf;
6099
m_rows_cur= m_rows_buf + cur_size;
6103
The end pointer should always be changed to point to the end of
6104
the allocated memory.
6106
m_rows_end= m_rows_buf + new_alloc;
6109
assert(m_rows_cur + length <= m_rows_end);
6110
memcpy(m_rows_cur, row_data, length);
6111
m_rows_cur+= length;
6117
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6118
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
6122
If m_table_id == UINT32_MAX, then we have a dummy event that does not
6123
contain any data. In that case, we just remove all tables in the
6124
tables_to_lock list, close the thread tables, and return with
6127
if (m_table_id == UINT32_MAX)
6130
This one is supposed to be set: just an extra check so that
6131
nothing strange has happened.
6133
assert(get_flags(STMT_END_F));
6135
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6136
close_thread_tables(thd);
6142
'thd' has been set by exec_relay_log_event(), just before calling
6143
do_apply_event(). We still check here to prevent future coding
6146
assert(rli->sql_thd == thd);
6149
If there is no locks taken, this is the first binrow event seen
6150
after the table map events. We should then lock all the tables
6151
used in the transaction and proceed with execution of the actual
6156
bool need_reopen= 1; /* To execute the first lap of the loop below */
6159
lock_tables() reads the contents of thd->lex, so they must be
6160
initialized. Contrary to in
6161
Table_map_log_event::do_apply_event() we don't call
6162
mysql_init_query() as that may reset the binlog format.
6167
There are a few flags that are replicated with each row event.
6168
Make sure to set/clear them before executing the main body of
6171
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6172
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6174
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6176
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6177
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6179
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6180
/* A small test to verify that objects have consistent types */
6181
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6184
while ((error= lock_tables(thd, rli->tables_to_lock,
6185
rli->tables_to_lock_count, &need_reopen)))
6189
if (thd->is_slave_error || thd->is_fatal_error)
6192
Error reporting borrowed from Query_log_event with many excessive
6193
simplifications (we don't honour --slave-skip-errors)
6195
uint actual_error= thd->main_da.sql_errno();
6196
rli->report(ERROR_LEVEL, actual_error,
6197
"Error '%s' in %s event: when locking tables",
6198
(actual_error ? thd->main_da.message():
6199
"unexpected success or fatal error"),
6201
thd->is_fatal_error= 1;
6205
rli->report(ERROR_LEVEL, error,
6206
"Error in %s event: when locking tables",
6209
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6214
So we need to reopen the tables.
6216
We need to flush the pending RBR event, since it keeps a
6217
pointer to an open table.
6219
ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
6220
the pending RBR event and reset the table pointer after the
6221
tables has been reopened.
6223
NOTE: For this new scheme there should be no pending event:
6224
need to add code to assert that is the case.
6226
thd->binlog_flush_pending_rows_event(false);
6227
TableList *tables= rli->tables_to_lock;
6228
close_tables_for_reopen(thd, &tables);
6230
uint tables_count= rli->tables_to_lock_count;
6231
if ((error= open_tables(thd, &tables, &tables_count, 0)))
6233
if (thd->is_slave_error || thd->is_fatal_error)
6236
Error reporting borrowed from Query_log_event with many excessive
6237
simplifications (we don't honour --slave-skip-errors)
6239
uint actual_error= thd->main_da.sql_errno();
6240
rli->report(ERROR_LEVEL, actual_error,
6241
"Error '%s' on reopening tables",
6242
(actual_error ? thd->main_da.message() :
6243
"unexpected success or fatal error"));
6244
thd->is_slave_error= 1;
6246
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6252
When the open and locking succeeded, we check all tables to
6253
ensure that they still have the correct type.
6255
We can use a down cast here since we know that every table added
6256
to the tables_to_lock is a RPL_TableList.
6260
RPL_TableList *ptr= rli->tables_to_lock;
6261
for ( ; ptr ; ptr= static_cast<RPL_TableList*>(ptr->next_global))
6263
if (ptr->m_tabledef.compatible_with(rli, ptr->table))
6265
mysql_unlock_tables(thd, thd->lock);
6267
thd->is_slave_error= 1;
6268
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6269
return(ERR_BAD_TABLE_DEF);
6275
... and then we add all the tables to the table map and remove
6276
them from tables to lock.
6278
We also invalidate the query cache for all the tables, since
6279
they will now be changed.
6281
TODO [/Matz]: Maybe the query cache should not be invalidated
6282
here? It might be that a table is not changed, even though it
6283
was locked for the statement. We do know that each
6284
Rows_log_event contain at least one row, so after processing one
6285
Rows_log_event, we can invalidate the query cache for the
6288
for (TableList *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
6290
const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
6296
m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
6301
table == NULL means that this table should not be replicated
6302
(this was set up by Table_map_log_event::do_apply_event()
6303
which tested replicate-* rules).
6307
It's not needed to set_time() but
6308
1) it continues the property that "Time" in SHOW PROCESSLIST shows how
6309
much slave is behind
6310
2) it will be needed when we allow replication from a table with no
6311
TIMESTAMP column to a table with one.
6312
So we call set_time(), like in SBR. Presently it changes nothing.
6314
thd->set_time((time_t)when);
6316
There are a few flags that are replicated with each row event.
6317
Make sure to set/clear them before executing the main body of
6320
if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6321
thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6323
thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6325
if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6326
thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6328
thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6330
if (slave_allow_batching)
6331
thd->options|= OPTION_ALLOW_BATCH;
6333
thd->options&= ~OPTION_ALLOW_BATCH;
6335
/* A small test to verify that objects have consistent types */
6336
assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6339
Now we are in a statement and will stay in a statement until we
6342
We set this flag here, before actually applying any rows, in
6343
case the SQL thread is stopped and we need to detect that we're
6344
inside a statement and halting abruptly might cause problems
6347
const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
6349
if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
6350
set_flags(COMPLETE_ROWS_F);
6353
Set tables write and read sets.
6355
Read_set contains all slave columns (in case we are going to fetch
6356
a complete record from slave)
6358
Write_set equals the m_cols bitmap sent from master but it can be
6359
longer if slave has extra columns.
6362
bitmap_set_all(table->read_set);
6363
bitmap_set_all(table->write_set);
6364
if (!get_flags(COMPLETE_ROWS_F))
6365
bitmap_intersect(table->write_set,&m_cols);
6367
this->slave_exec_mode= slave_exec_mode_options; // fix the mode
6369
// Do event specific preparations
6370
error= do_before_row_operations(rli);
6372
// row processing loop
6374
while (error == 0 && m_curr_row < m_rows_end)
6376
/* in_use can have been set to NULL in close_tables_for_reopen */
6377
THD* old_thd= table->in_use;
6381
error= do_exec_row(rli);
6383
table->in_use = old_thd;
6389
The following list of "idempotent" errors
6390
means that an error from the list might happen
6391
because of idempotent (more than once)
6392
applying of a binlog file.
6393
Notice, that binlog has a ddl operation its
6394
second applying may cause
6396
case HA_ERR_TABLE_DEF_CHANGED:
6397
case HA_ERR_CANNOT_ADD_FOREIGN:
6399
which are not included into to the list.
6401
case HA_ERR_RECORD_CHANGED:
6402
case HA_ERR_RECORD_DELETED:
6403
case HA_ERR_KEY_NOT_FOUND:
6404
case HA_ERR_END_OF_FILE:
6405
case HA_ERR_FOUND_DUPP_KEY:
6406
case HA_ERR_FOUND_DUPP_UNIQUE:
6407
case HA_ERR_FOREIGN_DUPLICATE_KEY:
6408
case HA_ERR_NO_REFERENCED_ROW:
6409
case HA_ERR_ROW_IS_REFERENCED:
6410
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
6412
if (global_system_variables.log_warnings)
6413
slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
6415
RPL_LOG_NAME, (ulong) log_pos);
6421
thd->is_slave_error= 1;
6426
If m_curr_row_end was not set during event execution (e.g., because
6427
of errors) we can't proceed to the next row. If the error is transient
6428
(i.e., error==0 at this point) we must call unpack_current_row() to set
6431
if (!m_curr_row_end && !error)
6432
unpack_current_row(rli, &m_cols);
6434
// at this moment m_curr_row_end should be set
6435
assert(error || m_curr_row_end != NULL);
6436
assert(error || m_curr_row < m_curr_row_end);
6437
assert(error || m_curr_row_end <= m_rows_end);
6439
m_curr_row= m_curr_row_end;
6441
} // row processing loop
6443
error= do_after_row_operations(rli, error);
6446
thd->options|= OPTION_KEEP_LOG;
6451
We need to delay this clear until here bacause unpack_current_row() uses
6452
master-side table definitions stored in rli.
6454
if (rli->tables_to_lock && get_flags(STMT_END_F))
6455
const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6456
/* reset OPTION_ALLOW_BATCH as not affect later events */
6457
thd->options&= ~OPTION_ALLOW_BATCH;
6460
{ /* error has occured during the transaction */
6461
slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
6462
get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
6467
If one day we honour --skip-slave-errors in row-based replication, and
6468
the error should be skipped, then we would clear mappings, rollback,
6469
close tables, but the slave SQL thread would not stop and then may
6470
assume the mapping is still available, the tables are still open...
6471
So then we should clear mappings/rollback/close here only if this is a
6473
For now we code, knowing that error is not skippable and so slave SQL
6474
thread is certainly going to stop.
6475
rollback at the caller along with sbr.
6477
thd->reset_current_stmt_binlog_row_based();
6478
const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
6479
thd->is_slave_error= 1;
6484
This code would ideally be placed in do_update_pos() instead, but
6485
since we have no access to table there, we do the setting of
6486
last_event_start_time here instead.
6488
if (table && (table->s->primary_key == MAX_KEY) &&
6489
!cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS)
6492
------------ Temporary fix until WL#2975 is implemented ---------
6494
This event is not the last one (no STMT_END_F). If we stop now
6495
(in case of terminate_slave_thread()), how will we restart? We
6496
have to restart from Table_map_log_event, but as this table is
6497
not transactional, the rows already inserted will still be
6498
present, and idempotency is not guaranteed (no PK) so we risk
6499
that repeating leads to double insert. So we desperately try to
6500
continue, hope we'll eventually leave this buggy situation (by
6501
executing the final Rows_log_event). If we are in a hopeless
6502
wait (reached end of last relay log and nothing gets appended
6503
there), we timeout after one minute, and notify DBA about the
6504
problem. When WL#2975 is implemented, just remove the member
6505
Relay_log_info::last_event_start_time and all its occurrences.
6507
const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
6513
Log_event::enum_skip_reason
6514
Rows_log_event::do_shall_skip(Relay_log_info *rli)
6517
If the slave skip counter is 1 and this event does not end a
6518
statement, then we should not start executing on the next event.
6519
Otherwise, we defer the decision to the normal skipping logic.
6521
if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
6522
return Log_event::EVENT_SKIP_IGNORE;
6524
return Log_event::do_shall_skip(rli);
6528
Rows_log_event::do_update_pos(Relay_log_info *rli)
6532
if (get_flags(STMT_END_F))
6535
This is the end of a statement or transaction, so close (and
6536
unlock) the tables we opened when processing the
6537
Table_map_log_event starting the statement.
6539
OBSERVER. This will clear *all* mappings, not only those that
6540
are open for the table. There is not good handle for on-close
6543
NOTE. Even if we have no table ('table' == 0) we still need to be
6544
here, so that we increase the group relay log position. If we didn't, we
6545
could have a group relay log position which lags behind "forever"
6546
(assume the last master's transaction is ignored by the slave because of
6547
replicate-ignore rules).
6549
thd->binlog_flush_pending_rows_event(true);
6552
If this event is not in a transaction, the call below will, if some
6553
transactional storage engines are involved, commit the statement into
6554
them and flush the pending event to binlog.
6555
If this event is in a transaction, the call will do nothing, but a
6556
Xid_log_event will come next which will, if some transactional engines
6557
are involved, commit the transaction and flush the pending event to the
6560
error= ha_autocommit_or_rollback(thd, 0);
6563
Now what if this is not a transactional engine? we still need to
6564
flush the pending event to the binlog; we did it with
6565
thd->binlog_flush_pending_rows_event(). Note that we imitate
6566
what is done for real queries: a call to
6567
ha_autocommit_or_rollback() (sometimes only if involves a
6568
transactional engine), and a call to be sure to have the pending
6572
thd->reset_current_stmt_binlog_row_based();
6574
rli->cleanup_context(thd, 0);
6578
Indicate that a statement is finished.
6579
Step the group log position if we are not in a transaction,
6580
otherwise increase the event log position.
6582
rli->stmt_done(log_pos, when);
6585
Clear any errors pushed in thd->net.last_err* if for example "no key
6586
found" (as this is allowed). This is a safety measure; apparently
6587
those errors (e.g. when executing a Delete_rows_log_event of a
6588
non-existing row, like in rpl_row_mystery22.test,
6589
thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
6590
do not become visible. We still prefer to wipe them out.
6595
rli->report(ERROR_LEVEL, error,
6596
"Error in %s event: commit of row events failed, "
6598
get_type_str(), m_table->s->db.str,
6599
m_table->s->table_name.str);
6603
rli->inc_event_relay_log_pos();
6609
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
6611
#ifndef DRIZZLE_CLIENT
6612
bool Rows_log_event::write_data_header(IO_CACHE *file)
6614
uchar buf[ROWS_HEADER_LEN]; // No need to init the buffer
6615
assert(m_table_id != UINT32_MAX);
6616
int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
6617
int2store(buf + RW_FLAGS_OFFSET, m_flags);
6618
return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
6621
bool Rows_log_event::write_data_body(IO_CACHE*file)
6624
Note that this should be the number of *bits*, not the number of
6627
uchar sbuf[sizeof(m_width)];
6628
my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
6630
uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
6631
assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
6633
res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
6635
res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
6636
no_bytes_in_map(&m_cols));
6638
TODO[refactor write]: Remove the "down cast" here (and elsewhere).
6640
if (get_type_code() == UPDATE_ROWS_EVENT)
6642
res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
6643
no_bytes_in_map(&m_cols_ai));
6645
res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
6652
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
6653
void Rows_log_event::pack_info(Protocol *protocol)
6656
char const *const flagstr=
6657
get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
6658
size_t bytes= snprintf(buf, sizeof(buf),
6659
"table_id: %lu%s", m_table_id, flagstr);
6660
protocol->store(buf, bytes, &my_charset_bin);
6664
#ifdef DRIZZLE_CLIENT
6665
void Rows_log_event::print_helper(FILE *file,
6666
PRINT_EVENT_INFO *print_event_info,
6667
char const *const name)
6669
IO_CACHE *const head= &print_event_info->head_cache;
6670
IO_CACHE *const body= &print_event_info->body_cache;
6671
if (!print_event_info->short_form)
6673
bool const last_stmt_event= get_flags(STMT_END_F);
6674
print_header(head, print_event_info, !last_stmt_event);
6675
my_b_printf(head, "\t%s: table id %lu%s\n",
6677
last_stmt_event ? " flags: STMT_END_F" : "");
6678
print_base64(body, print_event_info, !last_stmt_event);
6681
if (get_flags(STMT_END_F))
6683
copy_event_cache_to_file_and_reinit(head, file);
6684
copy_event_cache_to_file_and_reinit(body, file);
6689
/**************************************************************************
6690
Table_map_log_event member functions and support functions
6691
**************************************************************************/
6694
@page How replication of field metadata works.
6696
When a table map is created, the master first calls
6697
Table_map_log_event::save_field_metadata() which calculates how many
6698
values will be in the field metadata. Only those fields that require the
6699
extra data are added. The method also loops through all of the fields in
6700
the table calling the method Field::save_field_metadata() which returns the
6701
values for the field that will be saved in the metadata and replicated to
6702
the slave. Once all fields have been processed, the table map is written to
6703
the binlog adding the size of the field metadata and the field metadata to
6704
the end of the body of the table map.
6706
When a table map is read on the slave, the field metadata is read from the
6707
table map and passed to the table_def class constructor which saves the
6708
field metadata from the table map into an array based on the type of the
6709
field. Field metadata values not present (those fields that do not use extra
6710
data) in the table map are initialized as zero (0). The array size is the
6711
same as the columns for the table on the slave.
6713
Additionally, values saved for field metadata on the master are saved as a
6714
string of bytes (uchar) in the binlog. A field may require 1 or more bytes
6715
to store the information. In cases where values require multiple bytes
6716
(e.g. values > 255), the endian-safe methods are used to properly encode
6717
the values on the master and decode them on the slave. When the field
6718
metadata values are captured on the slave, they are stored in an array of
6719
type uint16_t. This allows the least number of casts to prevent casting bugs
6720
when the field metadata is used in comparisons of field attributes. When
6721
the field metadata is used for calculating addresses in pointer math, the
6722
type used is uint32_t.
6725
#if !defined(DRIZZLE_CLIENT)
6727
Save the field metadata based on the real_type of the field.
6728
The metadata saved depends on the type of the field. Some fields
6729
store a single byte for pack_length() while others store two bytes
6730
for field_length (max length).
6735
We may want to consider changing the encoding of the information.
6736
Currently, the code attempts to minimize the number of bytes written to
6737
the tablemap. There are at least two other alternatives; 1) using
6738
net_store_length() to store the data allowing it to choose the number of
6739
bytes that are appropriate thereby making the code much easier to
6740
maintain (only 1 place to change the encoding), or 2) use a fixed number
6741
of bytes for each field. The problem with option 1 is that net_store_length()
6742
will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
6743
for fields like CHAR which can be no larger than 255 characters, the method
6744
will use 3 bytes when the value is > 250. Further, every value that is
6745
encoded using 2 parts (e.g., pack_length, field_length) will be numerically
6746
> 250 therefore will use 3 bytes for eah value. The problem with option 2
6747
is less wasteful for space but does waste 1 byte for every field that does
6750
int Table_map_log_event::save_field_metadata()
6753
for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
6754
index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
6757
#endif /* !defined(DRIZZLE_CLIENT) */
6760
Constructor used to build an event for writing to the binary log.
6761
Mats says tbl->s lives longer than this event so it's ok to copy pointers
6762
(tbl->s->db etc) and not pointer content.
6764
#if !defined(DRIZZLE_CLIENT)
6765
Table_map_log_event::Table_map_log_event(THD *thd, Table *tbl, ulong tid,
6766
bool is_transactional __attribute__((unused)),
6768
: Log_event(thd, 0, true),
6770
m_dbnam(tbl->s->db.str),
6771
m_dblen(m_dbnam ? tbl->s->db.length : 0),
6772
m_tblnam(tbl->s->table_name.str),
6773
m_tbllen(tbl->s->table_name.length),
6774
m_colcnt(tbl->s->fields),
6779
m_field_metadata(0),
6780
m_field_metadata_size(0),
6784
assert(m_table_id != UINT32_MAX);
6786
In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
6787
table.cc / alloc_table_share():
6788
Use the fact the key is db/0/table_name/0
6789
As we rely on this let's assert it.
6791
assert((tbl->s->db.str == 0) ||
6792
(tbl->s->db.str[tbl->s->db.length] == 0));
6793
assert(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
6796
m_data_size= TABLE_MAP_HEADER_LEN;
6797
m_data_size+= m_dblen + 2; // Include length and terminating \0
6798
m_data_size+= m_tbllen + 2; // Include length and terminating \0
6799
m_data_size+= 1 + m_colcnt; // COLCNT and column types
6801
/* If malloc fails, caught in is_valid() */
6802
if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
6804
m_coltype= reinterpret_cast<uchar*>(m_memory);
6805
for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
6806
m_coltype[i]= m_table->field[i]->type();
6810
Calculate a bitmap for the results of maybe_null() for all columns.
6811
The bitmap is used to determine when there is a column from the master
6812
that is not on the slave and is null and thus not in the row data during
6815
uint num_null_bytes= (m_table->s->fields + 7) / 8;
6816
m_data_size+= num_null_bytes;
6817
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
6818
&m_null_bits, num_null_bytes,
6819
&m_field_metadata, (m_colcnt * 2),
6822
memset(m_field_metadata, 0, (m_colcnt * 2));
6825
Create an array for the field metadata and store it.
6827
m_field_metadata_size= save_field_metadata();
6828
assert(m_field_metadata_size <= (m_colcnt * 2));
6831
Now set the size of the data to the size of the field metadata array
6832
plus one or two bytes for number of elements in the field metadata array.
6834
if (m_field_metadata_size > 255)
6835
m_data_size+= m_field_metadata_size + 2;
6837
m_data_size+= m_field_metadata_size + 1;
6839
memset(m_null_bits, 0, num_null_bytes);
6840
for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
6841
if (m_table->field[i]->maybe_null())
6842
m_null_bits[(i / 8)]+= 1 << (i % 8);
6845
#endif /* !defined(DRIZZLE_CLIENT) */
6848
Constructor used by slave to read the event from the binary log.
6850
#if defined(HAVE_REPLICATION)
6851
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
6852
const Format_description_log_event
6855
: Log_event(buf, description_event),
6856
#ifndef DRIZZLE_CLIENT
6859
m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
6860
m_colcnt(0), m_coltype(0),
6861
m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
6862
m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
6863
m_null_bits(0), m_meta_memory(NULL)
6865
unsigned int bytes_read= 0;
6867
uint8_t common_header_len= description_event->common_header_len;
6868
uint8_t post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
6870
/* Read the post-header */
6871
const char *post_start= buf + common_header_len;
6873
post_start+= TM_MAPID_OFFSET;
6874
if (post_header_len == 6)
6876
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
6877
m_table_id= uint4korr(post_start);
6882
assert(post_header_len == TABLE_MAP_HEADER_LEN);
6883
m_table_id= (ulong) uint6korr(post_start);
6884
post_start+= TM_FLAGS_OFFSET;
6887
assert(m_table_id != UINT32_MAX);
6889
m_flags= uint2korr(post_start);
6891
/* Read the variable part of the event */
6892
const char *const vpart= buf + common_header_len + post_header_len;
6894
/* Extract the length of the various parts from the buffer */
6895
uchar const *const ptr_dblen= (uchar const*)vpart + 0;
6896
m_dblen= *(uchar*) ptr_dblen;
6898
/* Length of database name + counter + terminating null */
6899
uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
6900
m_tbllen= *(uchar*) ptr_tbllen;
6902
/* Length of table name + counter + terminating null */
6903
uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
6904
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
6905
m_colcnt= net_field_length(&ptr_after_colcnt);
6907
/* Allocate mem for all fields in one go. If fails, caught in is_valid() */
6908
m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
6909
&m_dbnam, (uint) m_dblen + 1,
6910
&m_tblnam, (uint) m_tbllen + 1,
6911
&m_coltype, (uint) m_colcnt,
6916
/* Copy the different parts into their memory */
6917
strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
6918
strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
6919
memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
6921
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
6922
bytes_read= ptr_after_colcnt - (uchar *)buf;
6923
if (bytes_read < event_len)
6925
m_field_metadata_size= net_field_length(&ptr_after_colcnt);
6926
assert(m_field_metadata_size <= (m_colcnt * 2));
6927
uint num_null_bytes= (m_colcnt + 7) / 8;
6928
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
6929
&m_null_bits, num_null_bytes,
6930
&m_field_metadata, m_field_metadata_size,
6932
memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
6933
ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
6934
memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
6942
Table_map_log_event::~Table_map_log_event()
6944
my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
6945
my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
6949
Return value is an error code, one of:
6951
-1 Failure to open table [from open_tables()]
6953
1 No room for more tables [from set_table()]
6954
2 Out of memory [from set_table()]
6955
3 Wrong table definition
6956
4 Daisy-chaining RBR with SBR not possible
6959
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6960
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
6962
RPL_TableList *table_list;
6963
char *db_mem, *tname_mem;
6966
assert(rli->sql_thd == thd);
6968
/* Step the query id to mark what columns that are actually used. */
6969
pthread_mutex_lock(&LOCK_thread_count);
6970
thd->query_id= next_query_id();
6971
pthread_mutex_unlock(&LOCK_thread_count);
6973
if (!(memory= my_multi_malloc(MYF(MY_WME),
6974
&table_list, (uint) sizeof(RPL_TableList),
6975
&db_mem, (uint) NAME_LEN + 1,
6976
&tname_mem, (uint) NAME_LEN + 1,
6978
return(HA_ERR_OUT_OF_MEM);
6980
memset(table_list, 0, sizeof(*table_list));
6981
table_list->db = db_mem;
6982
table_list->alias= table_list->table_name = tname_mem;
6983
table_list->lock_type= TL_WRITE;
6984
table_list->next_global= table_list->next_local= 0;
6985
table_list->table_id= m_table_id;
6986
table_list->updating= 1;
6987
stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
6988
stpcpy(table_list->table_name, m_tblnam);
6992
if (!rpl_filter->db_ok(table_list->db) ||
6993
(rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
6995
my_free(memory, MYF(MY_WME));
7000
open_tables() reads the contents of thd->lex, so they must be
7001
initialized, so we should call lex_start(); to be even safer, we
7002
call mysql_init_query() which does a more complete set of inits.
7005
mysql_reset_thd_for_next_command(thd);
7007
Check if the slave is set to use SBR. If so, it should switch
7008
to using RBR until the end of the "statement", i.e., next
7009
STMT_END_F or next error.
7011
if (!thd->current_stmt_binlog_row_based &&
7012
mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
7014
thd->set_current_stmt_binlog_row_based();
7018
Open the table if it is not already open and add the table to
7019
table map. Note that for any table that should not be
7020
replicated, a filter is needed.
7022
The creation of a new TableList is used to up-cast the
7023
table_list consisting of RPL_TableList items. This will work
7024
since the only case where the argument to open_tables() is
7025
changed, is when thd->lex->query_tables == table_list, i.e.,
7026
when the statement requires prelocking. Since this is not
7027
executed when a statement is executed, this case will not occur.
7028
As a precaution, an assertion is added to ensure that the bad
7031
Either way, the memory in the list is *never* released
7032
internally in the open_tables() function, hence we take a copy
7033
of the pointer to make sure that it's not lost.
7036
assert(thd->lex->query_tables != table_list);
7037
TableList *tmp_table_list= table_list;
7038
if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
7040
if (thd->is_slave_error || thd->is_fatal_error)
7043
Error reporting borrowed from Query_log_event with many excessive
7044
simplifications (we don't honour --slave-skip-errors)
7046
uint actual_error= thd->main_da.sql_errno();
7047
rli->report(ERROR_LEVEL, actual_error,
7048
"Error '%s' on opening table `%s`.`%s`",
7049
(actual_error ? thd->main_da.message() :
7050
"unexpected success or fatal error"),
7051
table_list->db, table_list->table_name);
7052
thd->is_slave_error= 1;
7057
m_table= table_list->table;
7060
This will fail later otherwise, the 'in_use' field should be
7061
set to the current thread.
7063
assert(m_table->in_use);
7066
Use placement new to construct the table_def instance in the
7067
memory allocated for it inside table_list.
7069
The memory allocated by the table_def structure (i.e., not the
7070
memory allocated *for* the table_def structure) is released
7071
inside Relay_log_info::clear_tables_to_lock() by calling the
7072
table_def destructor explicitly.
7074
new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt,
7075
m_field_metadata, m_field_metadata_size, m_null_bits);
7076
table_list->m_tabledef_valid= true;
7079
We record in the slave's information that the table should be
7080
locked by linking the table into the list of tables to lock.
7082
table_list->next_global= table_list->next_local= rli->tables_to_lock;
7083
const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
7084
const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
7085
/* 'memory' is freed in clear_tables_to_lock */
7091
my_free(memory, MYF(MY_WME));
7095
Log_event::enum_skip_reason
7096
Table_map_log_event::do_shall_skip(Relay_log_info *rli)
7099
If the slave skip counter is 1, then we should not start executing
7102
return continue_group(rli);
7105
int Table_map_log_event::do_update_pos(Relay_log_info *rli)
7107
rli->inc_event_relay_log_pos();
7111
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7113
#ifndef DRIZZLE_CLIENT
7114
bool Table_map_log_event::write_data_header(IO_CACHE *file)
7116
assert(m_table_id != UINT32_MAX);
7117
uchar buf[TABLE_MAP_HEADER_LEN];
7118
int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
7119
int2store(buf + TM_FLAGS_OFFSET, m_flags);
7120
return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
7123
bool Table_map_log_event::write_data_body(IO_CACHE *file)
7125
assert(m_dbnam != NULL);
7126
assert(m_tblnam != NULL);
7127
/* We use only one byte per length for storage in event: */
7128
assert(m_dblen < 128);
7129
assert(m_tbllen < 128);
7131
uchar const dbuf[]= { (uchar) m_dblen };
7132
uchar const tbuf[]= { (uchar) m_tbllen };
7134
uchar cbuf[sizeof(m_colcnt)];
7135
uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
7136
assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
7139
Store the size of the field metadata.
7141
uchar mbuf[sizeof(m_field_metadata_size)];
7142
uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
7144
return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
7145
my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
7146
my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
7147
my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
7148
my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
7149
my_b_safe_write(file, m_coltype, m_colcnt) ||
7150
my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
7151
my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
7152
my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
7156
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
7159
Print some useful information for the SHOW BINARY LOG information
7163
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
7164
void Table_map_log_event::pack_info(Protocol *protocol)
7167
size_t bytes= snprintf(buf, sizeof(buf),
7168
"table_id: %lu (%s.%s)",
7169
m_table_id, m_dbnam, m_tblnam);
7170
protocol->store(buf, bytes, &my_charset_bin);
7178
#ifdef DRIZZLE_CLIENT
7179
void Table_map_log_event::print(FILE * /* unused */,
7180
PRINT_EVENT_INFO *print_event_info)
7182
if (!print_event_info->short_form)
7184
print_header(&print_event_info->head_cache, print_event_info, true);
7185
my_b_printf(&print_event_info->head_cache,
7186
"\tTable_map: `%s`.`%s` mapped to number %lu\n",
7187
m_dbnam, m_tblnam, m_table_id);
7188
print_base64(&print_event_info->body_cache, print_event_info, true);
7193
/**************************************************************************
7194
Write_rows_log_event member functions
7195
**************************************************************************/
7198
Constructor used to build an event for writing to the binary log.
7200
#if !defined(DRIZZLE_CLIENT)
7201
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, Table *tbl_arg,
7203
bool is_transactional)
7204
: Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
7210
Constructor used by slave to read the event from the binary log.
7212
#ifdef HAVE_REPLICATION
7213
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
7214
const Format_description_log_event
7216
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
7221
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7223
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
7228
todo: to introduce a property for the event (handler?) which forces
7229
applying the event in the replace (idempotent) fashion.
7231
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
7234
We are using REPLACE semantics and not INSERT IGNORE semantics
7235
when writing rows, that is: new rows replace old rows. We need to
7236
inform the storage engine that it should use this behaviour.
7239
/* Tell the storage engine that we are using REPLACE semantics. */
7240
thd->lex->duplicates= DUP_REPLACE;
7243
Pretend we're executing a REPLACE command: this is needed for
7244
InnoDB since it is not (properly) checking the
7245
lex->duplicates flag.
7247
thd->lex->sql_command= SQLCOM_REPLACE;
7249
Do not raise the error flag in case of hitting to an unique attribute
7251
m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
7254
m_table->file->ha_start_bulk_insert(0);
7256
We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
7257
any TIMESTAMP column with data from the row but instead will use
7258
the event's current time.
7259
As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
7260
columns, we know that all TIMESTAMP columns on slave will receive explicit
7261
data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
7262
When we allow a table without TIMESTAMP to be replicated to a table having
7263
more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
7264
column to be replicated into a BIGINT column and the slave's table has a
7265
TIMESTAMP column, then the slave's TIMESTAMP column will take its value
7266
from set_time() which we called earlier (consistent with SBR). And then in
7267
some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
7268
analyze if explicit data is provided for slave's TIMESTAMP columns).
7270
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
7276
Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
7280
if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
7282
m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
7283
m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
7285
resetting the extra with
7286
table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
7288
explanation: file->reset() performs this duty
7289
ultimately. Still todo: fix
7292
if ((local_error= m_table->file->ha_end_bulk_insert()))
7294
m_table->file->print_error(local_error, MYF(0));
7296
return error? error : local_error;
7299
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7302
Check if there are more UNIQUE keys after the given key.
7305
last_uniq_key(Table *table, uint keyno)
7307
while (++keyno < table->s->keys)
7308
if (table->key_info[keyno].flags & HA_NOSAME)
7314
Check if an error is a duplicate key error.
7316
This function is used to check if an error code is one of the
7317
duplicate key error, i.e., and error code for which it is sensible
7318
to do a <code>get_dup_key()</code> to retrieve the duplicate key.
7320
@param errcode The error code to check.
7322
@return <code>true</code> if the error code is such that
7323
<code>get_dup_key()</code> will return true, <code>false</code>
7327
is_duplicate_key_error(int errcode)
7331
case HA_ERR_FOUND_DUPP_KEY:
7332
case HA_ERR_FOUND_DUPP_UNIQUE:
7339
Write the current row into event's table.
7341
The row is located in the row buffer, pointed by @c m_curr_row member.
7342
Number of columns of the row is stored in @c m_width member (it can be
7343
different from the number of columns in the table to which we insert).
7344
Bitmap @c m_cols indicates which columns are present in the row. It is assumed
7345
that event's table is already open and pointed by @c m_table.
7347
If the same record already exists in the table it can be either overwritten
7348
or an error is reported depending on the value of @c overwrite flag
7349
(error reporting not yet implemented). Note that the matching record can be
7350
different from the row we insert if we use primary keys to identify records in
7353
The row to be inserted can contain values only for selected columns. The
7354
missing columns are filled with default values using @c prepare_record()
7355
function. If a matching record is found in the table and @c overwritte is
7356
true, the missing columns are taken from it.
7358
@param rli Relay log info (needed for row unpacking).
7360
Shall we overwrite if the row already exists or signal
7361
error (currently ignored).
7363
@returns Error code on failure, 0 on success.
7365
This method, if successful, sets @c m_curr_row_end pointer to point at the
7366
next row in the rows buffer. This is done when unpacking the row to be
7369
@note If a matching record is found, it is either updated using
7370
@c ha_update_row() or first deleted and then new record written.
7374
Rows_log_event::write_row(const Relay_log_info *const rli,
7375
const bool overwrite)
7377
assert(m_table != NULL && thd != NULL);
7379
Table *table= m_table; // pointer to event's table
7382
auto_afree_ptr<char> key(NULL);
7384
/* fill table->record[0] with default values */
7387
We only check if the columns have default values for non-NDB
7388
engines, for NDB we ignore the check since updates are sent as
7389
writes, causing errors when trying to prepare the record.
7391
TODO[ndb]: Elimiate this hard-coded dependency on NDB. Ideally,
7392
the engine should be able to set a flag that it want the default
7393
values filled in and one flag to handle the case that the default
7394
values should be checked. Maybe these two flags can be combined.
7396
if ((error= prepare_record(table, &m_cols, m_width, true)))
7399
/* unpack row into table->record[0] */
7400
error= unpack_current_row(rli, &m_cols);
7402
// Temporary fix to find out why it fails [/Matz]
7403
memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
7406
Try to write record. If a corresponding record already exists in the table,
7407
we try to change it using ha_update_row() if possible. Otherwise we delete
7408
it and repeat the whole process again.
7410
TODO: Add safety measures against infinite looping.
7413
while ((error= table->file->ha_write_row(table->record[0])))
7415
if (error == HA_ERR_LOCK_DEADLOCK ||
7416
error == HA_ERR_LOCK_WAIT_TIMEOUT ||
7417
(keynum= table->file->get_dup_key(error)) < 0 ||
7421
Deadlock, waiting for lock or just an error from the handler
7422
such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
7423
Retrieval of the duplicate key number may fail
7424
- either because the error was not "duplicate key" error
7425
- or because the information which key is not available
7427
table->file->print_error(error, MYF(0));
7431
We need to retrieve the old row into record[1] to be able to
7432
either update or delete the offending record. We either:
7434
- use rnd_pos() with a row-id (available as dupp_row) to the
7435
offending row, if that is possible (MyISAM and Blackhole), or else
7437
- use index_read_idx() with the key that is duplicated, to
7438
retrieve the offending row.
7440
if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
7442
if (table->file->inited && (error= table->file->ha_index_end()))
7444
if ((error= table->file->ha_rnd_init(false)))
7447
error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
7448
table->file->ha_rnd_end();
7451
table->file->print_error(error, MYF(0));
7457
if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
7462
if (key.get() == NULL)
7464
key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
7465
if (key.get() == NULL)
7471
key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
7473
error= table->file->index_read_idx_map(table->record[1], keynum,
7474
(const uchar*)key.get(),
7479
table->file->print_error(error, MYF(0));
7485
Now, record[1] should contain the offending row. That
7486
will enable us to update it or, alternatively, delete it (so
7487
that we can insert the new row afterwards).
7491
If row is incomplete we will use the record found to fill
7494
if (!get_flags(COMPLETE_ROWS_F))
7496
restore_record(table,record[1]);
7497
error= unpack_current_row(rli, &m_cols);
7501
REPLACE is defined as either INSERT or DELETE + INSERT. If
7502
possible, we can replace it with an UPDATE, but that will not
7503
work on InnoDB if FOREIGN KEY checks are necessary.
7505
I (Matz) am not sure of the reason for the last_uniq_key()
7506
check as, but I'm guessing that it's something along the
7509
Suppose that we got the duplicate key to be a key that is not
7510
the last unique key for the table and we perform an update:
7511
then there might be another key for which the unique check will
7512
fail, so we're better off just deleting the row and inserting
7515
if (last_uniq_key(table, keynum) &&
7516
!table->file->referenced_by_foreign_key())
7518
error=table->file->ha_update_row(table->record[1],
7522
case HA_ERR_RECORD_IS_THE_SAME:
7529
table->file->print_error(error, MYF(0));
7536
if ((error= table->file->ha_delete_row(table->record[1])))
7538
table->file->print_error(error, MYF(0));
7541
/* Will retry ha_write_row() with the offending row removed. */
7551
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
7553
assert(m_table != NULL);
7555
write_row(rli, /* if 1 then overwrite */
7556
bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
7558
if (error && !thd->is_error())
7561
my_error(ER_UNKNOWN_ERROR, MYF(0));
7567
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7569
#ifdef DRIZZLE_CLIENT
7570
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
7572
Rows_log_event::print_helper(file, print_event_info, "Write_rows");
7576
/**************************************************************************
7577
Delete_rows_log_event member functions
7578
**************************************************************************/
7580
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7582
Compares table->record[0] and table->record[1]
7584
Returns TRUE if different.
7586
static bool record_compare(Table *table)
7589
Need to set the X bit and the filler bits in both records since
7590
there are engines that do not set it correctly.
7592
In addition, since MyISAM checks that one hasn't tampered with the
7593
record, it is necessary to restore the old bytes into the record
7594
after doing the comparison.
7596
TODO[record format ndb]: Remove it once NDB returns correct
7597
records. Check that the other engines also return correct records.
7600
uchar saved_x[2], saved_filler[2];
7602
if (table->s->null_bytes > 0)
7604
for (int i = 0 ; i < 2 ; ++i)
7606
saved_x[i]= table->record[i][0];
7607
saved_filler[i]= table->record[i][table->s->null_bytes - 1];
7608
table->record[i][0]|= 1U;
7609
table->record[i][table->s->null_bytes - 1]|=
7610
256U - (1U << table->s->last_null_bit_pos);
7614
if (table->s->blob_fields + table->s->varchar_fields == 0)
7616
result= cmp_record(table,record[1]);
7617
goto record_compare_exit;
7620
/* Compare null bits */
7621
if (memcmp(table->null_flags,
7622
table->null_flags+table->s->rec_buff_length,
7623
table->s->null_bytes))
7625
result= true; // Diff in NULL value
7626
goto record_compare_exit;
7629
/* Compare updated fields */
7630
for (Field **ptr=table->field ; *ptr ; ptr++)
7632
if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
7635
goto record_compare_exit;
7639
record_compare_exit:
7641
Restore the saved bytes.
7643
TODO[record format ndb]: Remove this code once NDB returns the
7644
correct record format.
7646
if (table->s->null_bytes > 0)
7648
for (int i = 0 ; i < 2 ; ++i)
7650
table->record[i][0]= saved_x[i];
7651
table->record[i][table->s->null_bytes - 1]= saved_filler[i];
7659
Locate the current row in event's table.
7661
The current row is pointed by @c m_curr_row. Member @c m_width tells how many
7662
columns are there in the row (this can be differnet from the number of columns
7663
in the table). It is assumed that event's table is already open and pointed
7666
If a corresponding record is found in the table it is stored in
7667
@c m_table->record[0]. Note that when record is located based on a primary
7668
key, it is possible that the record found differs from the row being located.
7670
If no key is specified or table does not have keys, a table scan is used to
7671
find the row. In that case the row should be complete and contain values for
7672
all columns. However, it can still be shorter than the table, i.e. the table
7673
can contain extra columns not present in the row. It is also possible that
7674
the table has fewer columns than the row being located.
7676
@returns Error code on failure, 0 on success.
7678
@post In case of success @c m_table->record[0] contains the record found.
7679
Also, the internal "cursor" of the table is positioned at the record found.
7681
@note If the engine allows random access of the records, a combination of
7682
@c position() and @c rnd_pos() will be used.
7685
int Rows_log_event::find_row(const Relay_log_info *rli)
7687
assert(m_table && m_table->in_use != NULL);
7689
Table *table= m_table;
7692
/* unpack row - missing fields get default values */
7693
prepare_record(table, &m_cols, m_width, false/* don't check errors */);
7694
error= unpack_current_row(rli, &m_cols);
7696
// Temporary fix to find out why it fails [/Matz]
7697
memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
7699
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
7700
table->s->primary_key < MAX_KEY)
7703
Use a more efficient method to fetch the record given by
7704
table->record[0] if the engine allows it. We first compute a
7705
row reference using the position() member function (it will be
7706
stored in table->file->ref) and the use rnd_pos() to position
7707
the "cursor" (i.e., record[0] in this case) at the correct row.
7709
TODO: Add a check that the correct record has been fetched by
7710
comparing with the original record. Take into account that the
7711
record on the master and slave can be of different
7712
length. Something along these lines should work:
7714
ADD>>> store_record(table,record[1]);
7715
int error= table->file->rnd_pos(table->record[0], table->file->ref);
7716
ADD>>> assert(memcmp(table->record[1], table->record[0],
7717
table->s->reclength) == 0);
7720
int error= table->file->rnd_pos_by_record(table->record[0]);
7721
table->file->ha_rnd_end();
7724
table->file->print_error(error, MYF(0));
7729
// We can't use position() - try other methods.
7732
Save copy of the record in table->record[1]. It might be needed
7733
later if linear search is used to find exact match.
7735
store_record(table,record[1]);
7737
if (table->s->keys > 0)
7739
/* We have a key: search the table using the index */
7740
if (!table->file->inited && (error= table->file->ha_index_init(0, false)))
7742
table->file->print_error(error, MYF(0));
7746
/* Fill key data for the row */
7749
key_copy(m_key, table->record[0], table->key_info, 0);
7752
We need to set the null bytes to ensure that the filler bit are
7753
all set when returning. There are storage engines that just set
7754
the necessary bits on the bytes and don't set the filler bits
7757
my_ptrdiff_t const pos=
7758
table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
7759
table->record[0][pos]= 0xFF;
7761
if ((error= table->file->index_read_map(table->record[0], m_key,
7763
HA_READ_KEY_EXACT)))
7765
table->file->print_error(error, MYF(0));
7766
table->file->ha_index_end();
7771
Below is a minor "optimization". If the key (i.e., key number
7772
0) has the HA_NOSAME flag set, we know that we have found the
7773
correct record (since there can be no duplicates); otherwise, we
7774
have to compare the record with the one found to see if it is
7777
CAVEAT! This behaviour is essential for the replication of,
7778
e.g., the mysql.proc table since the correct record *shall* be
7779
found using the primary key *only*. There shall be no
7780
comparison of non-PK columns to decide if the correct record is
7781
found. I can see no scenario where it would be incorrect to
7782
chose the row to change only using a PK or an UNNI.
7784
if (table->key_info->flags & HA_NOSAME)
7786
table->file->ha_index_end();
7791
In case key is not unique, we still have to iterate over records found
7792
and find the one which is identical to the row given. A copy of the
7793
record we are looking for is stored in record[1].
7795
while (record_compare(table))
7798
We need to set the null bytes to ensure that the filler bit
7799
are all set when returning. There are storage engines that
7800
just set the necessary bits on the bytes and don't set the
7801
filler bits correctly.
7803
TODO[record format ndb]: Remove this code once NDB returns the
7804
correct record format.
7806
if (table->s->null_bytes > 0)
7808
table->record[0][table->s->null_bytes - 1]|=
7809
256U - (1U << table->s->last_null_bit_pos);
7812
if ((error= table->file->index_next(table->record[0])))
7814
table->file->print_error(error, MYF(0));
7815
table->file->ha_index_end();
7821
Have to restart the scan to be able to fetch the next row.
7823
table->file->ha_index_end();
7827
int restart_count= 0; // Number of times scanning has restarted from top
7829
/* We don't have a key: search the table using rnd_next() */
7830
if ((error= table->file->ha_rnd_init(1)))
7832
table->file->print_error(error, MYF(0));
7836
/* Continue until we find the right record or have made a full loop */
7839
error= table->file->rnd_next(table->record[0]);
7844
case HA_ERR_RECORD_DELETED:
7847
case HA_ERR_END_OF_FILE:
7848
if (++restart_count < 2)
7849
table->file->ha_rnd_init(1);
7853
table->file->print_error(error, MYF(0));
7854
table->file->ha_rnd_end();
7858
while (restart_count < 2 && record_compare(table));
7861
Note: above record_compare will take into accout all record fields
7862
which might be incorrect in case a partial row was given in the event
7864
table->file->ha_rnd_end();
7866
assert(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
7870
table->default_column_bitmaps();
7873
table->default_column_bitmaps();
7880
Constructor used to build an event for writing to the binary log.
7883
#ifndef DRIZZLE_CLIENT
7884
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, Table *tbl_arg,
7886
bool is_transactional)
7887
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
7890
#endif /* #if !defined(DRIZZLE_CLIENT) */
7893
Constructor used by slave to read the event from the binary log.
7895
#ifdef HAVE_REPLICATION
7896
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
7897
const Format_description_log_event
7899
: Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
7904
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7907
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
7909
if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
7910
m_table->s->primary_key < MAX_KEY)
7913
We don't need to allocate any memory for m_key since it is not used.
7918
if (m_table->s->keys > 0)
7920
// Allocate buffer for key searches
7921
m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
7923
return HA_ERR_OUT_OF_MEM;
7930
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
7933
/*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
7934
m_table->file->ha_index_or_rnd_end();
7935
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
7941
int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
7944
assert(m_table != NULL);
7946
if (!(error= find_row(rli)))
7949
Delete the record found, located in record[0]
7951
error= m_table->file->ha_delete_row(m_table->record[0]);
7956
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7958
#ifdef DRIZZLE_CLIENT
7959
void Delete_rows_log_event::print(FILE *file,
7960
PRINT_EVENT_INFO* print_event_info)
7962
Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
7967
/**************************************************************************
7968
Update_rows_log_event member functions
7969
**************************************************************************/
7972
Constructor used to build an event for writing to the binary log.
7974
#if !defined(DRIZZLE_CLIENT)
7975
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, Table *tbl_arg,
7977
bool is_transactional)
7978
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
7980
init(tbl_arg->write_set);
7983
void Update_rows_log_event::init(MY_BITMAP const *cols)
7985
/* if bitmap_init fails, caught in is_valid() */
7986
if (likely(!bitmap_init(&m_cols_ai,
7987
m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
7991
/* Cols can be zero if this is a dummy binrows event */
7992
if (likely(cols != NULL))
7994
memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
7995
create_last_word_mask(&m_cols_ai);
7999
#endif /* !defined(DRIZZLE_CLIENT) */
8002
Update_rows_log_event::~Update_rows_log_event()
8004
if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
8005
m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
8006
bitmap_free(&m_cols_ai); // To pair with bitmap_init().
8011
Constructor used by slave to read the event from the binary log.
8013
#ifdef HAVE_REPLICATION
8014
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
8016
Format_description_log_event
8018
: Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
8023
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
8026
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
8028
if (m_table->s->keys > 0)
8030
// Allocate buffer for key searches
8031
m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
8033
return HA_ERR_OUT_OF_MEM;
8036
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
8042
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
8045
/*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
8046
m_table->file->ha_index_or_rnd_end();
8047
my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
8054
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
8056
assert(m_table != NULL);
8058
int error= find_row(rli);
8062
We need to read the second image in the event of error to be
8063
able to skip to the next pair of updates
8065
m_curr_row= m_curr_row_end;
8066
unpack_current_row(rli, &m_cols_ai);
8071
This is the situation after locating BI:
8073
===|=== before image ====|=== after image ===|===
8075
m_curr_row m_curr_row_end
8077
BI found in the table is stored in record[0]. We copy it to record[1]
8078
and unpack AI to record[0].
8081
store_record(m_table,record[1]);
8083
m_curr_row= m_curr_row_end;
8084
error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
8087
Now we have the right row to update. The old row (the one we're
8088
looking for) is in record[1] and the new row is in record[0].
8091
// Temporary fix to find out why it fails [/Matz]
8092
memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
8093
memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
8095
error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
8096
if (error == HA_ERR_RECORD_IS_THE_SAME)
8102
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
8104
#ifdef DRIZZLE_CLIENT
8105
void Update_rows_log_event::print(FILE *file,
8106
PRINT_EVENT_INFO* print_event_info)
8108
Rows_log_event::print_helper(file, print_event_info, "Update_rows");
8113
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
8114
const Format_description_log_event *descr_event)
8115
: Log_event(buf, descr_event)
8117
uint8_t const common_header_len=
8118
descr_event->common_header_len;
8119
uint8_t const post_header_len=
8120
descr_event->post_header_len[INCIDENT_EVENT-1];
8122
m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
8123
char const *ptr= buf + common_header_len + post_header_len;
8124
char const *const str_end= buf + event_len;
8125
uint8_t len= 0; // Assignment to keep compiler happy
8126
const char *str= NULL; // Assignment to keep compiler happy
8127
read_str(&ptr, str_end, &str, &len);
8128
m_message.str= const_cast<char*>(str);
8129
m_message.length= len;
8134
Incident_log_event::~Incident_log_event()
8140
Incident_log_event::description() const
8142
static const char *const description[]= {
8143
"NOTHING", // Not used
8147
assert(0 <= m_incident);
8148
assert((size_t) m_incident <= sizeof(description)/sizeof(*description));
8150
return description[m_incident];
8154
#ifndef DRIZZLE_CLIENT
8155
void Incident_log_event::pack_info(Protocol *protocol)
8159
if (m_message.length > 0)
8160
bytes= snprintf(buf, sizeof(buf), "#%d (%s)",
8161
m_incident, description());
8163
bytes= snprintf(buf, sizeof(buf), "#%d (%s): %s",
8164
m_incident, description(), m_message.str);
8165
protocol->store(buf, bytes, &my_charset_bin);
8170
#ifdef DRIZZLE_CLIENT
8172
Incident_log_event::print(FILE *file,
8173
PRINT_EVENT_INFO *print_event_info)
8175
if (print_event_info->short_form)
8178
Write_on_release_cache cache(&print_event_info->head_cache, file);
8179
print_header(&cache, print_event_info, false);
8180
my_b_printf(&cache, "\n# Incident: %s", description());
8184
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
8186
Incident_log_event::do_apply_event(Relay_log_info const *rli)
8188
rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
8189
ER(ER_SLAVE_INCIDENT),
8191
m_message.length > 0 ? m_message.str : "<none>");
8197
Incident_log_event::write_data_header(IO_CACHE *file)
8199
uchar buf[sizeof(int16_t)];
8200
int2store(buf, (int16_t) m_incident);
8201
return(my_b_safe_write(file, buf, sizeof(buf)));
8205
Incident_log_event::write_data_body(IO_CACHE *file)
8207
return(write_str(file, m_message.str, m_message.length));
8210
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
8211
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
8212
const Format_description_log_event* description_event)
8213
:Log_event(buf, description_event)
8215
uint8_t header_size= description_event->common_header_len;
8216
ident_len = event_len - header_size;
8217
set_if_smaller(ident_len,FN_REFLEN-1);
8218
log_ident= buf + header_size;
8223
#ifdef DRIZZLE_CLIENT
8225
The default values for these variables should be values that are
8226
*incorrect*, i.e., values that cannot occur in an event. This way,
8227
they will always be printed for the first event.
8229
st_print_event_info::st_print_event_info()
8230
:flags2_inited(0), sql_mode_inited(0),
8231
auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
8232
lc_time_names_number(UINT32_MAX),
8233
charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
8234
thread_id(0), thread_id_printed(false),
8235
base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(false)
8238
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
8239
program's startup, but these explicit memset() is for the day someone
8240
creates dynamic instances.
8242
memset(db, 0, sizeof(db));
8243
memset(charset, 0, sizeof(charset));
8244
memset(time_zone_str, 0, sizeof(time_zone_str));
8247
myf const flags = MYF(MY_WME | MY_NABP);
8248
open_cached_file(&head_cache, NULL, NULL, 0, flags);
8249
open_cached_file(&body_cache, NULL, NULL, 0, flags);