1 /*
2 Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16
17
18 #ifdef MYSQL_CLIENT
19
20 #include "sql_priv.h"
21 #include "mysqld_error.h"
22
23 #else
24
25 #ifdef USE_PRAGMA_IMPLEMENTATION
26 #pragma implementation // gcc: Class implementation
27 #endif
28
29 #include "sql_priv.h"
30 #include "unireg.h"
31 #include "my_global.h" // REQUIRED by log_event.h > m_string.h > my_bitmap.h
32 #include "log_event.h"
33 #include "sql_base.h" // close_thread_tables
34 #include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE
35 #include "sql_locale.h" // MY_LOCALE, my_locale_by_number, my_locale_en_US
36 #include "key.h" // key_copy
37 #include "lock.h" // mysql_unlock_tables
38 #include "sql_parse.h" // mysql_test_parse_for_slave
39 #include "tztime.h" // struct Time_zone
40 #include "sql_load.h" // mysql_load
41 #include "sql_db.h" // load_db_opt_by_name
42 #include "slave.h"
43 #include "rpl_rli.h"
44 #include "rpl_mi.h"
45 #include "rpl_filter.h"
46 #include "rpl_record.h"
47 #include "transaction.h"
48 #include <my_dir.h>
49 #include "sql_show.h" // append_identifier
50
51 #endif /* MYSQL_CLIENT */
52
53 #include <base64.h>
54 #include <my_bitmap.h>
55 #include "rpl_utility.h"
56
57 #define log_cs &my_charset_latin1
58
59 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
60
61
62 /*
63 Size of buffer for printing a double in format %.<PREC>g
64
65 optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
66 exponent digits + '\0'
67 */
68 #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
69
70 /*
71 Explicit instantiation to unsigned int of template available_buffer
72 function.
73 */
74 template unsigned int available_buffer<unsigned int>(const char*,
75 const char*,
76 unsigned int);
77
78 /*
79 Explicit instantiation to unsigned int of template valid_buffer_range
80 function.
81 */
82 template bool valid_buffer_range<unsigned int>(unsigned int,
83 const char*,
84 const char*,
85 unsigned int);
86
87 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
88 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
89
HA_ERR(int i)90 static const char *HA_ERR(int i)
91 {
92 /*
93 This function should only be called in case of an error
94 was detected
95 */
96 DBUG_ASSERT(i != 0);
97 switch (i) {
98 case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
99 case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
100 case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
101 case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
102 case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
103 case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
104 case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
105 case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
106 case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
107 case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
108 case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
109 case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
110 case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
111 case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
112 case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
113 case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
114 case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
115 case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
116 case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
117 case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
118 case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
119 case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
120 case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
121 case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
122 case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
123 case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
124 case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
125 case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
126 case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
127 case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
128 case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
129 case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
130 case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
131 case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
132 case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
133 case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
134 case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
135 case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
136 case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
137 case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
138 case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
139 case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
140 case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
141 case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
142 case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
143 case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
144 case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
145 case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
146 case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
147 case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
148 }
149 return "No Error!";
150 }
151
152 /**
153 Error reporting facility for Rows_log_event::do_apply_event
154
155 @param level error, warning or info
156 @param ha_error HA_ERR_ code
157 @param rli pointer to the active Relay_log_info instance
158 @param thd pointer to the slave thread's thd
159 @param table pointer to the event's table object
160 @param type the type of the event
161 @param log_name the master binlog file name
162 @param pos the master binlog file pos (the next after the event)
163
164 */
slave_rows_error_report(enum loglevel level,int ha_error,Relay_log_info const * rli,THD * thd,TABLE * table,const char * type,const char * log_name,ulong pos)165 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
166 Relay_log_info const *rli, THD *thd,
167 TABLE *table, const char * type,
168 const char *log_name, ulong pos)
169 {
170 const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
171 char buff[MAX_SLAVE_ERRMSG], *slider;
172 const char *buff_end= buff + sizeof(buff);
173 uint len;
174 List_iterator_fast<MYSQL_ERROR> it(thd->warning_info->warn_list());
175 MYSQL_ERROR *err;
176 buff[0]= 0;
177
178 for (err= it++, slider= buff; err && slider < buff_end - 1;
179 slider += len, err= it++)
180 {
181 len= my_snprintf(slider, buff_end - slider,
182 " %s, Error_code: %d;", err->get_message_text(),
183 err->get_sql_errno());
184 }
185
186 if (ha_error != 0)
187 rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
188 "Could not execute %s event on table %s.%s;"
189 "%s handler error %s; "
190 "the event's master log %s, end_log_pos %lu",
191 type, table->s->db.str, table->s->table_name.str,
192 buff, handler_error == NULL ? "<unknown>" : handler_error,
193 log_name, pos);
194 else
195 rli->report(level, thd->is_error() ? thd->stmt_da->sql_errno() : 0,
196 "Could not execute %s event on table %s.%s;"
197 "%s the event's master log %s, end_log_pos %lu",
198 type, table->s->db.str, table->s->table_name.str,
199 buff, log_name, pos);
200 }
201 #endif
202
203 /*
204 Cache that will automatically be written to a dedicated file on
205 destruction.
206
207 DESCRIPTION
208
209 */
210 class Write_on_release_cache
211 {
212 public:
213 enum flag
214 {
215 FLUSH_F
216 };
217
218 typedef unsigned short flag_set;
219
220 /*
221 Constructor.
222
223 SYNOPSIS
224 Write_on_release_cache
225 cache Pointer to cache to use
226 file File to write cache to upon destruction
227 flags Flags for the cache
228
229 DESCRIPTION
230
231 Class used to guarantee copy of cache to file before exiting the
232 current block. On successful copy of the cache, the cache will
233 be reinited as a WRITE_CACHE.
234
235 Currently, a pointer to the cache is provided in the
236 constructor, but it would be possible to create a subclass
237 holding the IO_CACHE itself.
238 */
Write_on_release_cache(IO_CACHE * cache,FILE * file,flag_set flags=0)239 Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
240 : m_cache(cache), m_file(file), m_flags(flags)
241 {
242 reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
243 }
244
~Write_on_release_cache()245 ~Write_on_release_cache()
246 {
247 copy_event_cache_to_file_and_reinit(m_cache, m_file);
248 if (m_flags | FLUSH_F)
249 fflush(m_file);
250 }
251
252 /*
253 Return a pointer to the internal IO_CACHE.
254
255 SYNOPSIS
256 operator&()
257
258 DESCRIPTION
259
260 Function to return a pointer to the internal cache, so that the
261 object can be treated as a IO_CACHE and used with the my_b_*
262 IO_CACHE functions
263
264 RETURN VALUE
265 A pointer to the internal IO_CACHE.
266 */
operator &()267 IO_CACHE *operator&()
268 {
269 return m_cache;
270 }
271
272 private:
273 // Hidden, to prevent usage.
274 Write_on_release_cache(Write_on_release_cache const&);
275
276 IO_CACHE *m_cache;
277 FILE *m_file;
278 flag_set m_flags;
279 };
280
281 #ifndef DBUG_OFF
282 uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
283 #endif
284
285 /*
286 pretty_print_str()
287 */
288
289 #ifdef MYSQL_CLIENT
pretty_print_str(IO_CACHE * cache,const char * str,int len)290 static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
291 {
292 const char* end = str + len;
293 my_b_printf(cache, "\'");
294 while (str < end)
295 {
296 char c;
297 switch ((c=*str++)) {
298 case '\n': my_b_printf(cache, "\\n"); break;
299 case '\r': my_b_printf(cache, "\\r"); break;
300 case '\\': my_b_printf(cache, "\\\\"); break;
301 case '\b': my_b_printf(cache, "\\b"); break;
302 case '\t': my_b_printf(cache, "\\t"); break;
303 case '\'': my_b_printf(cache, "\\'"); break;
304 case 0 : my_b_printf(cache, "\\0"); break;
305 default:
306 my_b_printf(cache, "%c", c);
307 break;
308 }
309 }
310 my_b_printf(cache, "\'");
311 }
312 #endif /* MYSQL_CLIENT */
313
314 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
315
clear_all_errors(THD * thd,Relay_log_info * rli)316 static void clear_all_errors(THD *thd, Relay_log_info *rli)
317 {
318 thd->is_slave_error = 0;
319 thd->clear_error();
320 rli->clear_error();
321 }
322
idempotent_error_code(int err_code)323 inline int idempotent_error_code(int err_code)
324 {
325 int ret= 0;
326
327 switch (err_code)
328 {
329 case 0:
330 ret= 1;
331 break;
332 /*
333 The following list of "idempotent" errors
334 means that an error from the list might happen
335 because of idempotent (more than once)
336 applying of a binlog file.
337 Notice, that binlog has a ddl operation its
338 second applying may cause
339
340 case HA_ERR_TABLE_DEF_CHANGED:
341 case HA_ERR_CANNOT_ADD_FOREIGN:
342
343 which are not included into to the list.
344
345 Note that HA_ERR_RECORD_DELETED is not in the list since
346 do_exec_row() should not return that error code.
347 */
348 case HA_ERR_RECORD_CHANGED:
349 case HA_ERR_KEY_NOT_FOUND:
350 case HA_ERR_END_OF_FILE:
351 case HA_ERR_FOUND_DUPP_KEY:
352 case HA_ERR_FOUND_DUPP_UNIQUE:
353 case HA_ERR_FOREIGN_DUPLICATE_KEY:
354 case HA_ERR_NO_REFERENCED_ROW:
355 case HA_ERR_ROW_IS_REFERENCED:
356 ret= 1;
357 break;
358 default:
359 ret= 0;
360 break;
361 }
362 return (ret);
363 }
364
365 /**
366 Ignore error code specified on command line.
367 */
368
ignored_error_code(int err_code)369 inline int ignored_error_code(int err_code)
370 {
371 #ifdef HAVE_NDB_BINLOG
372 /*
373 The following error codes are hard-coded and will always be ignored.
374 */
375 switch (err_code)
376 {
377 case ER_DB_CREATE_EXISTS:
378 case ER_DB_DROP_EXISTS:
379 return 1;
380 default:
381 /* Nothing to do */
382 break;
383 }
384 #endif
385 return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
386 (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
387 }
388
389 /*
390 This function converts an engine's error to a server error.
391
392 If the thread does not have an error already reported, it tries to
393 define it by calling the engine's method print_error. However, if a
394 mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
395 warning message.
396 */
convert_handler_error(int error,THD * thd,TABLE * table)397 int convert_handler_error(int error, THD* thd, TABLE *table)
398 {
399 uint actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
400 0);
401
402 if (actual_error == 0)
403 {
404 table->file->print_error(error, MYF(0));
405 actual_error= (thd->is_error() ? thd->stmt_da->sql_errno() :
406 ER_UNKNOWN_ERROR);
407 if (actual_error == ER_UNKNOWN_ERROR)
408 if (global_system_variables.log_warnings)
409 sql_print_warning("Unknown error detected %d in handler", error);
410 }
411
412 return (actual_error);
413 }
414
concurrency_error_code(int error)415 inline bool concurrency_error_code(int error)
416 {
417 switch (error)
418 {
419 case ER_LOCK_WAIT_TIMEOUT:
420 case ER_LOCK_DEADLOCK:
421 case ER_XA_RBDEADLOCK:
422 return TRUE;
423 default:
424 return (FALSE);
425 }
426 }
427
unexpected_error_code(int unexpected_error)428 inline bool unexpected_error_code(int unexpected_error)
429 {
430 switch (unexpected_error)
431 {
432 case ER_NET_READ_ERROR:
433 case ER_NET_ERROR_ON_WRITE:
434 case ER_QUERY_INTERRUPTED:
435 case ER_SERVER_SHUTDOWN:
436 case ER_NEW_ABORTING_CONNECTION:
437 return(TRUE);
438 default:
439 return(FALSE);
440 }
441 }
442
443 /*
444 pretty_print_str()
445 */
446
pretty_print_str(char * packet,const char * str,int len)447 static char *pretty_print_str(char *packet, const char *str, int len)
448 {
449 const char *end= str + len;
450 char *pos= packet;
451 *pos++= '\'';
452 while (str < end)
453 {
454 char c;
455 switch ((c=*str++)) {
456 case '\n': *pos++= '\\'; *pos++= 'n'; break;
457 case '\r': *pos++= '\\'; *pos++= 'r'; break;
458 case '\\': *pos++= '\\'; *pos++= '\\'; break;
459 case '\b': *pos++= '\\'; *pos++= 'b'; break;
460 case '\t': *pos++= '\\'; *pos++= 't'; break;
461 case '\'': *pos++= '\\'; *pos++= '\''; break;
462 case 0 : *pos++= '\\'; *pos++= '0'; break;
463 default:
464 *pos++= c;
465 break;
466 }
467 }
468 *pos++= '\'';
469 return pos;
470 }
471 #endif /* !MYSQL_CLIENT */
472
473
474 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
475
476 /**
477 Creates a temporary name for load data infile:.
478
479 @param buf Store new filename here
480 @param file_id File_id (part of file name)
481 @param event_server_id Event_id (part of file name)
482 @param ext Extension for file name
483
484 @return
485 Pointer to start of extension
486 */
487
slave_load_file_stem(char * buf,uint file_id,int event_server_id,const char * ext)488 static char *slave_load_file_stem(char *buf, uint file_id,
489 int event_server_id, const char *ext)
490 {
491 char *res;
492 fn_format(buf,PREFIX_SQL_LOAD,slave_load_tmpdir, "", MY_UNPACK_FILENAME);
493 to_unix_path(buf);
494
495 buf = strend(buf);
496 buf = int10_to_str(::server_id, buf, 10);
497 *buf++ = '-';
498 buf = int10_to_str(event_server_id, buf, 10);
499 *buf++ = '-';
500 res= int10_to_str(file_id, buf, 10);
501 strmov(res, ext); // Add extension last
502 return res; // Pointer to extension
503 }
504 #endif
505
506
507 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
508
509 /**
510 Delete all temporary files used for SQL_LOAD.
511 */
512
cleanup_load_tmpdir()513 static void cleanup_load_tmpdir()
514 {
515 MY_DIR *dirp;
516 FILEINFO *file;
517 uint i;
518 char fname[FN_REFLEN], prefbuf[31], *p;
519
520 if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
521 return;
522
523 /*
524 When we are deleting temporary files, we should only remove
525 the files associated with the server id of our server.
526 We don't use event_server_id here because since we've disabled
527 direct binlogging of Create_file/Append_file/Exec_load events
528 we cannot meet Start_log event in the middle of events from one
529 LOAD DATA.
530 */
531 p= strmake(prefbuf, STRING_WITH_LEN(PREFIX_SQL_LOAD));
532 p= int10_to_str(::server_id, p, 10);
533 *(p++)= '-';
534 *p= 0;
535
536 for (i=0 ; i < (uint)dirp->number_off_files; i++)
537 {
538 file=dirp->dir_entry+i;
539 if (is_prefix(file->name, prefbuf))
540 {
541 fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
542 mysql_file_delete(key_file_misc, fname, MYF(0));
543 }
544 }
545
546 my_dirend(dirp);
547 }
548 #endif
549
550
551 /*
552 write_str()
553 */
554
write_str(IO_CACHE * file,const char * str,uint length)555 static bool write_str(IO_CACHE *file, const char *str, uint length)
556 {
557 uchar tmp[1];
558 tmp[0]= (uchar) length;
559 return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
560 my_b_safe_write(file, (uchar*) str, length));
561 }
562
563
564 /*
565 read_str()
566 */
567
read_str(const char ** buf,const char * buf_end,const char ** str,uint8 * len)568 static inline int read_str(const char **buf, const char *buf_end,
569 const char **str, uint8 *len)
570 {
571 if (*buf + ((uint) (uchar) **buf) >= buf_end)
572 return 1;
573 *len= (uint8) **buf;
574 *str= (*buf)+1;
575 (*buf)+= (uint) *len+1;
576 return 0;
577 }
578
579
580 /**
581 Transforms a string into "" or its expression in 0x... form.
582 */
583
str_to_hex(char * to,const char * from,uint len)584 char *str_to_hex(char *to, const char *from, uint len)
585 {
586 if (len)
587 {
588 *to++= '0';
589 *to++= 'x';
590 to= octet2hex(to, from, len);
591 }
592 else
593 to= strmov(to, "\"\"");
594 return to; // pointer to end 0 of 'to'
595 }
596
597 #ifndef MYSQL_CLIENT
598
599 /**
600 Append a version of the 'from' string suitable for use in a query to
601 the 'to' string. To generate a correct escaping, the character set
602 information in 'csinfo' is used.
603 */
604
605 int
append_query_string(THD * thd,CHARSET_INFO * csinfo,String const * from,String * to)606 append_query_string(THD *thd, CHARSET_INFO *csinfo,
607 String const *from, String *to)
608 {
609 char *beg, *ptr;
610 uint32 const orig_len= to->length();
611 if (to->reserve(orig_len + from->length()*2+3))
612 return 1;
613
614 beg= to->c_ptr_quick() + to->length();
615 ptr= beg;
616 if (csinfo->escape_with_backslash_is_dangerous)
617 ptr= str_to_hex(ptr, from->ptr(), from->length());
618 else
619 {
620 *ptr++= '\'';
621 if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
622 {
623 ptr+= escape_string_for_mysql(csinfo, ptr, 0,
624 from->ptr(), from->length());
625 }
626 else
627 {
628 const char *frm_str= from->ptr();
629
630 for (; frm_str < (from->ptr() + from->length()); frm_str++)
631 {
632 /* Using '' way to represent "'" */
633 if (*frm_str == '\'')
634 *ptr++= *frm_str;
635
636 *ptr++= *frm_str;
637 }
638 }
639
640 *ptr++= '\'';
641 }
642 to->length(orig_len + ptr - beg);
643 return 0;
644 }
645 #endif
646
647
648 /**
649 Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
650 commands just before it prints a query.
651 */
652
653 #ifdef MYSQL_CLIENT
654
print_set_option(IO_CACHE * file,uint32 bits_changed,uint32 option,uint32 flags,const char * name,bool * need_comma)655 static void print_set_option(IO_CACHE* file, uint32 bits_changed,
656 uint32 option, uint32 flags, const char* name,
657 bool* need_comma)
658 {
659 if (bits_changed & option)
660 {
661 if (*need_comma)
662 my_b_printf(file,", ");
663 my_b_printf(file,"%s=%d", name, test(flags & option));
664 *need_comma= 1;
665 }
666 }
667 #endif
668
669 /**************************************************************************
670 Log_event methods (= the parent class of all events)
671 **************************************************************************/
672
673 /**
674 @return
675 returns the human readable name of the event's type
676 */
677
get_type_str(Log_event_type type)678 const char* Log_event::get_type_str(Log_event_type type)
679 {
680 switch(type) {
681 case START_EVENT_V3: return "Start_v3";
682 case STOP_EVENT: return "Stop";
683 case QUERY_EVENT: return "Query";
684 case ROTATE_EVENT: return "Rotate";
685 case INTVAR_EVENT: return "Intvar";
686 case LOAD_EVENT: return "Load";
687 case NEW_LOAD_EVENT: return "New_load";
688 case SLAVE_EVENT: return "Slave";
689 case CREATE_FILE_EVENT: return "Create_file";
690 case APPEND_BLOCK_EVENT: return "Append_block";
691 case DELETE_FILE_EVENT: return "Delete_file";
692 case EXEC_LOAD_EVENT: return "Exec_load";
693 case RAND_EVENT: return "RAND";
694 case XID_EVENT: return "Xid";
695 case USER_VAR_EVENT: return "User var";
696 case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
697 case TABLE_MAP_EVENT: return "Table_map";
698 case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
699 case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
700 case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
701 case WRITE_ROWS_EVENT: return "Write_rows";
702 case UPDATE_ROWS_EVENT: return "Update_rows";
703 case DELETE_ROWS_EVENT: return "Delete_rows";
704 case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
705 case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
706 case INCIDENT_EVENT: return "Incident";
707 default: return "Unknown"; /* impossible */
708 }
709 }
710
get_type_str()711 const char* Log_event::get_type_str()
712 {
713 return get_type_str(get_type_code());
714 }
715
716
717 /*
718 Log_event::Log_event()
719 */
720
721 #ifndef MYSQL_CLIENT
Log_event(THD * thd_arg,uint16 flags_arg,bool using_trans)722 Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
723 :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
724 cache_type(Log_event::EVENT_INVALID_CACHE), thd(thd_arg)
725 {
726 server_id= thd->server_id;
727 when= thd->start_time;
728
729 if (using_trans)
730 cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
731 else
732 cache_type= Log_event::EVENT_STMT_CACHE;
733 }
734
735 /**
736 This minimal constructor is for when you are not even sure that there
737 is a valid THD. For example in the server when we are shutting down or
738 flushing logs after receiving a SIGHUP (then we must write a Rotate to
739 the binlog but we have no THD, so we need this minimal constructor).
740 */
741
Log_event()742 Log_event::Log_event()
743 :temp_buf(0), exec_time(0), flags(0),
744 cache_type(Log_event::EVENT_INVALID_CACHE), thd(0)
745 {
746 server_id= ::server_id;
747 /*
748 We can't call my_time() here as this would cause a call before
749 my_init() is called
750 */
751 when= 0;
752 log_pos= 0;
753 }
754 #endif /* !MYSQL_CLIENT */
755
756
757 /*
758 Log_event::Log_event()
759 */
760
Log_event(const char * buf,const Format_description_log_event * description_event)761 Log_event::Log_event(const char* buf,
762 const Format_description_log_event* description_event)
763 :temp_buf(0), cache_type(Log_event::EVENT_INVALID_CACHE)
764 {
765 #ifndef MYSQL_CLIENT
766 thd = 0;
767 #endif
768 when = uint4korr(buf);
769 server_id = uint4korr(buf + SERVER_ID_OFFSET);
770 data_written= uint4korr(buf + EVENT_LEN_OFFSET);
771 if (description_event->binlog_version==1)
772 {
773 log_pos= 0;
774 flags= 0;
775 return;
776 }
777 /* 4.0 or newer */
778 log_pos= uint4korr(buf + LOG_POS_OFFSET);
779 /*
780 If the log is 4.0 (so here it can only be a 4.0 relay log read by
781 the SQL thread or a 4.0 master binlog read by the I/O thread),
782 log_pos is the beginning of the event: we transform it into the end
783 of the event, which is more useful.
784 But how do you know that the log is 4.0: you know it if
785 description_event is version 3 *and* you are not reading a
786 Format_desc (remember that mysqlbinlog starts by assuming that 5.0
787 logs are in 4.0 format, until it finds a Format_desc).
788 */
789 if (description_event->binlog_version==3 &&
790 buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
791 {
792 /*
793 If log_pos=0, don't change it. log_pos==0 is a marker to mean
794 "don't change rli->group_master_log_pos" (see
795 inc_group_relay_log_pos()). As it is unreal log_pos, adding the
796 event len's is nonsense. For example, a fake Rotate event should
797 not have its log_pos (which is 0) changed or it will modify
798 Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
799 value of (a non-zero offset which does not exist in the master's
800 binlog, so which will cause problems if the user uses this value
801 in CHANGE MASTER).
802 */
803 log_pos+= data_written; /* purecov: inspected */
804 }
805 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
806
807 flags= uint2korr(buf + FLAGS_OFFSET);
808 if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
809 (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
810 {
811 /*
812 These events always have a header which stops here (i.e. their
813 header is FROZEN).
814 */
815 /*
816 Initialization to zero of all other Log_event members as they're
817 not specified. Currently there are no such members; in the future
818 there will be an event UID (but Format_description and Rotate
819 don't need this UID, as they are not propagated through
820 --log-slave-updates (remember the UID is used to not play a query
821 twice when you have two masters which are slaves of a 3rd master).
822 Then we are done.
823 */
824 return;
825 }
826 /* otherwise, go on with reading the header from buf (nothing now) */
827 }
828
829 #ifndef MYSQL_CLIENT
830 #ifdef HAVE_REPLICATION
831
do_update_pos(Relay_log_info * rli)832 int Log_event::do_update_pos(Relay_log_info *rli)
833 {
834 /*
835 rli is null when (as far as I (Guilhem) know) the caller is
836 Load_log_event::do_apply_event *and* that one is called from
837 Execute_load_log_event::do_apply_event. In this case, we don't
838 do anything here ; Execute_load_log_event::do_apply_event will
839 call Log_event::do_apply_event again later with the proper rli.
840 Strictly speaking, if we were sure that rli is null only in the
841 case discussed above, 'if (rli)' is useless here. But as we are
842 not 100% sure, keep it for now.
843
844 Matz: I don't think we will need this check with this refactoring.
845 */
846 if (rli)
847 {
848 /*
849 bug#29309 simulation: resetting the flag to force
850 wrong behaviour of artificial event to update
851 rli->last_master_timestamp for only one time -
852 the first FLUSH LOGS in the test.
853 */
854 DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
855 if (debug_not_change_ts_if_art_event == 1
856 && is_artificial_event())
857 {
858 debug_not_change_ts_if_art_event= 0;
859 });
860 #ifndef DBUG_OFF
861 rli->stmt_done(log_pos,
862 is_artificial_event() &&
863 debug_not_change_ts_if_art_event > 0 ? 0 : when);
864 #else
865 rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
866 #endif
867 DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
868 if (debug_not_change_ts_if_art_event == 0)
869 {
870 debug_not_change_ts_if_art_event= 2;
871 });
872 }
873 return 0; // Cannot fail currently
874 }
875
876
877 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)878 Log_event::do_shall_skip(Relay_log_info *rli)
879 {
880 DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
881 " rli->replicate_same_server_id=%d,"
882 " rli->slave_skip_counter=%d",
883 (ulong) server_id, (ulong) ::server_id,
884 rli->replicate_same_server_id,
885 rli->slave_skip_counter));
886 if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
887 (rli->slave_skip_counter == 1 && rli->is_in_group()))
888 return EVENT_SKIP_IGNORE;
889 else if (rli->slave_skip_counter > 0)
890 return EVENT_SKIP_COUNT;
891 else
892 return EVENT_SKIP_NOT;
893 }
894
895
896 /*
897 Log_event::pack_info()
898 */
899
pack_info(Protocol * protocol)900 void Log_event::pack_info(Protocol *protocol)
901 {
902 protocol->store("", &my_charset_bin);
903 }
904
905
906 /**
907 Only called by SHOW BINLOG EVENTS
908 */
net_send(Protocol * protocol,const char * log_name,my_off_t pos)909 int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
910 {
911 const char *p= strrchr(log_name, FN_LIBCHAR);
912 const char *event_type;
913 if (p)
914 log_name = p + 1;
915
916 protocol->prepare_for_resend();
917 protocol->store(log_name, &my_charset_bin);
918 protocol->store((ulonglong) pos);
919 event_type = get_type_str();
920 protocol->store(event_type, strlen(event_type), &my_charset_bin);
921 protocol->store((uint32) server_id);
922 protocol->store((ulonglong) log_pos);
923 pack_info(protocol);
924 return protocol->write();
925 }
926 #endif /* HAVE_REPLICATION */
927
928
929 /**
930 init_show_field_list() prepares the column names and types for the
931 output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
932 EVENTS.
933 */
934
init_show_field_list(List<Item> * field_list)935 void Log_event::init_show_field_list(List<Item>* field_list)
936 {
937 field_list->push_back(new Item_empty_string("Log_name", 20));
938 field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
939 MYSQL_TYPE_LONGLONG));
940 field_list->push_back(new Item_empty_string("Event_type", 20));
941 field_list->push_back(new Item_return_int("Server_id", 10,
942 MYSQL_TYPE_LONG));
943 field_list->push_back(new Item_return_int("End_log_pos",
944 MY_INT32_NUM_DECIMAL_DIGITS,
945 MYSQL_TYPE_LONGLONG));
946 field_list->push_back(new Item_empty_string("Info", 20));
947 }
948
949
950 /*
951 Log_event::write()
952 */
953
write_header(IO_CACHE * file,ulong event_data_length)954 bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
955 {
956 uchar header[LOG_EVENT_HEADER_LEN];
957 ulong now;
958 DBUG_ENTER("Log_event::write_header");
959
960 /* Store number of bytes that will be written by this event */
961 data_written= event_data_length + sizeof(header);
962
963 /*
964 log_pos != 0 if this is relay-log event. In this case we should not
965 change the position
966 */
967
968 if (is_artificial_event())
969 {
970 /*
971 Artificial events are automatically generated and do not exist
972 in master's binary log, so log_pos should be set to 0.
973 */
974 log_pos= 0;
975 }
976 else if (!log_pos)
977 {
978 /*
979 Calculate position of end of event
980
981 Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
982 work well. So this will give slightly wrong positions for the
983 Format_desc/Rotate/Stop events which the slave writes to its
984 relay log. For example, the initial Format_desc will have
985 end_log_pos=91 instead of 95. Because after writing the first 4
986 bytes of the relay log, my_b_tell() still reports 0. Because
987 my_b_append() does not update the counter which my_b_tell()
988 later uses (one should probably use my_b_append_tell() to work
989 around this). To get right positions even when writing to the
990 relay log, we use the (new) my_b_safe_tell().
991
992 Note that this raises a question on the correctness of all these
993 DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
994
995 If in a transaction, the log_pos which we calculate below is not
996 very good (because then my_b_safe_tell() returns start position
997 of the BEGIN, so it's like the statement was at the BEGIN's
998 place), but it's not a very serious problem (as the slave, when
999 it is in a transaction, does not take those end_log_pos into
1000 account (as it calls inc_event_relay_log_pos()). To be fixed
1001 later, so that it looks less strange. But not bug.
1002 */
1003
1004 log_pos= my_b_safe_tell(file)+data_written;
1005 }
1006
1007 now= (ulong) get_time(); // Query start time
1008
1009 /*
1010 Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1011 FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1012 LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1013 because we read them before knowing the format).
1014 */
1015
1016 int4store(header, now); // timestamp
1017 header[EVENT_TYPE_OFFSET]= get_type_code();
1018 int4store(header+ SERVER_ID_OFFSET, server_id);
1019 int4store(header+ EVENT_LEN_OFFSET, data_written);
1020 int4store(header+ LOG_POS_OFFSET, log_pos);
1021 int2store(header+ FLAGS_OFFSET, flags);
1022
1023 DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0);
1024 }
1025
1026
1027 /**
1028 This needn't be format-tolerant, because we only read
1029 LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
1030 */
1031
read_log_event(IO_CACHE * file,String * packet,mysql_mutex_t * log_lock,const char * log_file_name_arg,bool * is_binlog_active)1032 int Log_event::read_log_event(IO_CACHE* file, String* packet,
1033 mysql_mutex_t* log_lock,
1034 const char *log_file_name_arg,
1035 bool* is_binlog_active)
1036 {
1037 ulong data_len;
1038 int result=0;
1039 char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1040 DBUG_ENTER("Log_event::read_log_event");
1041
1042 if (log_lock)
1043 mysql_mutex_lock(log_lock);
1044
1045 if (log_file_name_arg)
1046 *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
1047
1048 if (my_b_read(file, (uchar*) buf, sizeof(buf)))
1049 {
1050 /*
1051 If the read hits eof, we must report it as eof so the caller
1052 will know it can go into cond_wait to be woken up on the next
1053 update to the log.
1054 */
1055 DBUG_PRINT("error",("file->error: %d", file->error));
1056 if (!file->error)
1057 result= LOG_READ_EOF;
1058 else
1059 result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1060 goto end;
1061 }
1062 data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1063 if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
1064 data_len > current_thd->variables.max_allowed_packet)
1065 {
1066 DBUG_PRINT("error",("data_len: %ld", data_len));
1067 result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
1068 LOG_READ_TOO_LARGE);
1069 goto end;
1070 }
1071
1072 /* Append the log event header to packet */
1073 if (packet->append(buf, sizeof(buf)))
1074 {
1075 /* Failed to allocate packet */
1076 result= LOG_READ_MEM;
1077 goto end;
1078 }
1079 data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
1080 if (data_len)
1081 {
1082 /* Append rest of event, read directly from file into packet */
1083 if (packet->append(file, data_len))
1084 {
1085 /*
1086 Fatal error occured when appending rest of the event
1087 to packet, possible failures:
1088 1. EOF occured when reading from file, it's really an error
1089 as data_len is >=0 there's supposed to be more bytes available.
1090 file->error will have been set to number of bytes left to read
1091 2. Read was interrupted, file->error would normally be set to -1
1092 3. Failed to allocate memory for packet, my_errno
1093 will be ENOMEM(file->error shuold be 0, but since the
1094 memory allocation occurs before the call to read it might
1095 be uninitialized)
1096 */
1097 result= (my_errno == ENOMEM ? LOG_READ_MEM :
1098 (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1099 /* Implicit goto end; */
1100 }
1101 }
1102
1103 end:
1104 if (log_lock)
1105 mysql_mutex_unlock(log_lock);
1106 DBUG_RETURN(result);
1107 }
1108 #endif /* !MYSQL_CLIENT */
1109
1110 #ifndef MYSQL_CLIENT
1111 #define UNLOCK_MUTEX if (log_lock) mysql_mutex_unlock(log_lock);
1112 #define LOCK_MUTEX if (log_lock) mysql_mutex_lock(log_lock);
1113 #else
1114 #define UNLOCK_MUTEX
1115 #define LOCK_MUTEX
1116 #endif
1117
1118 #ifndef MYSQL_CLIENT
1119 /**
1120 @note
1121 Allocates memory; The caller is responsible for clean-up.
1122 */
read_log_event(IO_CACHE * file,mysql_mutex_t * log_lock,const Format_description_log_event * description_event)1123 Log_event* Log_event::read_log_event(IO_CACHE* file,
1124 mysql_mutex_t* log_lock,
1125 const Format_description_log_event
1126 *description_event)
1127 #else
1128 Log_event* Log_event::read_log_event(IO_CACHE* file,
1129 const Format_description_log_event
1130 *description_event)
1131 #endif
1132 {
1133 DBUG_ENTER("Log_event::read_log_event");
1134 DBUG_ASSERT(description_event != 0);
1135 char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1136 /*
1137 First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1138 check the event for sanity and to know its length; no need to really parse
1139 it. We say "at most" because this could be a 3.23 master, which has header
1140 of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
1141 "minimal" over the set {MySQL >=4.0}).
1142 */
1143 uint header_size= min(description_event->common_header_len,
1144 LOG_EVENT_MINIMAL_HEADER_LEN);
1145
1146 LOCK_MUTEX;
1147 DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
1148 if (my_b_read(file, (uchar *) head, header_size))
1149 {
1150 DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
1151 failed my_b_read"));
1152 UNLOCK_MUTEX;
1153 /*
1154 No error here; it could be that we are at the file's end. However
1155 if the next my_b_read() fails (below), it will be an error as we
1156 were able to read the first bytes.
1157 */
1158 DBUG_RETURN(0);
1159 }
1160 uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
1161 char *buf= 0;
1162 const char *error= 0;
1163 Log_event *res= 0;
1164 #ifndef max_allowed_packet
1165 THD *thd=current_thd;
1166 uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0;
1167 #endif
1168
1169 if (data_len > max_allowed_packet)
1170 {
1171 error = "Event too big";
1172 goto err;
1173 }
1174
1175 if (data_len < header_size)
1176 {
1177 error = "Event too small";
1178 goto err;
1179 }
1180
1181 // some events use the extra byte to null-terminate strings
1182 if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
1183 {
1184 error = "Out of memory";
1185 goto err;
1186 }
1187 buf[data_len] = 0;
1188 memcpy(buf, head, header_size);
1189 if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1190 {
1191 error = "read error";
1192 goto err;
1193 }
1194 if ((res= read_log_event(buf, data_len, &error, description_event)))
1195 res->register_temp_buf(buf);
1196
1197 err:
1198 UNLOCK_MUTEX;
1199 if (!res)
1200 {
1201 DBUG_ASSERT(error != 0);
1202 sql_print_error("Error in Log_event::read_log_event(): "
1203 "'%s', data_len: %d, event_type: %d",
1204 error,data_len,head[EVENT_TYPE_OFFSET]);
1205 my_free(buf);
1206 /*
1207 The SQL slave thread will check if file->error<0 to know
1208 if there was an I/O error. Even if there is no "low-level" I/O errors
1209 with 'file', any of the high-level above errors is worrying
1210 enough to stop the SQL thread now ; as we are skipping the current event,
1211 going on with reading and successfully executing other events can
1212 only corrupt the slave's databases. So stop.
1213 */
1214 file->error= -1;
1215 }
1216 DBUG_RETURN(res);
1217 }
1218
1219
1220 /**
1221 Binlog format tolerance is in (buf, event_len, description_event)
1222 constructors.
1223 */
1224
read_log_event(const char * buf,uint event_len,const char ** error,const Format_description_log_event * description_event)1225 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1226 const char **error,
1227 const Format_description_log_event *description_event)
1228 {
1229 Log_event* ev;
1230 DBUG_ENTER("Log_event::read_log_event(char*,...)");
1231 DBUG_ASSERT(description_event != 0);
1232 DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1233 DBUG_DUMP("data", (unsigned char*) buf, event_len);
1234
1235 /* Check the integrity */
1236 if (event_len < EVENT_LEN_OFFSET ||
1237 buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
1238 (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1239 {
1240 *error="Sanity check failed"; // Needed to free buffer
1241 DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1242 }
1243
1244 uint event_type= buf[EVENT_TYPE_OFFSET];
1245 if (event_type > description_event->number_of_event_types &&
1246 event_type != FORMAT_DESCRIPTION_EVENT)
1247 {
1248 /*
1249 It is unsafe to use the description_event if its post_header_len
1250 array does not include the event type.
1251 */
1252 DBUG_PRINT("error", ("event type %d found, but the current "
1253 "Format_description_log_event supports only %d event "
1254 "types", event_type,
1255 description_event->number_of_event_types));
1256 ev= NULL;
1257 }
1258 else
1259 {
1260 /*
1261 In some previuos versions (see comment in
1262 Format_description_log_event::Format_description_log_event(char*,...)),
1263 event types were assigned different id numbers than in the
1264 present version. In order to replicate from such versions to the
1265 present version, we must map those event type id's to our event
1266 type id's. The mapping is done with the event_type_permutation
1267 array, which was set up when the Format_description_log_event
1268 was read.
1269 */
1270 if (description_event->event_type_permutation)
1271 {
1272 int new_event_type= description_event->event_type_permutation[event_type];
1273 DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1274 event_type, new_event_type,
1275 get_type_str((Log_event_type)new_event_type)));
1276 event_type= new_event_type;
1277 }
1278
1279 switch(event_type) {
1280 case QUERY_EVENT:
1281 ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1282 break;
1283 case LOAD_EVENT:
1284 ev = new Load_log_event(buf, event_len, description_event);
1285 break;
1286 case NEW_LOAD_EVENT:
1287 ev = new Load_log_event(buf, event_len, description_event);
1288 break;
1289 case ROTATE_EVENT:
1290 ev = new Rotate_log_event(buf, event_len, description_event);
1291 break;
1292 #ifdef HAVE_REPLICATION
1293 case SLAVE_EVENT: /* can never happen (unused event) */
1294 ev = new Slave_log_event(buf, event_len, description_event);
1295 break;
1296 #endif /* HAVE_REPLICATION */
1297 case CREATE_FILE_EVENT:
1298 ev = new Create_file_log_event(buf, event_len, description_event);
1299 break;
1300 case APPEND_BLOCK_EVENT:
1301 ev = new Append_block_log_event(buf, event_len, description_event);
1302 break;
1303 case DELETE_FILE_EVENT:
1304 ev = new Delete_file_log_event(buf, event_len, description_event);
1305 break;
1306 case EXEC_LOAD_EVENT:
1307 ev = new Execute_load_log_event(buf, event_len, description_event);
1308 break;
1309 case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1310 ev = new Start_log_event_v3(buf, event_len, description_event);
1311 break;
1312 case STOP_EVENT:
1313 ev = new Stop_log_event(buf, description_event);
1314 break;
1315 case INTVAR_EVENT:
1316 ev = new Intvar_log_event(buf, description_event);
1317 break;
1318 case XID_EVENT:
1319 ev = new Xid_log_event(buf, description_event);
1320 break;
1321 case RAND_EVENT:
1322 ev = new Rand_log_event(buf, description_event);
1323 break;
1324 case USER_VAR_EVENT:
1325 ev = new User_var_log_event(buf, event_len, description_event);
1326 break;
1327 case FORMAT_DESCRIPTION_EVENT:
1328 ev = new Format_description_log_event(buf, event_len, description_event);
1329 break;
1330 #if defined(HAVE_REPLICATION)
1331 case PRE_GA_WRITE_ROWS_EVENT:
1332 ev = new Write_rows_log_event_old(buf, event_len, description_event);
1333 break;
1334 case PRE_GA_UPDATE_ROWS_EVENT:
1335 ev = new Update_rows_log_event_old(buf, event_len, description_event);
1336 break;
1337 case PRE_GA_DELETE_ROWS_EVENT:
1338 ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1339 break;
1340 case WRITE_ROWS_EVENT:
1341 ev = new Write_rows_log_event(buf, event_len, description_event);
1342 break;
1343 case UPDATE_ROWS_EVENT:
1344 ev = new Update_rows_log_event(buf, event_len, description_event);
1345 break;
1346 case DELETE_ROWS_EVENT:
1347 ev = new Delete_rows_log_event(buf, event_len, description_event);
1348 break;
1349 case TABLE_MAP_EVENT:
1350 ev = new Table_map_log_event(buf, event_len, description_event);
1351 break;
1352 #endif
1353 case BEGIN_LOAD_QUERY_EVENT:
1354 ev = new Begin_load_query_log_event(buf, event_len, description_event);
1355 break;
1356 case EXECUTE_LOAD_QUERY_EVENT:
1357 ev= new Execute_load_query_log_event(buf, event_len, description_event);
1358 break;
1359 case INCIDENT_EVENT:
1360 ev = new Incident_log_event(buf, event_len, description_event);
1361 break;
1362 default:
1363 DBUG_PRINT("error",("Unknown event code: %d",
1364 (int) buf[EVENT_TYPE_OFFSET]));
1365 ev= NULL;
1366 break;
1367 }
1368 }
1369
1370 DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1371 ev ? ev->get_type_str() : "<unknown>",
1372 buf[EVENT_TYPE_OFFSET],
1373 event_len));
1374 /*
1375 is_valid() are small event-specific sanity tests which are
1376 important; for example there are some my_malloc() in constructors
1377 (e.g. Query_log_event::Query_log_event(char*...)); when these
1378 my_malloc() fail we can't return an error out of the constructor
1379 (because constructor is "void") ; so instead we leave the pointer we
1380 wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1381 Same for Format_description_log_event, member 'post_header_len'.
1382
1383 SLAVE_EVENT is never used, so it should not be read ever.
1384 */
1385 if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
1386 {
1387 DBUG_PRINT("error",("Found invalid event in binary log"));
1388
1389 delete ev;
1390 #ifdef MYSQL_CLIENT
1391 if (!force_opt) /* then mysqlbinlog dies */
1392 {
1393 *error= "Found invalid event in binary log";
1394 DBUG_RETURN(0);
1395 }
1396 ev= new Unknown_log_event(buf, description_event);
1397 #else
1398 *error= "Found invalid event in binary log";
1399 DBUG_RETURN(0);
1400 #endif
1401 }
1402 DBUG_RETURN(ev);
1403 }
1404
1405 #ifdef MYSQL_CLIENT
1406
1407 /*
1408 Log_event::print_header()
1409 */
1410
print_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool is_more)1411 void Log_event::print_header(IO_CACHE* file,
1412 PRINT_EVENT_INFO* print_event_info,
1413 bool is_more __attribute__((unused)))
1414 {
1415 char llbuff[22];
1416 my_off_t hexdump_from= print_event_info->hexdump_from;
1417 DBUG_ENTER("Log_event::print_header");
1418
1419 my_b_printf(file, "#");
1420 print_timestamp(file);
1421 my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
1422 llstr(log_pos,llbuff));
1423
1424 /* mysqlbinlog --hexdump */
1425 if (print_event_info->hexdump_from)
1426 {
1427 my_b_printf(file, "\n");
1428 uchar *ptr= (uchar*)temp_buf;
1429 my_off_t size=
1430 uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1431 my_off_t i;
1432
1433 /* Header len * 4 >= header len * (2 chars + space + extra space) */
1434 char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
1435 char *c, char_string[16+1]= {0};
1436
1437 /* Pretty-print event common header if header is exactly 19 bytes */
1438 if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1439 {
1440 char emit_buf[256]; // Enough for storing one line
1441 my_b_printf(file, "# Position Timestamp Type Master ID "
1442 "Size Master Pos Flags \n");
1443 size_t const bytes_written=
1444 my_snprintf(emit_buf, sizeof(emit_buf),
1445 "# %8.8lx %02x %02x %02x %02x %02x "
1446 "%02x %02x %02x %02x %02x %02x %02x %02x "
1447 "%02x %02x %02x %02x %02x %02x\n",
1448 (unsigned long) hexdump_from,
1449 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1450 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1451 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1452 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1453 my_b_write(file, (uchar*) emit_buf, bytes_written);
1454 ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1455 hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1456 }
1457
1458 /* Rest of event (without common header) */
1459 for (i= 0, c= char_string, h=hex_string;
1460 i < size;
1461 i++, ptr++)
1462 {
1463 my_snprintf(h, 4, "%02x ", *ptr);
1464 h += 3;
1465
1466 *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1467
1468 if (i % 16 == 15)
1469 {
1470 /*
1471 my_b_printf() does not support full printf() formats, so we
1472 have to do it this way.
1473
1474 TODO: Rewrite my_b_printf() to support full printf() syntax.
1475 */
1476 char emit_buf[256];
1477 size_t const bytes_written=
1478 my_snprintf(emit_buf, sizeof(emit_buf),
1479 "# %8.8lx %-48.48s |%16s|\n",
1480 (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1481 hex_string, char_string);
1482 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1483 my_b_write(file, (uchar*) emit_buf, bytes_written);
1484 hex_string[0]= 0;
1485 char_string[0]= 0;
1486 c= char_string;
1487 h= hex_string;
1488 }
1489 else if (i % 8 == 7) *h++ = ' ';
1490 }
1491 *c= '\0';
1492
1493 if (hex_string[0])
1494 {
1495 char emit_buf[256];
1496 size_t const bytes_written=
1497 my_snprintf(emit_buf, sizeof(emit_buf),
1498 "# %8.8lx %-48.48s |%s|\n",
1499 (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1500 hex_string, char_string);
1501 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1502 my_b_write(file, (uchar*) emit_buf, bytes_written);
1503 }
1504 /*
1505 need a # to prefix the rest of printouts for example those of
1506 Rows_log_event::print_helper().
1507 */
1508 my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1509 }
1510 DBUG_VOID_RETURN;
1511 }
1512
1513
1514 /**
1515 Prints a quoted string to io cache.
1516 Control characters are displayed as hex sequence, e.g. \x00
1517
1518 @param[in] file IO cache
1519 @param[in] prt Pointer to string
1520 @param[in] length String length
1521 */
1522
1523 static void
my_b_write_quoted(IO_CACHE * file,const uchar * ptr,uint length)1524 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
1525 {
1526 const uchar *s;
1527 my_b_printf(file, "'");
1528 for (s= ptr; length > 0 ; s++, length--)
1529 {
1530 if (*s > 0x1F)
1531 my_b_write(file, s, 1);
1532 else
1533 {
1534 uchar hex[10];
1535 size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
1536 my_b_write(file, hex, len);
1537 }
1538 }
1539 my_b_printf(file, "'");
1540 }
1541
1542
1543 /**
1544 Prints a bit string to io cache in format b'1010'.
1545
1546 @param[in] file IO cache
1547 @param[in] ptr Pointer to string
1548 @param[in] nbits Number of bits
1549 */
1550 static void
my_b_write_bit(IO_CACHE * file,const uchar * ptr,uint nbits)1551 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
1552 {
1553 uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
1554 my_b_printf(file, "b'");
1555 for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
1556 {
1557 int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
1558 my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
1559 }
1560 my_b_printf(file, "'");
1561 }
1562
1563
1564 /**
1565 Prints a packed string to io cache.
1566 The string consists of length packed to 1 or 2 bytes,
1567 followed by string data itself.
1568
1569 @param[in] file IO cache
1570 @param[in] ptr Pointer to string
1571 @param[in] length String size
1572
1573 @retval - number of bytes scanned.
1574 */
1575 static size_t
my_b_write_quoted_with_length(IO_CACHE * file,const uchar * ptr,uint length)1576 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
1577 {
1578 if (length < 256)
1579 {
1580 length= *ptr;
1581 my_b_write_quoted(file, ptr + 1, length);
1582 return length + 1;
1583 }
1584 else
1585 {
1586 length= uint2korr(ptr);
1587 my_b_write_quoted(file, ptr + 2, length);
1588 return length + 2;
1589 }
1590 }
1591
1592
1593 /**
1594 Prints a 32-bit number in both signed and unsigned representation
1595
1596 @param[in] file IO cache
1597 @param[in] sl Signed number
1598 @param[in] ul Unsigned number
1599 */
1600 static void
my_b_write_sint32_and_uint32(IO_CACHE * file,int32 si,uint32 ui)1601 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
1602 {
1603 my_b_printf(file, "%d", si);
1604 if (si < 0)
1605 my_b_printf(file, " (%u)", ui);
1606 }
1607
1608
1609 /**
1610 Print a packed value of the given SQL type into IO cache
1611
1612 @param[in] file IO cache
1613 @param[in] ptr Pointer to string
1614 @param[in] type Column type
1615 @param[in] meta Column meta information
1616 @param[out] typestr SQL type string buffer (for verbose output)
1617 @param[out] typestr_length Size of typestr
1618
1619 @retval - number of bytes scanned from ptr.
1620 */
1621
1622 static size_t
log_event_print_value(IO_CACHE * file,const uchar * ptr,uint type,uint meta,char * typestr,size_t typestr_length)1623 log_event_print_value(IO_CACHE *file, const uchar *ptr,
1624 uint type, uint meta,
1625 char *typestr, size_t typestr_length)
1626 {
1627 uint32 length= 0;
1628
1629 if (type == MYSQL_TYPE_STRING)
1630 {
1631 if (meta >= 256)
1632 {
1633 uint byte0= meta >> 8;
1634 uint byte1= meta & 0xFF;
1635
1636 if ((byte0 & 0x30) != 0x30)
1637 {
1638 /* a long CHAR() field: see #37426 */
1639 length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
1640 type= byte0 | 0x30;
1641 }
1642 else
1643 length = meta & 0xFF;
1644 }
1645 else
1646 length= meta;
1647 }
1648
1649 switch (type) {
1650 case MYSQL_TYPE_LONG:
1651 {
1652 int32 si= sint4korr(ptr);
1653 uint32 ui= uint4korr(ptr);
1654 my_b_write_sint32_and_uint32(file, si, ui);
1655 my_snprintf(typestr, typestr_length, "INT");
1656 return 4;
1657 }
1658
1659 case MYSQL_TYPE_TINY:
1660 {
1661 my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
1662 (uint) (unsigned char) *ptr);
1663 my_snprintf(typestr, typestr_length, "TINYINT");
1664 return 1;
1665 }
1666
1667 case MYSQL_TYPE_SHORT:
1668 {
1669 int32 si= (int32) sint2korr(ptr);
1670 uint32 ui= (uint32) uint2korr(ptr);
1671 my_b_write_sint32_and_uint32(file, si, ui);
1672 my_snprintf(typestr, typestr_length, "SHORTINT");
1673 return 2;
1674 }
1675
1676 case MYSQL_TYPE_INT24:
1677 {
1678 int32 si= sint3korr(ptr);
1679 uint32 ui= uint3korr(ptr);
1680 my_b_write_sint32_and_uint32(file, si, ui);
1681 my_snprintf(typestr, typestr_length, "MEDIUMINT");
1682 return 3;
1683 }
1684
1685 case MYSQL_TYPE_LONGLONG:
1686 {
1687 char tmp[64];
1688 longlong si= sint8korr(ptr);
1689 longlong10_to_str(si, tmp, -10);
1690 my_b_printf(file, "%s", tmp);
1691 if (si < 0)
1692 {
1693 ulonglong ui= uint8korr(ptr);
1694 longlong10_to_str((longlong) ui, tmp, 10);
1695 my_b_printf(file, " (%s)", tmp);
1696 }
1697 my_snprintf(typestr, typestr_length, "LONGINT");
1698 return 8;
1699 }
1700
1701 case MYSQL_TYPE_NEWDECIMAL:
1702 {
1703 uint precision= meta >> 8;
1704 uint decimals= meta & 0xFF;
1705 uint bin_size= my_decimal_get_binary_size(precision, decimals);
1706 my_decimal dec;
1707 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
1708 precision, decimals);
1709 int i, end;
1710 char buff[512], *pos;
1711 pos= buff;
1712 pos+= sprintf(buff, "%s", dec.sign() ? "-" : "");
1713 end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
1714 for (i=0; i < end; i++)
1715 pos+= sprintf(pos, "%09d.", dec.buf[i]);
1716 pos+= sprintf(pos, "%09d", dec.buf[i]);
1717 my_b_printf(file, "%s", buff);
1718 my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
1719 precision, decimals);
1720 return bin_size;
1721 }
1722
1723 case MYSQL_TYPE_FLOAT:
1724 {
1725 float fl;
1726 float4get(fl, ptr);
1727 char tmp[320];
1728 sprintf(tmp, "%-20g", (double) fl);
1729 my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
1730 my_snprintf(typestr, typestr_length, "FLOAT");
1731 return 4;
1732 }
1733
1734 case MYSQL_TYPE_DOUBLE:
1735 {
1736 double dbl;
1737 float8get(dbl, ptr);
1738 char tmp[320];
1739 sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
1740 my_b_printf(file, "%s", tmp);
1741 strcpy(typestr, "DOUBLE");
1742 return 8;
1743 }
1744
1745 case MYSQL_TYPE_BIT:
1746 {
1747 /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
1748 uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
1749 length= (nbits + 7) / 8;
1750 my_b_write_bit(file, ptr, nbits);
1751 my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
1752 return length;
1753 }
1754
1755 case MYSQL_TYPE_TIMESTAMP:
1756 {
1757 uint32 i32= uint4korr(ptr);
1758 my_b_printf(file, "%d", i32);
1759 my_snprintf(typestr, typestr_length, "TIMESTAMP");
1760 return 4;
1761 }
1762
1763 case MYSQL_TYPE_DATETIME:
1764 {
1765 size_t d, t;
1766 uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
1767 d= i64 / 1000000;
1768 t= i64 % 1000000;
1769 my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
1770 d / 10000, (d % 10000) / 100, d % 100,
1771 t / 10000, (t % 10000) / 100, t % 100);
1772 my_snprintf(typestr, typestr_length, "DATETIME");
1773 return 8;
1774 }
1775
1776 case MYSQL_TYPE_TIME:
1777 {
1778 uint32 i32= uint3korr(ptr);
1779 my_b_printf(file, "'%02d:%02d:%02d'",
1780 i32 / 10000, (i32 % 10000) / 100, i32 % 100);
1781 my_snprintf(typestr, typestr_length, "TIME");
1782 return 3;
1783 }
1784
1785 case MYSQL_TYPE_NEWDATE:
1786 {
1787 uint32 tmp= uint3korr(ptr);
1788 int part;
1789 char buf[11];
1790 char *pos= &buf[10]; // start from '\0' to the beginning
1791
1792 /* Copied from field.cc */
1793 *pos--=0; // End NULL
1794 part=(int) (tmp & 31);
1795 *pos--= (char) ('0'+part%10);
1796 *pos--= (char) ('0'+part/10);
1797 *pos--= ':';
1798 part=(int) (tmp >> 5 & 15);
1799 *pos--= (char) ('0'+part%10);
1800 *pos--= (char) ('0'+part/10);
1801 *pos--= ':';
1802 part=(int) (tmp >> 9);
1803 *pos--= (char) ('0'+part%10); part/=10;
1804 *pos--= (char) ('0'+part%10); part/=10;
1805 *pos--= (char) ('0'+part%10); part/=10;
1806 *pos= (char) ('0'+part);
1807 my_b_printf(file , "'%s'", buf);
1808 my_snprintf(typestr, typestr_length, "DATE");
1809 return 3;
1810 }
1811
1812 case MYSQL_TYPE_DATE:
1813 {
1814 uint i32= uint3korr(ptr);
1815 my_b_printf(file , "'%04d:%02d:%02d'",
1816 (i32 / (16L * 32L)), (i32 / 32L % 16L), (i32 % 32L));
1817 my_snprintf(typestr, typestr_length, "DATE");
1818 return 3;
1819 }
1820
1821 case MYSQL_TYPE_YEAR:
1822 {
1823 uint32 i32= *ptr;
1824 my_b_printf(file, "%04d", i32+ 1900);
1825 my_snprintf(typestr, typestr_length, "YEAR");
1826 return 1;
1827 }
1828
1829 case MYSQL_TYPE_ENUM:
1830 switch (meta & 0xFF) {
1831 case 1:
1832 my_b_printf(file, "%d", (int) *ptr);
1833 my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
1834 return 1;
1835 case 2:
1836 {
1837 int32 i32= uint2korr(ptr);
1838 my_b_printf(file, "%d", i32);
1839 my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
1840 return 2;
1841 }
1842 default:
1843 my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
1844 return 0;
1845 }
1846 break;
1847
1848 case MYSQL_TYPE_SET:
1849 my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
1850 my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
1851 return meta & 0xFF;
1852
1853 case MYSQL_TYPE_BLOB:
1854 switch (meta) {
1855 case 1:
1856 length= *ptr;
1857 my_b_write_quoted(file, ptr + 1, length);
1858 my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
1859 return length + 1;
1860 case 2:
1861 length= uint2korr(ptr);
1862 my_b_write_quoted(file, ptr + 2, length);
1863 my_snprintf(typestr, typestr_length, "BLOB/TEXT");
1864 return length + 2;
1865 case 3:
1866 length= uint3korr(ptr);
1867 my_b_write_quoted(file, ptr + 3, length);
1868 my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
1869 return length + 3;
1870 case 4:
1871 length= uint4korr(ptr);
1872 my_b_write_quoted(file, ptr + 4, length);
1873 my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
1874 return length + 4;
1875 default:
1876 my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
1877 return 0;
1878 }
1879
1880 case MYSQL_TYPE_VARCHAR:
1881 case MYSQL_TYPE_VAR_STRING:
1882 length= meta;
1883 my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
1884 return my_b_write_quoted_with_length(file, ptr, length);
1885
1886 case MYSQL_TYPE_STRING:
1887 my_snprintf(typestr, typestr_length, "STRING(%d)", length);
1888 return my_b_write_quoted_with_length(file, ptr, length);
1889
1890 default:
1891 {
1892 char tmp[5];
1893 my_snprintf(tmp, sizeof(tmp), "%04x", meta);
1894 my_b_printf(file,
1895 "!! Don't know how to handle column type=%d meta=%d (%s)",
1896 type, meta, tmp);
1897 }
1898 break;
1899 }
1900 *typestr= 0;
1901 return 0;
1902 }
1903
1904
1905 /**
1906 Print a packed row into IO cache
1907
1908 @param[in] file IO cache
1909 @param[in] td Table definition
1910 @param[in] print_event_into Print parameters
1911 @param[in] cols_bitmap Column bitmaps.
1912 @param[in] value Pointer to packed row
1913 @param[in] prefix Row's SQL clause ("SET", "WHERE", etc)
1914
1915 @retval - number of bytes scanned.
1916 */
1917
1918
1919 size_t
print_verbose_one_row(IO_CACHE * file,table_def * td,PRINT_EVENT_INFO * print_event_info,MY_BITMAP * cols_bitmap,const uchar * value,const uchar * prefix)1920 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
1921 PRINT_EVENT_INFO *print_event_info,
1922 MY_BITMAP *cols_bitmap,
1923 const uchar *value, const uchar *prefix)
1924 {
1925 const uchar *value0= value;
1926 const uchar *null_bits= value;
1927 uint null_bit_index= 0;
1928 char typestr[64]= "";
1929
1930 value+= (m_width + 7) / 8;
1931
1932 my_b_printf(file, "%s", prefix);
1933
1934 for (size_t i= 0; i < td->size(); i ++)
1935 {
1936 int is_null= (null_bits[null_bit_index / 8]
1937 >> (null_bit_index % 8)) & 0x01;
1938
1939 if (bitmap_is_set(cols_bitmap, i) == 0)
1940 continue;
1941
1942 if (is_null)
1943 {
1944 my_b_printf(file, "### @%d=NULL", i + 1);
1945 }
1946 else
1947 {
1948 my_b_printf(file, "### @%d=", i + 1);
1949 size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
1950 if (value + fsize > m_rows_end)
1951 {
1952 my_b_printf(file, "***Corrupted replication event was detected."
1953 " Not printing the value***\n");
1954 value+= fsize;
1955 return 0;
1956 }
1957 size_t size= log_event_print_value(file, value,
1958 td->type(i), td->field_metadata(i),
1959 typestr, sizeof(typestr));
1960 if (!size)
1961 return 0;
1962
1963 value+= size;
1964 }
1965
1966 if (print_event_info->verbose > 1)
1967 {
1968 my_b_printf(file, " /* ");
1969
1970 if (typestr[0])
1971 my_b_printf(file, "%s ", typestr);
1972 else
1973 my_b_printf(file, "type=%d ", td->type(i));
1974
1975 my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
1976 td->field_metadata(i),
1977 td->maybe_null(i), is_null);
1978 my_b_printf(file, "*/");
1979 }
1980
1981 my_b_printf(file, "\n");
1982
1983 null_bit_index++;
1984 }
1985 return value - value0;
1986 }
1987
1988
1989 /**
1990 Print a row event into IO cache in human readable form (in SQL format)
1991
1992 @param[in] file IO cache
1993 @param[in] print_event_into Print parameters
1994 */
print_verbose(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)1995 void Rows_log_event::print_verbose(IO_CACHE *file,
1996 PRINT_EVENT_INFO *print_event_info)
1997 {
1998 // Quoted length of the identifier can be twice the original length
1999 char quoted_db[1 + NAME_LEN * 2 + 2];
2000 char quoted_table[1 + NAME_LEN * 2 + 2];
2001 int quoted_db_len, quoted_table_len;
2002 Table_map_log_event *map;
2003 table_def *td;
2004 const char *sql_command, *sql_clause1, *sql_clause2;
2005 Log_event_type type_code= get_type_code();
2006
2007 switch (type_code) {
2008 case WRITE_ROWS_EVENT:
2009 sql_command= "INSERT INTO";
2010 sql_clause1= "### SET\n";
2011 sql_clause2= NULL;
2012 break;
2013 case DELETE_ROWS_EVENT:
2014 sql_command= "DELETE FROM";
2015 sql_clause1= "### WHERE\n";
2016 sql_clause2= NULL;
2017 break;
2018 case UPDATE_ROWS_EVENT:
2019 sql_command= "UPDATE";
2020 sql_clause1= "### WHERE\n";
2021 sql_clause2= "### SET\n";
2022 break;
2023 default:
2024 sql_command= sql_clause1= sql_clause2= NULL;
2025 DBUG_ASSERT(0); /* Not possible */
2026 }
2027
2028 if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2029 !(td= map->create_table_def()))
2030 {
2031 my_b_printf(file, "### Row event for unknown table #%d", m_table_id);
2032 return;
2033 }
2034
2035 for (const uchar *value= m_rows_buf; value < m_rows_end; )
2036 {
2037 size_t length;
2038 #ifdef MYSQL_SERVER
2039 quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2040 map->get_db_name(), 0);
2041 quoted_table_len= my_strmov_quoted_identifier(this->thd,
2042 (char *) quoted_table,
2043 map->get_table_name(), 0);
2044 #else
2045 quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2046 map->get_db_name());
2047 quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2048 map->get_table_name());
2049 #endif
2050 quoted_db[quoted_db_len]= '\0';
2051 quoted_table[quoted_table_len]= '\0';
2052 my_b_printf(file, "### %s %s.%s\n",
2053 sql_command,
2054 quoted_db, quoted_table);
2055 /* Print the first image */
2056 if (!(length= print_verbose_one_row(file, td, print_event_info,
2057 &m_cols, value,
2058 (const uchar*) sql_clause1)))
2059 goto end;
2060 value+= length;
2061
2062 /* Print the second image (for UPDATE only) */
2063 if (sql_clause2)
2064 {
2065 if (!(length= print_verbose_one_row(file, td, print_event_info,
2066 &m_cols_ai, value,
2067 (const uchar*) sql_clause2)))
2068 goto end;
2069 value+= length;
2070 }
2071 }
2072
2073 end:
2074 delete td;
2075 }
2076
2077 #ifdef MYSQL_CLIENT
free_table_map_log_event(Table_map_log_event * event)2078 void free_table_map_log_event(Table_map_log_event *event)
2079 {
2080 delete event;
2081 }
2082 #endif
2083
print_base64(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool more)2084 void Log_event::print_base64(IO_CACHE* file,
2085 PRINT_EVENT_INFO* print_event_info,
2086 bool more)
2087 {
2088 const uchar *ptr= (const uchar *)temp_buf;
2089 uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2090 DBUG_ENTER("Log_event::print_base64");
2091
2092 size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
2093 char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
2094 if (!tmp_str) {
2095 fprintf(stderr, "\nError: Out of memory. "
2096 "Could not print correct binlog event.\n");
2097 DBUG_VOID_RETURN;
2098 }
2099
2100 if (base64_encode(ptr, (size_t) size, tmp_str))
2101 {
2102 DBUG_ASSERT(0);
2103 }
2104
2105 if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2106 {
2107 if (my_b_tell(file) == 0)
2108 my_b_printf(file, "\nBINLOG '\n");
2109
2110 my_b_printf(file, "%s\n", tmp_str);
2111
2112 if (!more)
2113 my_b_printf(file, "'%s\n", print_event_info->delimiter);
2114 }
2115
2116 if (print_event_info->verbose)
2117 {
2118 Rows_log_event *ev= NULL;
2119
2120 if (ptr[4] == TABLE_MAP_EVENT)
2121 {
2122 Table_map_log_event *map;
2123 map= new Table_map_log_event((const char*) ptr, size,
2124 glob_description_event);
2125 print_event_info->m_table_map.set_table(map->get_table_id(), map);
2126 }
2127 else if (ptr[4] == WRITE_ROWS_EVENT)
2128 {
2129 ev= new Write_rows_log_event((const char*) ptr, size,
2130 glob_description_event);
2131 }
2132 else if (ptr[4] == DELETE_ROWS_EVENT)
2133 {
2134 ev= new Delete_rows_log_event((const char*) ptr, size,
2135 glob_description_event);
2136 }
2137 else if (ptr[4] == UPDATE_ROWS_EVENT)
2138 {
2139 ev= new Update_rows_log_event((const char*) ptr, size,
2140 glob_description_event);
2141 }
2142
2143 if (ev)
2144 {
2145 ev->print_verbose(file, print_event_info);
2146 delete ev;
2147 }
2148 }
2149
2150 my_free(tmp_str);
2151 DBUG_VOID_RETURN;
2152 }
2153
2154
2155 /*
2156 Log_event::print_timestamp()
2157 */
2158
print_timestamp(IO_CACHE * file,time_t * ts)2159 void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
2160 {
2161 struct tm *res;
2162 DBUG_ENTER("Log_event::print_timestamp");
2163 if (!ts)
2164 ts = &when;
2165 struct tm tm_tmp;
2166 localtime_r(ts,(res= &tm_tmp));
2167 my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2168 res->tm_year % 100,
2169 res->tm_mon+1,
2170 res->tm_mday,
2171 res->tm_hour,
2172 res->tm_min,
2173 res->tm_sec);
2174 DBUG_VOID_RETURN;
2175 }
2176
2177 #endif /* MYSQL_CLIENT */
2178
2179
2180 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2181 inline Log_event::enum_skip_reason
continue_group(Relay_log_info * rli)2182 Log_event::continue_group(Relay_log_info *rli)
2183 {
2184 if (rli->slave_skip_counter == 1)
2185 return Log_event::EVENT_SKIP_IGNORE;
2186 return Log_event::do_shall_skip(rli);
2187 }
2188 #endif
2189
2190 /**************************************************************************
2191 Query_log_event methods
2192 **************************************************************************/
2193
2194 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2195
2196 /**
2197 This (which is used only for SHOW BINLOG EVENTS) could be updated to
2198 print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
2199 only an information, it does not produce suitable queries to replay (for
2200 example it does not print LOAD DATA INFILE).
2201 @todo
2202 show the catalog ??
2203 */
2204
pack_info(Protocol * protocol)2205 void Query_log_event::pack_info(Protocol *protocol)
2206 {
2207 // TODO: show the catalog ??
2208 String temp_buf;
2209 // Add use `DB` to the string if required
2210 if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
2211 && db && db_len)
2212 {
2213 temp_buf.append("use ");
2214 append_identifier(this->thd, &temp_buf, db, db_len);
2215 temp_buf.append("; ");
2216 }
2217 // Add the query to the string
2218 if (query && q_len)
2219 temp_buf.append(query);
2220 // persist the buffer in protocol
2221 protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
2222 }
2223 #endif
2224
2225 #ifndef MYSQL_CLIENT
2226
2227 /**
2228 Utility function for the next method (Query_log_event::write()) .
2229 */
write_str_with_code_and_len(uchar ** dst,const char * src,uint len,uint code)2230 static void write_str_with_code_and_len(uchar **dst, const char *src,
2231 uint len, uint code)
2232 {
2233 /*
2234 only 1 byte to store the length of catalog, so it should not
2235 surpass 255
2236 */
2237 DBUG_ASSERT(len <= 255);
2238 DBUG_ASSERT(src);
2239 *((*dst)++)= code;
2240 *((*dst)++)= (uchar) len;
2241 bmove(*dst, src, len);
2242 (*dst)+= len;
2243 }
2244
2245
2246 /**
2247 Query_log_event::write().
2248
2249 @note
2250 In this event we have to modify the header to have the correct
2251 EVENT_LEN_OFFSET as we don't yet know how many status variables we
2252 will print!
2253 */
2254
write(IO_CACHE * file)2255 bool Query_log_event::write(IO_CACHE* file)
2256 {
2257 uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
2258 uchar *start, *start_of_status;
2259 ulong event_length;
2260
2261 if (!query)
2262 return 1; // Something wrong with event
2263
2264 /*
2265 We want to store the thread id:
2266 (- as an information for the user when he reads the binlog)
2267 - if the query uses temporary table: for the slave SQL thread to know to
2268 which master connection the temp table belongs.
2269 Now imagine we (write()) are called by the slave SQL thread (we are
2270 logging a query executed by this thread; the slave runs with
2271 --log-slave-updates). Then this query will be logged with
2272 thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
2273 the same name were created simultaneously on the master (in the master
2274 binlog you have
2275 CREATE TEMPORARY TABLE t; (thread 1)
2276 CREATE TEMPORARY TABLE t; (thread 2)
2277 ...)
2278 then in the slave's binlog there will be
2279 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
2280 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
2281 which is bad (same thread id!).
2282
2283 To avoid this, we log the thread's thread id EXCEPT for the SQL
2284 slave thread for which we log the original (master's) thread id.
2285 Now this moves the bug: what happens if the thread id on the
2286 master was 10 and when the slave replicates the query, a
2287 connection number 10 is opened by a normal client on the slave,
2288 and updates a temp table of the same name? We get a problem
2289 again. To avoid this, in the handling of temp tables (sql_base.cc)
2290 we use thread_id AND server_id. TODO when this is merged into
2291 4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
2292 and is a session variable: that's to make mysqlbinlog work with
2293 temp tables. We probably need to introduce
2294
2295 SET PSEUDO_SERVER_ID
2296 for mysqlbinlog in 4.1. mysqlbinlog would print:
2297 SET PSEUDO_SERVER_ID=
2298 SET PSEUDO_THREAD_ID=
2299 for each query using temp tables.
2300 */
2301 int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
2302 int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
2303 buf[Q_DB_LEN_OFFSET] = (char) db_len;
2304 int2store(buf + Q_ERR_CODE_OFFSET, error_code);
2305
2306 /*
2307 You MUST always write status vars in increasing order of code. This
2308 guarantees that a slightly older slave will be able to parse those he
2309 knows.
2310 */
2311 start_of_status= start= buf+QUERY_HEADER_LEN;
2312 if (flags2_inited)
2313 {
2314 *start++= Q_FLAGS2_CODE;
2315 int4store(start, flags2);
2316 start+= 4;
2317 }
2318 if (sql_mode_inited)
2319 {
2320 *start++= Q_SQL_MODE_CODE;
2321 int8store(start, (ulonglong)sql_mode);
2322 start+= 8;
2323 }
2324 if (catalog_len) // i.e. this var is inited (false for 4.0 events)
2325 {
2326 write_str_with_code_and_len(&start,
2327 catalog, catalog_len, Q_CATALOG_NZ_CODE);
2328 /*
2329 In 5.0.x where x<4 masters we used to store the end zero here. This was
2330 a waste of one byte so we don't do it in x>=4 masters. We change code to
2331 Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
2332 of this x>=4 master segfault (expecting a zero when there is
2333 none). Remaining compatibility problems are: the older slave will not
2334 find the catalog; but it is will not crash, and it's not an issue
2335 that it does not find the catalog as catalogs were not used in these
2336 older MySQL versions (we store it in binlog and read it from relay log
2337 but do nothing useful with it). What is an issue is that the older slave
2338 will stop processing the Q_* blocks (and jumps to the db/query) as soon
2339 as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
2340 Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
2341 various ways. Documented that you should not mix alpha/beta versions if
2342 they are not exactly the same version, with example of 5.0.3->5.0.2 and
2343 5.0.4->5.0.3. If replication is from older to new, the new will
2344 recognize Q_CATALOG_CODE and have no problem.
2345 */
2346 }
2347 if (auto_increment_increment != 1 || auto_increment_offset != 1)
2348 {
2349 *start++= Q_AUTO_INCREMENT;
2350 int2store(start, auto_increment_increment);
2351 int2store(start+2, auto_increment_offset);
2352 start+= 4;
2353 }
2354 if (charset_inited)
2355 {
2356 *start++= Q_CHARSET_CODE;
2357 memcpy(start, charset, 6);
2358 start+= 6;
2359 }
2360 if (time_zone_len)
2361 {
2362 /* In the TZ sys table, column Name is of length 64 so this should be ok */
2363 DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
2364 write_str_with_code_and_len(&start,
2365 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
2366 }
2367 if (lc_time_names_number)
2368 {
2369 DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
2370 *start++= Q_LC_TIME_NAMES_CODE;
2371 int2store(start, lc_time_names_number);
2372 start+= 2;
2373 }
2374 if (charset_database_number)
2375 {
2376 DBUG_ASSERT(charset_database_number <= 0xFFFF);
2377 *start++= Q_CHARSET_DATABASE_CODE;
2378 int2store(start, charset_database_number);
2379 start+= 2;
2380 }
2381 if (table_map_for_update)
2382 {
2383 *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
2384 int8store(start, table_map_for_update);
2385 start+= 8;
2386 }
2387 if (master_data_written != 0)
2388 {
2389 /*
2390 Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
2391 has binlog_version<4 and the slave has binlog_version=4. See comment
2392 for master_data_written in log_event.h for details.
2393 */
2394 *start++= Q_MASTER_DATA_WRITTEN_CODE;
2395 int4store(start, master_data_written);
2396 start+= 4;
2397 }
2398
2399 if (thd && thd->need_binlog_invoker())
2400 {
2401 LEX_STRING user;
2402 LEX_STRING host;
2403 memset(&user, 0, sizeof(user));
2404 memset(&host, 0, sizeof(host));
2405
2406 if (thd->slave_thread && thd->has_invoker())
2407 {
2408 /* user will be null, if master is older than this patch */
2409 user= thd->get_invoker_user();
2410 host= thd->get_invoker_host();
2411 }
2412 else if (thd->security_ctx->priv_user)
2413 {
2414 Security_context *ctx= thd->security_ctx;
2415
2416 user.length= strlen(ctx->priv_user);
2417 user.str= ctx->priv_user;
2418 if (ctx->priv_host[0] != '\0')
2419 {
2420 host.str= ctx->priv_host;
2421 host.length= strlen(ctx->priv_host);
2422 }
2423 }
2424
2425 if (user.length > 0)
2426 {
2427 *start++= Q_INVOKER;
2428
2429 /*
2430 Store user length and user. The max length of use is 16, so 1 byte is
2431 enough to store the user's length.
2432 */
2433 *start++= (uchar)user.length;
2434 memcpy(start, user.str, user.length);
2435 start+= user.length;
2436
2437 /*
2438 Store host length and host. The max length of host is 60, so 1 byte is
2439 enough to store the host's length.
2440 */
2441 *start++= (uchar)host.length;
2442 memcpy(start, host.str, host.length);
2443 start+= host.length;
2444 }
2445 }
2446 /*
2447 NOTE: When adding new status vars, please don't forget to update
2448 the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
2449 code_name() in this file.
2450
2451 Here there could be code like
2452 if (command-line-option-which-says-"log_this_variable" && inited)
2453 {
2454 *start++= Q_THIS_VARIABLE_CODE;
2455 int4store(start, this_variable);
2456 start+= 4;
2457 }
2458 */
2459
2460 /* Store length of status variables */
2461 status_vars_len= (uint) (start-start_of_status);
2462 DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
2463 int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
2464
2465 /*
2466 Calculate length of whole event
2467 The "1" below is the \0 in the db's length
2468 */
2469 event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
2470
2471 return (write_header(file, event_length) ||
2472 my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
2473 write_post_header_for_derived(file) ||
2474 my_b_safe_write(file, (uchar*) start_of_status,
2475 (uint) (start-start_of_status)) ||
2476 my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
2477 my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
2478 }
2479
2480 /**
2481 The simplest constructor that could possibly work. This is used for
2482 creating static objects that have a special meaning and are invisible
2483 to the log.
2484 */
Query_log_event()2485 Query_log_event::Query_log_event()
2486 :Log_event(), data_buf(0)
2487 {
2488 memset(&user, 0, sizeof(user));
2489 memset(&host, 0, sizeof(host));
2490 }
2491
2492
2493 /*
2494 SYNOPSIS
2495 Query_log_event::Query_log_event()
2496 thd_arg - thread handle
2497 query_arg - array of char representing the query
2498 query_length - size of the `query_arg' array
2499 using_trans - there is a modified transactional table
2500 suppress_use - suppress the generation of 'USE' statements
2501 errcode - the error code of the query
2502
2503 DESCRIPTION
2504 Creates an event for binlogging
2505 The value for `errcode' should be supplied by caller.
2506 */
Query_log_event(THD * thd_arg,const char * query_arg,ulong query_length,bool using_trans,bool direct,bool suppress_use,int errcode)2507 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
2508 ulong query_length, bool using_trans,
2509 bool direct, bool suppress_use, int errcode)
2510
2511 :Log_event(thd_arg,
2512 (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
2513 0) |
2514 (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
2515 using_trans),
2516 data_buf(0), query(query_arg), catalog(thd_arg->catalog),
2517 db(thd_arg->db), q_len((uint32) query_length),
2518 thread_id(thd_arg->thread_id),
2519 /* save the original thread id; we already know the server id */
2520 slave_proxy_id(thd_arg->variables.pseudo_thread_id),
2521 flags2_inited(1), sql_mode_inited(1), charset_inited(1),
2522 sql_mode(thd_arg->variables.sql_mode),
2523 auto_increment_increment(thd_arg->variables.auto_increment_increment),
2524 auto_increment_offset(thd_arg->variables.auto_increment_offset),
2525 lc_time_names_number(thd_arg->variables.lc_time_names->number),
2526 charset_database_number(0),
2527 table_map_for_update((ulonglong)thd_arg->table_map_for_update),
2528 master_data_written(0)
2529 {
2530 time_t end_time;
2531
2532 memset(&user, 0, sizeof(user));
2533 memset(&host, 0, sizeof(host));
2534
2535 error_code= errcode;
2536
2537 time(&end_time);
2538 exec_time = (ulong) (end_time - thd_arg->start_time);
2539 /**
2540 @todo this means that if we have no catalog, then it is replicated
2541 as an existing catalog of length zero. is that safe? /sven
2542 */
2543 catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
2544 /* status_vars_len is set just before writing the event */
2545 db_len = (db) ? (uint32) strlen(db) : 0;
2546 if (thd_arg->variables.collation_database != thd_arg->db_charset)
2547 charset_database_number= thd_arg->variables.collation_database->number;
2548
2549 /*
2550 We only replicate over the bits of flags2 that we need: the rest
2551 are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
2552
2553 We also force AUTOCOMMIT=1. Rationale (cf. BUG#29288): After
2554 fixing BUG#26395, we always write BEGIN and COMMIT around all
2555 transactions (even single statements in autocommit mode). This is
2556 so that replication from non-transactional to transactional table
2557 and error recovery from XA to non-XA table should work as
2558 expected. The BEGIN/COMMIT are added in log.cc. However, there is
2559 one exception: MyISAM bypasses log.cc and writes directly to the
2560 binlog. So if autocommit is off, master has MyISAM, and slave has
2561 a transactional engine, then the slave will just see one long
2562 never-ending transaction. The only way to bypass explicit
2563 BEGIN/COMMIT in the binlog is by using a non-transactional table.
2564 So setting AUTOCOMMIT=1 will make this work as expected.
2565
2566 Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
2567 assume AUTOCOMMIT=1 on slave; the slave still reads the state of
2568 the autocommit flag as written by the master to the binlog. This
2569 behavior may change after WL#4162 has been implemented.
2570 */
2571 flags2= (uint32) (thd_arg->variables.option_bits &
2572 (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
2573 DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
2574 DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
2575 DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
2576 DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
2577 int2store(charset, thd_arg->variables.character_set_client->number);
2578 int2store(charset+2, thd_arg->variables.collation_connection->number);
2579 int2store(charset+4, thd_arg->variables.collation_server->number);
2580 if (thd_arg->time_zone_used)
2581 {
2582 /*
2583 Note that our event becomes dependent on the Time_zone object
2584 representing the time zone. Fortunately such objects are never deleted
2585 or changed during mysqld's lifetime.
2586 */
2587 time_zone_len= thd_arg->variables.time_zone->get_name()->length();
2588 time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
2589 }
2590 else
2591 time_zone_len= 0;
2592
2593 LEX *lex= thd->lex;
2594 /*
2595 Defines that the statement will be written directly to the binary log
2596 without being wrapped by a BEGIN...COMMIT. Otherwise, the statement
2597 will be written to either the trx-cache or stmt-cache.
2598
2599 Note that a cache will not be used if the parameter direct is TRUE.
2600 */
2601 bool use_cache= FALSE;
2602 /*
2603 TRUE defines that the trx-cache must be used and by consequence the
2604 use_cache is TRUE.
2605
2606 Note that a cache will not be used if the parameter direct is TRUE.
2607 */
2608 bool trx_cache= FALSE;
2609 cache_type= Log_event::EVENT_INVALID_CACHE;
2610
2611 switch (lex->sql_command)
2612 {
2613 case SQLCOM_DROP_TABLE:
2614 use_cache= (lex->drop_temporary && thd->in_multi_stmt_transaction_mode());
2615 break;
2616
2617 case SQLCOM_CREATE_TABLE:
2618 trx_cache= (lex->select_lex.item_list.elements &&
2619 thd->is_current_stmt_binlog_format_row());
2620 use_cache= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
2621 thd->in_multi_stmt_transaction_mode()) || trx_cache;
2622 break;
2623 case SQLCOM_SET_OPTION:
2624 use_cache= trx_cache= (lex->autocommit ? FALSE : TRUE);
2625 break;
2626 case SQLCOM_RELEASE_SAVEPOINT:
2627 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
2628 case SQLCOM_SAVEPOINT:
2629 use_cache= trx_cache= TRUE;
2630 break;
2631 default:
2632 use_cache= sqlcom_can_generate_row_events(thd);
2633 break;
2634 }
2635
2636 if (!use_cache || direct)
2637 {
2638 cache_type= Log_event::EVENT_NO_CACHE;
2639 }
2640 else if (using_trans || trx_cache ||
2641 stmt_has_updated_trans_table(thd->transaction.stmt.ha_list) ||
2642 thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
2643 thd->variables.binlog_direct_non_trans_update,
2644 trans_has_updated_trans_table(thd),
2645 thd->tx_isolation))
2646 cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
2647 else
2648 cache_type= Log_event::EVENT_STMT_CACHE;
2649 DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE);
2650 DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %lu",
2651 (ulong) flags2, sql_mode));
2652 }
2653 #endif /* MYSQL_CLIENT */
2654
2655
2656 /* 2 utility functions for the next method */
2657
2658 /**
2659 Read a string with length from memory.
2660
2661 This function reads the string-with-length stored at
2662 <code>src</code> and extract the length into <code>*len</code> and
2663 a pointer to the start of the string into <code>*dst</code>. The
2664 string can then be copied using <code>memcpy()</code> with the
2665 number of bytes given in <code>*len</code>.
2666
2667 @param src Pointer to variable holding a pointer to the memory to
2668 read the string from.
2669 @param dst Pointer to variable holding a pointer where the actual
2670 string starts. Starting from this position, the string
2671 can be copied using @c memcpy().
2672 @param len Pointer to variable where the length will be stored.
2673 @param end One-past-the-end of the memory where the string is
2674 stored.
2675
2676 @return Zero if the entire string can be copied successfully,
2677 @c UINT_MAX if the length could not be read from memory
2678 (that is, if <code>*src >= end</code>), otherwise the
2679 number of bytes that are missing to read the full
2680 string, which happends <code>*dst + *len >= end</code>.
2681 */
2682 static int
get_str_len_and_pointer(const Log_event::Byte ** src,const char ** dst,uint * len,const Log_event::Byte * end)2683 get_str_len_and_pointer(const Log_event::Byte **src,
2684 const char **dst,
2685 uint *len,
2686 const Log_event::Byte *end)
2687 {
2688 if (*src >= end)
2689 return -1; // Will be UINT_MAX in two-complement arithmetics
2690 uint length= **src;
2691 if (length > 0)
2692 {
2693 if (*src + length >= end)
2694 return *src + length - end + 1; // Number of bytes missing
2695 *dst= (char *)*src + 1; // Will be copied later
2696 }
2697 *len= length;
2698 *src+= length + 1;
2699 return 0;
2700 }
2701
copy_str_and_move(const char ** src,Log_event::Byte ** dst,uint len)2702 static void copy_str_and_move(const char **src,
2703 Log_event::Byte **dst,
2704 uint len)
2705 {
2706 memcpy(*dst, *src, len);
2707 *src= (const char *)*dst;
2708 (*dst)+= len;
2709 *(*dst)++= 0;
2710 }
2711
2712
2713 #ifndef DBUG_OFF
2714 static char const *
code_name(int code)2715 code_name(int code)
2716 {
2717 static char buf[255];
2718 switch (code) {
2719 case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
2720 case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
2721 case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
2722 case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
2723 case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
2724 case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
2725 case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
2726 case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
2727 case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
2728 case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
2729 case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
2730 }
2731 sprintf(buf, "CODE#%d", code);
2732 return buf;
2733 }
2734 #endif
2735
2736 /**
2737 Macro to check that there is enough space to read from memory.
2738
2739 @param PTR Pointer to memory
2740 @param END End of memory
2741 @param CNT Number of bytes that should be read.
2742 */
2743 #define CHECK_SPACE(PTR,END,CNT) \
2744 do { \
2745 DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
2746 DBUG_ASSERT((PTR) + (CNT) <= (END)); \
2747 if ((PTR) + (CNT) > (END)) { \
2748 DBUG_PRINT("info", ("query= 0")); \
2749 query= 0; \
2750 DBUG_VOID_RETURN; \
2751 } \
2752 } while (0)
2753
2754
2755 /**
2756 This is used by the SQL slave thread to prepare the event before execution.
2757 */
Query_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event,Log_event_type event_type)2758 Query_log_event::Query_log_event(const char* buf, uint event_len,
2759 const Format_description_log_event
2760 *description_event,
2761 Log_event_type event_type)
2762 :Log_event(buf, description_event), data_buf(0), query(NullS),
2763 db(NullS), catalog_len(0), status_vars_len(0),
2764 flags2_inited(0), sql_mode_inited(0), charset_inited(0),
2765 auto_increment_increment(1), auto_increment_offset(1),
2766 time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
2767 table_map_for_update(0), master_data_written(0)
2768 {
2769 ulong data_len;
2770 uint32 tmp;
2771 uint8 common_header_len, post_header_len;
2772 Log_event::Byte *start;
2773 const Log_event::Byte *end;
2774 bool catalog_nz= 1;
2775 DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
2776
2777 memset(&user, 0, sizeof(user));
2778 memset(&host, 0, sizeof(host));
2779 common_header_len= description_event->common_header_len;
2780 post_header_len= description_event->post_header_len[event_type-1];
2781 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
2782 event_len, common_header_len, post_header_len));
2783
2784 /*
2785 We test if the event's length is sensible, and if so we compute data_len.
2786 We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
2787 We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
2788 */
2789 if (event_len < (uint)(common_header_len + post_header_len))
2790 DBUG_VOID_RETURN;
2791 data_len = event_len - (common_header_len + post_header_len);
2792 buf+= common_header_len;
2793
2794 slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
2795 exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
2796 db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
2797 error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
2798
2799 /*
2800 5.0 format starts here.
2801 Depending on the format, we may or not have affected/warnings etc
2802 The remnent post-header to be parsed has length:
2803 */
2804 tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
2805 if (tmp)
2806 {
2807 status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
2808 /*
2809 Check if status variable length is corrupt and will lead to very
2810 wrong data. We could be even more strict and require data_len to
2811 be even bigger, but this will suffice to catch most corruption
2812 errors that can lead to a crash.
2813 */
2814 if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
2815 {
2816 DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
2817 status_vars_len, data_len));
2818 query= 0;
2819 DBUG_VOID_RETURN;
2820 }
2821 data_len-= status_vars_len;
2822 DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
2823 (uint) status_vars_len));
2824 tmp-= 2;
2825 }
2826 else
2827 {
2828 /*
2829 server version < 5.0 / binlog_version < 4 master's event is
2830 relay-logged with storing the original size of the event in
2831 Q_MASTER_DATA_WRITTEN_CODE status variable.
2832 The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
2833 event from the relay log.
2834 */
2835 DBUG_ASSERT(description_event->binlog_version < 4);
2836 master_data_written= data_written;
2837 }
2838 /*
2839 We have parsed everything we know in the post header for QUERY_EVENT,
2840 the rest of post header is either comes from older version MySQL or
2841 dedicated to derived events (e.g. Execute_load_query...)
2842 */
2843
2844 /* variable-part: the status vars; only in MySQL 5.0 */
2845
2846 start= (Log_event::Byte*) (buf+post_header_len);
2847 end= (const Log_event::Byte*) (start+status_vars_len);
2848 for (const Log_event::Byte* pos= start; pos < end;)
2849 {
2850 switch (*pos++) {
2851 case Q_FLAGS2_CODE:
2852 CHECK_SPACE(pos, end, 4);
2853 flags2_inited= 1;
2854 flags2= uint4korr(pos);
2855 DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
2856 pos+= 4;
2857 break;
2858 case Q_SQL_MODE_CODE:
2859 {
2860 #ifndef DBUG_OFF
2861 char buff[22];
2862 #endif
2863 CHECK_SPACE(pos, end, 8);
2864 sql_mode_inited= 1;
2865 sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong
2866 DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
2867 llstr(sql_mode, buff)));
2868 pos+= 8;
2869 break;
2870 }
2871 case Q_CATALOG_NZ_CODE:
2872 DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
2873 (ulong) pos, (ulong) end));
2874 if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
2875 {
2876 DBUG_PRINT("info", ("query= 0"));
2877 query= 0;
2878 DBUG_VOID_RETURN;
2879 }
2880 break;
2881 case Q_AUTO_INCREMENT:
2882 CHECK_SPACE(pos, end, 4);
2883 auto_increment_increment= uint2korr(pos);
2884 auto_increment_offset= uint2korr(pos+2);
2885 pos+= 4;
2886 break;
2887 case Q_CHARSET_CODE:
2888 {
2889 CHECK_SPACE(pos, end, 6);
2890 charset_inited= 1;
2891 memcpy(charset, pos, 6);
2892 pos+= 6;
2893 break;
2894 }
2895 case Q_TIME_ZONE_CODE:
2896 {
2897 if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
2898 {
2899 DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
2900 query= 0;
2901 DBUG_VOID_RETURN;
2902 }
2903 break;
2904 }
2905 case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
2906 CHECK_SPACE(pos, end, 1);
2907 if ((catalog_len= *pos))
2908 catalog= (char*) pos+1; // Will be copied later
2909 CHECK_SPACE(pos, end, catalog_len + 2);
2910 pos+= catalog_len+2; // leap over end 0
2911 catalog_nz= 0; // catalog has end 0 in event
2912 break;
2913 case Q_LC_TIME_NAMES_CODE:
2914 CHECK_SPACE(pos, end, 2);
2915 lc_time_names_number= uint2korr(pos);
2916 pos+= 2;
2917 break;
2918 case Q_CHARSET_DATABASE_CODE:
2919 CHECK_SPACE(pos, end, 2);
2920 charset_database_number= uint2korr(pos);
2921 pos+= 2;
2922 break;
2923 case Q_TABLE_MAP_FOR_UPDATE_CODE:
2924 CHECK_SPACE(pos, end, 8);
2925 table_map_for_update= uint8korr(pos);
2926 pos+= 8;
2927 break;
2928 case Q_MASTER_DATA_WRITTEN_CODE:
2929 CHECK_SPACE(pos, end, 4);
2930 data_written= master_data_written= uint4korr(pos);
2931 pos+= 4;
2932 break;
2933 case Q_INVOKER:
2934 {
2935 CHECK_SPACE(pos, end, 1);
2936 user.length= *pos++;
2937 CHECK_SPACE(pos, end, user.length);
2938 user.str= (char *)pos;
2939 pos+= user.length;
2940
2941 CHECK_SPACE(pos, end, 1);
2942 host.length= *pos++;
2943 CHECK_SPACE(pos, end, host.length);
2944 host.str= (char *)pos;
2945 pos+= host.length;
2946 }
2947 default:
2948 /* That's why you must write status vars in growing order of code */
2949 DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
2950 code: %u), skipping the rest of them", (uint) *(pos-1)));
2951 pos= (const uchar*) end; // Break loop
2952 }
2953 }
2954
2955 /**
2956 Layout for the data buffer is as follows
2957 +--------+-----------+------+------+---------+----+-------+
2958 | catlog | time_zone | user | host | db name | \0 | Query |
2959 +--------+-----------+------+------+---------+----+-------+
2960
2961 To support the query cache we append the following buffer to the above
2962 +-------+----------------------------------------+-------+
2963 |db len | uninitiatlized space of size of db len | FLAGS |
2964 +-------+----------------------------------------+-------+
2965
2966 The area of buffer starting from Query field all the way to the end belongs
2967 to the Query buffer and its structure is described in alloc_query() in
2968 sql_parse.cc
2969 */
2970
2971 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
2972 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
2973 + time_zone_len + 1
2974 + user.length + 1
2975 + host.length + 1
2976 + data_len + 1
2977 + sizeof(size_t)//for db_len
2978 + db_len + 1
2979 + QUERY_CACHE_FLAGS_SIZE,
2980 MYF(MY_WME))))
2981 #else
2982 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
2983 + time_zone_len + 1
2984 + user.length + 1
2985 + host.length + 1
2986 + data_len + 1,
2987 MYF(MY_WME))))
2988 #endif
2989 DBUG_VOID_RETURN;
2990 if (catalog_len) // If catalog is given
2991 {
2992 /**
2993 @todo we should clean up and do only copy_str_and_move; it
2994 works for both cases. Then we can remove the catalog_nz
2995 flag. /sven
2996 */
2997 if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
2998 copy_str_and_move(&catalog, &start, catalog_len);
2999 else
3000 {
3001 memcpy(start, catalog, catalog_len+1); // copy end 0
3002 catalog= (const char *)start;
3003 start+= catalog_len+1;
3004 }
3005 }
3006 if (time_zone_len)
3007 copy_str_and_move(&time_zone_str, &start, time_zone_len);
3008
3009 if (user.length > 0)
3010 copy_str_and_move((const char **)&(user.str), &start, user.length);
3011 if (host.length > 0)
3012 copy_str_and_move((const char **)&(host.str), &start, host.length);
3013
3014 /**
3015 if time_zone_len or catalog_len are 0, then time_zone and catalog
3016 are uninitialized at this point. shouldn't they point to the
3017 zero-length null-terminated strings we allocated space for in the
3018 my_alloc call above? /sven
3019 */
3020
3021 /* A 2nd variable part; this is common to all versions */
3022 memcpy((char*) start, end, data_len); // Copy db and query
3023 start[data_len]= '\0'; // End query with \0 (For safetly)
3024 db= (char *)start;
3025 query= (char *)(start + db_len + 1);
3026 q_len= data_len - db_len -1;
3027
3028 if (data_len && (data_len < db_len ||
3029 data_len < q_len ||
3030 data_len != (db_len + q_len + 1)))
3031 {
3032 q_len= 0;
3033 query= NULL;
3034 DBUG_VOID_RETURN;
3035 }
3036
3037 unsigned int max_length;
3038 max_length= (event_len - ((const char*)(end + db_len + 1) -
3039 (buf - common_header_len)));
3040 if (q_len != max_length)
3041 {
3042 q_len= 0;
3043 query= NULL;
3044 DBUG_VOID_RETURN;
3045 }
3046 /**
3047 Append the db length at the end of the buffer. This will be used by
3048 Query_cache::send_result_to_client() in case the query cache is On.
3049 */
3050 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
3051 size_t db_length= (size_t)db_len;
3052 memcpy(start + data_len + 1, &db_length, sizeof(size_t));
3053 #endif
3054 DBUG_VOID_RETURN;
3055 }
3056
3057
3058 #ifdef MYSQL_CLIENT
3059 /**
3060 Query_log_event::print().
3061
3062 @todo
3063 print the catalog ??
3064 */
print_query_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)3065 void Query_log_event::print_query_header(IO_CACHE* file,
3066 PRINT_EVENT_INFO* print_event_info)
3067 {
3068 // TODO: print the catalog ??
3069 char buff[40],*end; // Enough for SET TIMESTAMP
3070 char quoted_id[1+ 2*FN_REFLEN+ 2];
3071 int quoted_len= 0;
3072 bool different_db= 1;
3073 uint32 tmp;
3074
3075 if (!print_event_info->short_form)
3076 {
3077 print_header(file, print_event_info, FALSE);
3078 my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
3079 get_type_str(), (ulong) thread_id, (ulong) exec_time,
3080 error_code);
3081 }
3082
3083 if ((flags & LOG_EVENT_SUPPRESS_USE_F))
3084 {
3085 if (!is_trans_keyword())
3086 print_event_info->db[0]= '\0';
3087 }
3088 else if (db)
3089 {
3090 #ifdef MYSQL_SERVER
3091 quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
3092 #else
3093 quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
3094 #endif
3095 quoted_id[quoted_len]= '\0';
3096 different_db= memcmp(print_event_info->db, db, db_len + 1);
3097 if (different_db)
3098 memcpy(print_event_info->db, db, db_len + 1);
3099 if (db[0] && different_db)
3100 my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
3101 }
3102
3103 end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
3104 end= strmov(end, print_event_info->delimiter);
3105 *end++='\n';
3106 my_b_write(file, (uchar*) buff, (uint) (end-buff));
3107 if ((!print_event_info->thread_id_printed ||
3108 ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
3109 thread_id != print_event_info->thread_id)))
3110 {
3111 // If --short-form, print deterministic value instead of pseudo_thread_id.
3112 my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
3113 short_form ? 999999999 : (ulong)thread_id,
3114 print_event_info->delimiter);
3115 print_event_info->thread_id= thread_id;
3116 print_event_info->thread_id_printed= 1;
3117 }
3118
3119 /*
3120 If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
3121 print (remember we don't produce mixed relay logs so there cannot be
3122 5.0 events before that one so there is nothing to reset).
3123 */
3124 if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
3125 {
3126 /* tmp is a bitmask of bits which have changed. */
3127 if (likely(print_event_info->flags2_inited))
3128 /* All bits which have changed */
3129 tmp= (print_event_info->flags2) ^ flags2;
3130 else /* that's the first Query event we read */
3131 {
3132 print_event_info->flags2_inited= 1;
3133 tmp= ~((uint32)0); /* all bits have changed */
3134 }
3135
3136 if (unlikely(tmp)) /* some bits have changed */
3137 {
3138 bool need_comma= 0;
3139 my_b_printf(file, "SET ");
3140 print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
3141 "@@session.foreign_key_checks", &need_comma);
3142 print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
3143 "@@session.sql_auto_is_null", &need_comma);
3144 print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
3145 "@@session.unique_checks", &need_comma);
3146 print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
3147 "@@session.autocommit", &need_comma);
3148 my_b_printf(file,"%s\n", print_event_info->delimiter);
3149 print_event_info->flags2= flags2;
3150 }
3151 }
3152
3153 /*
3154 Now the session variables;
3155 it's more efficient to pass SQL_MODE as a number instead of a
3156 comma-separated list.
3157 FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
3158 variables (they have no global version; they're not listed in
3159 sql_class.h), The tests below work for pure binlogs or pure relay
3160 logs. Won't work for mixed relay logs but we don't create mixed
3161 relay logs (that is, there is no relay log with a format change
3162 except within the 3 first events, which mysqlbinlog handles
3163 gracefully). So this code should always be good.
3164 */
3165
3166 if (likely(sql_mode_inited) &&
3167 (unlikely(print_event_info->sql_mode != sql_mode ||
3168 !print_event_info->sql_mode_inited)))
3169 {
3170 my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
3171 (ulong)sql_mode, print_event_info->delimiter);
3172 print_event_info->sql_mode= sql_mode;
3173 print_event_info->sql_mode_inited= 1;
3174 }
3175 if (print_event_info->auto_increment_increment != auto_increment_increment ||
3176 print_event_info->auto_increment_offset != auto_increment_offset)
3177 {
3178 my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
3179 auto_increment_increment,auto_increment_offset,
3180 print_event_info->delimiter);
3181 print_event_info->auto_increment_increment= auto_increment_increment;
3182 print_event_info->auto_increment_offset= auto_increment_offset;
3183 }
3184
3185 /* TODO: print the catalog when we feature SET CATALOG */
3186
3187 if (likely(charset_inited) &&
3188 (unlikely(!print_event_info->charset_inited ||
3189 memcmp(print_event_info->charset, charset, 6))))
3190 {
3191 CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
3192 if (cs_info)
3193 {
3194 /* for mysql client */
3195 my_b_printf(file, "/*!\\C %s */%s\n",
3196 cs_info->csname, print_event_info->delimiter);
3197 }
3198 my_b_printf(file,"SET "
3199 "@@session.character_set_client=%d,"
3200 "@@session.collation_connection=%d,"
3201 "@@session.collation_server=%d"
3202 "%s\n",
3203 uint2korr(charset),
3204 uint2korr(charset+2),
3205 uint2korr(charset+4),
3206 print_event_info->delimiter);
3207 memcpy(print_event_info->charset, charset, 6);
3208 print_event_info->charset_inited= 1;
3209 }
3210 if (time_zone_len)
3211 {
3212 if (memcmp(print_event_info->time_zone_str,
3213 time_zone_str, time_zone_len+1))
3214 {
3215 my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
3216 time_zone_str, print_event_info->delimiter);
3217 memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
3218 }
3219 }
3220 if (lc_time_names_number != print_event_info->lc_time_names_number)
3221 {
3222 my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
3223 lc_time_names_number, print_event_info->delimiter);
3224 print_event_info->lc_time_names_number= lc_time_names_number;
3225 }
3226 if (charset_database_number != print_event_info->charset_database_number)
3227 {
3228 if (charset_database_number)
3229 my_b_printf(file, "SET @@session.collation_database=%d%s\n",
3230 charset_database_number, print_event_info->delimiter);
3231 else
3232 my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
3233 print_event_info->delimiter);
3234 print_event_info->charset_database_number= charset_database_number;
3235 }
3236 }
3237
3238
print(FILE * file,PRINT_EVENT_INFO * print_event_info)3239 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3240 {
3241 Write_on_release_cache cache(&print_event_info->head_cache, file);
3242
3243 /**
3244 reduce the size of io cache so that the write function is called
3245 for every call to my_b_write().
3246 */
3247 DBUG_EXECUTE_IF ("simulate_file_write_error",
3248 {(&cache)->write_pos= (&cache)->write_end- 500;});
3249 print_query_header(&cache, print_event_info);
3250 my_b_write(&cache, (uchar*) query, q_len);
3251 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
3252 }
3253 #endif /* MYSQL_CLIENT */
3254
3255
3256 /*
3257 Query_log_event::do_apply_event()
3258 */
3259
3260 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3261
do_apply_event(Relay_log_info const * rli)3262 int Query_log_event::do_apply_event(Relay_log_info const *rli)
3263 {
3264 return do_apply_event(rli, query, q_len);
3265 }
3266
3267
3268 /**
3269 @todo
3270 Compare the values of "affected rows" around here. Something
3271 like:
3272 @code
3273 if ((uint32) affected_in_event != (uint32) affected_on_slave)
3274 {
3275 sql_print_error("Slave: did not get the expected number of affected \
3276 rows running query from master - expected %d, got %d (this numbers \
3277 should have matched modulo 4294967296).", 0, ...);
3278 thd->query_error = 1;
3279 }
3280 @endcode
3281 We may also want an option to tell the slave to ignore "affected"
3282 mismatch. This mismatch could be implemented with a new ER_ code, and
3283 to ignore it you would use --slave-skip-errors...
3284 */
do_apply_event(Relay_log_info const * rli,const char * query_arg,uint32 q_len_arg)3285 int Query_log_event::do_apply_event(Relay_log_info const *rli,
3286 const char *query_arg, uint32 q_len_arg)
3287 {
3288 LEX_STRING new_db;
3289 int expected_error,actual_error= 0;
3290 HA_CREATE_INFO db_options;
3291
3292 /*
3293 Colleagues: please never free(thd->catalog) in MySQL. This would
3294 lead to bugs as here thd->catalog is a part of an alloced block,
3295 not an entire alloced block (see
3296 Query_log_event::do_apply_event()). Same for thd->db. Thank
3297 you.
3298 */
3299 thd->catalog= catalog_len ? (char *) catalog : (char *)"";
3300
3301 size_t valid_len;
3302 bool len_error;
3303 bool is_invalid_db_name= validate_string(system_charset_info, db, db_len,
3304 &valid_len, &len_error);
3305
3306 DBUG_PRINT("debug",("is_invalid_db_name= %s, valid_len=%zu, len_error=%s",
3307 is_invalid_db_name ? "true" : "false",
3308 valid_len,
3309 len_error ? "true" : "false"));
3310
3311 if (is_invalid_db_name || len_error)
3312 {
3313 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3314 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
3315 "Invalid database name in Query event.");
3316 thd->is_slave_error= true;
3317 goto end;
3318 }
3319
3320 new_db.length= db_len;
3321 new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
3322 thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */
3323
3324 /*
3325 Setting the character set and collation of the current database thd->db.
3326 */
3327 load_db_opt_by_name(thd, thd->db, &db_options);
3328 if (db_options.default_table_charset)
3329 thd->db_charset= db_options.default_table_charset;
3330 thd->variables.auto_increment_increment= auto_increment_increment;
3331 thd->variables.auto_increment_offset= auto_increment_offset;
3332
3333 /*
3334 InnoDB internally stores the master log position it has executed so far,
3335 i.e. the position just after the COMMIT event.
3336 When InnoDB will want to store, the positions in rli won't have
3337 been updated yet, so group_master_log_* will point to old BEGIN
3338 and event_master_log* will point to the beginning of current COMMIT.
3339 But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
3340 END of the current log event (COMMIT). We save it in rli so that InnoDB can
3341 access it.
3342 */
3343 const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
3344 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
3345
3346 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
3347 if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock)
3348 {
3349 /*
3350 Cleaning-up the last statement context:
3351 the terminal event of the current statement flagged with
3352 STMT_END_F got filtered out in ndb circular replication.
3353 */
3354 int error;
3355 char llbuff[22];
3356 if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
3357 {
3358 const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
3359 "Error in cleaning up after an event preceeding the commit; "
3360 "the group log file/position: %s %s",
3361 const_cast<Relay_log_info*>(rli)->group_master_log_name,
3362 llstr(const_cast<Relay_log_info*>(rli)->group_master_log_pos,
3363 llbuff));
3364 }
3365 /*
3366 Executing a part of rli->stmt_done() logics that does not deal
3367 with group position change. The part is redundant now but is
3368 future-change-proof addon, e.g if COMMIT handling will start checking
3369 invariants like IN_STMT flag must be off at committing the transaction.
3370 */
3371 const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
3372 const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
3373 }
3374 else
3375 {
3376 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
3377 }
3378
3379 /*
3380 Note: We do not need to execute reset_one_shot_variables() if this
3381 db_ok() test fails.
3382 Reason: The db stored in binlog events is the same for SET and for
3383 its companion query. If the SET is ignored because of
3384 db_ok(), the companion query will also be ignored, and if
3385 the companion query is ignored in the db_ok() test of
3386 ::do_apply_event(), then the companion SET also have so
3387 we don't need to reset_one_shot_variables().
3388 */
3389 if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
3390 {
3391 thd->set_time((time_t)when);
3392 thd->set_query_and_id((char*)query_arg, q_len_arg,
3393 thd->charset(), next_query_id());
3394 thd->variables.pseudo_thread_id= thread_id; // for temp tables
3395 DBUG_PRINT("query",("%s", thd->query()));
3396
3397 if (ignored_error_code((expected_error= error_code)) ||
3398 !unexpected_error_code(expected_error))
3399 {
3400 if (flags2_inited)
3401 /*
3402 all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
3403 must take their value from flags2.
3404 */
3405 thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
3406 /*
3407 else, we are in a 3.23/4.0 binlog; we previously received a
3408 Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
3409 nothing to do.
3410 */
3411 /*
3412 We do not replicate IGNORE_DIR_IN_CREATE. That is, if the master is a
3413 slave which runs with SQL_MODE=IGNORE_DIR_IN_CREATE, this should not
3414 force us to ignore the dir too. Imagine you are a ring of machines, and
3415 one has a disk problem so that you temporarily need
3416 IGNORE_DIR_IN_CREATE on this machine; you don't want it to propagate
3417 elsewhere (you don't want all slaves to start ignoring the dirs).
3418 */
3419 if (sql_mode_inited)
3420 thd->variables.sql_mode=
3421 (ulong) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
3422 (sql_mode & ~(ulong) MODE_NO_DIR_IN_CREATE));
3423 if (charset_inited)
3424 {
3425 if (rli->cached_charset_compare(charset))
3426 {
3427 /* Verify that we support the charsets found in the event. */
3428 if (!(thd->variables.character_set_client=
3429 get_charset(uint2korr(charset), MYF(MY_WME))) ||
3430 !(thd->variables.collation_connection=
3431 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
3432 !(thd->variables.collation_server=
3433 get_charset(uint2korr(charset+4), MYF(MY_WME))))
3434 {
3435 /*
3436 We updated the thd->variables with nonsensical values (0). Let's
3437 set them to something safe (i.e. which avoids crash), and we'll
3438 stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
3439 ignore this error).
3440 */
3441 set_slave_thread_default_charset(thd, rli);
3442 goto compare_errors;
3443 }
3444 thd->update_charset(); // for the charset change to take effect
3445 /*
3446 Reset thd->query_string.cs to the newly set value.
3447 Note, there is a small flaw here. For a very short time frame
3448 if the new charset is different from the old charset and
3449 if another thread executes "SHOW PROCESSLIST" after
3450 the above thd->set_query_and_id() and before this thd->set_query(),
3451 and if the current query has some non-ASCII characters,
3452 the another thread may see some '?' marks in the PROCESSLIST
3453 result. This should be acceptable now. This is a reminder
3454 to fix this if any refactoring happens here sometime.
3455 */
3456 thd->set_query((char*) query_arg, q_len_arg, thd->charset());
3457 }
3458 }
3459 if (time_zone_len)
3460 {
3461 String tmp(time_zone_str, time_zone_len, &my_charset_bin);
3462 if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
3463 {
3464 my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
3465 thd->variables.time_zone= global_system_variables.time_zone;
3466 goto compare_errors;
3467 }
3468 }
3469 if (lc_time_names_number)
3470 {
3471 if (!(thd->variables.lc_time_names=
3472 my_locale_by_number(lc_time_names_number)))
3473 {
3474 my_printf_error(ER_UNKNOWN_ERROR,
3475 "Unknown locale: '%d'", MYF(0), lc_time_names_number);
3476 thd->variables.lc_time_names= &my_locale_en_US;
3477 goto compare_errors;
3478 }
3479 }
3480 else
3481 thd->variables.lc_time_names= &my_locale_en_US;
3482 if (charset_database_number)
3483 {
3484 CHARSET_INFO *cs;
3485 if (!(cs= get_charset(charset_database_number, MYF(0))))
3486 {
3487 char buf[20];
3488 int10_to_str((int) charset_database_number, buf, -10);
3489 my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
3490 goto compare_errors;
3491 }
3492 thd->variables.collation_database= cs;
3493 }
3494 else
3495 thd->variables.collation_database= thd->db_charset;
3496
3497 {
3498 const CHARSET_INFO *cs= thd->charset();
3499 /*
3500 We cannot ask for parsing a statement using a character set
3501 without state_maps (parser internal data).
3502 */
3503 if (!cs->state_map)
3504 {
3505 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3506 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
3507 "character_set cannot be parsed");
3508 thd->is_slave_error= true;
3509 goto end;
3510 }
3511 }
3512
3513 thd->table_map_for_update= (table_map)table_map_for_update;
3514 thd->set_invoker(&user, &host);
3515 /*
3516 Flag if we need to rollback the statement transaction on
3517 slave if it by chance succeeds.
3518 If we expected a non-zero error code and get nothing and,
3519 it is a concurrency issue or ignorable issue, effects
3520 of the statement should be rolled back.
3521 */
3522 if (expected_error &&
3523 (ignored_error_code(expected_error) ||
3524 concurrency_error_code(expected_error)))
3525 {
3526 thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
3527 }
3528 /* Execute the query (note that we bypass dispatch_command()) */
3529 Parser_state parser_state;
3530 if (!parser_state.init(thd, thd->query(), thd->query_length()))
3531 {
3532 mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
3533 /* Finalize server status flags after executing a statement. */
3534 thd->update_server_status();
3535 log_slow_statement(thd);
3536 }
3537
3538 thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
3539
3540 /*
3541 Resetting the enable_slow_log thd variable.
3542
3543 We need to reset it back to the opt_log_slow_slave_statements
3544 value after the statement execution (and slow logging
3545 is done). It might have changed if the statement was an
3546 admin statement (in which case, down in mysql_parse execution
3547 thd->enable_slow_log is set to the value of
3548 opt_log_slow_admin_statements).
3549 */
3550 thd->enable_slow_log= opt_log_slow_slave_statements;
3551 }
3552 else
3553 {
3554 /*
3555 The query got a really bad error on the master (thread killed etc),
3556 which could be inconsistent. Parse it to test the table names: if the
3557 replicate-*-do|ignore-table rules say "this query must be ignored" then
3558 we exit gracefully; otherwise we warn about the bad error and tell DBA
3559 to check/fix it.
3560 */
3561 if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
3562 clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
3563 else
3564 {
3565 rli->report(ERROR_LEVEL, expected_error,
3566 "\
3567 Query partially completed on the master (error on master: %d) \
3568 and was aborted. There is a chance that your master is inconsistent at this \
3569 point. If you are sure that your master is ok, run this query manually on the \
3570 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
3571 START SLAVE; . Query: '%s'", expected_error, thd->query());
3572 thd->is_slave_error= 1;
3573 }
3574 goto end;
3575 }
3576
3577 /* If the query was not ignored, it is printed to the general log */
3578 if (!thd->is_error() || thd->stmt_da->sql_errno() != ER_SLAVE_IGNORED_TABLE)
3579 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
3580
3581 compare_errors:
3582 /*
3583 In the slave thread, we may sometimes execute some DROP / * 40005
3584 TEMPORARY * / TABLE that come from parts of binlogs (likely if we
3585 use RESET SLAVE or CHANGE MASTER TO), while the temporary table
3586 has already been dropped. To ignore such irrelevant "table does
3587 not exist errors", we silently clear the error if TEMPORARY was used.
3588 */
3589 if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
3590 thd->is_error() && thd->stmt_da->sql_errno() == ER_BAD_TABLE_ERROR &&
3591 !expected_error)
3592 thd->stmt_da->reset_diagnostics_area();
3593 /*
3594 If we expected a non-zero error code, and we don't get the same error
3595 code, and it should be ignored or is related to a concurrency issue.
3596 */
3597 actual_error= thd->is_error() ? thd->stmt_da->sql_errno() : 0;
3598 DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
3599 expected_error, actual_error));
3600
3601 if ((expected_error && expected_error != actual_error &&
3602 !concurrency_error_code(expected_error)) &&
3603 !ignored_error_code(actual_error) &&
3604 !ignored_error_code(expected_error))
3605 {
3606 rli->report(ERROR_LEVEL, 0,
3607 "\
3608 Query caused different errors on master and slave. \
3609 Error on master: message (format)='%s' error code=%d ; \
3610 Error on slave: actual message='%s', error code=%d. \
3611 Default database: '%s'. Query: '%s'",
3612 ER_SAFE(expected_error),
3613 expected_error,
3614 actual_error ? thd->stmt_da->message() : "no error",
3615 actual_error,
3616 print_slave_db_safe(db), query_arg);
3617 thd->is_slave_error= 1;
3618 }
3619 /*
3620 If we get the same error code as expected and it is not a concurrency
3621 issue, or should be ignored.
3622 */
3623 else if ((expected_error == actual_error &&
3624 !concurrency_error_code(expected_error)) ||
3625 ignored_error_code(actual_error))
3626 {
3627 DBUG_PRINT("info",("error ignored"));
3628 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
3629 thd->killed= THD::NOT_KILLED;
3630 }
3631 /*
3632 Other cases: mostly we expected no error and get one.
3633 */
3634 else if (thd->is_slave_error || thd->is_fatal_error)
3635 {
3636 rli->report(ERROR_LEVEL, actual_error,
3637 "Error '%s' on query. Default database: '%s'. Query: '%s'",
3638 (actual_error ? thd->stmt_da->message() :
3639 "unexpected success or fatal error"),
3640 print_slave_db_safe(thd->db), query_arg);
3641 thd->is_slave_error= 1;
3642 }
3643
3644 /*
3645 TODO: compare the values of "affected rows" around here. Something
3646 like:
3647 if ((uint32) affected_in_event != (uint32) affected_on_slave)
3648 {
3649 sql_print_error("Slave: did not get the expected number of affected \
3650 rows running query from master - expected %d, got %d (this numbers \
3651 should have matched modulo 4294967296).", 0, ...);
3652 thd->is_slave_error = 1;
3653 }
3654 We may also want an option to tell the slave to ignore "affected"
3655 mismatch. This mismatch could be implemented with a new ER_ code, and
3656 to ignore it you would use --slave-skip-errors...
3657
3658 To do the comparison we need to know the value of "affected" which the
3659 above mysql_parse() computed. And we need to know the value of
3660 "affected" in the master's binlog. Both will be implemented later. The
3661 important thing is that we now have the format ready to log the values
3662 of "affected" in the binlog. So we can release 5.0.0 before effectively
3663 logging "affected" and effectively comparing it.
3664 */
3665 } /* End of if (db_ok(... */
3666
3667 {
3668 /**
3669 The following failure injecion works in cooperation with tests
3670 setting @@global.debug= 'd,stop_slave_middle_group'.
3671 The sql thread receives the killed status and will proceed
3672 to shutdown trying to finish incomplete events group.
3673 */
3674 DBUG_EXECUTE_IF("stop_slave_middle_group",
3675 if (strcmp("COMMIT", query) != 0 &&
3676 strcmp("BEGIN", query) != 0)
3677 {
3678 if (thd->transaction.all.modified_non_trans_table)
3679 const_cast<Relay_log_info*>(rli)->abort_slave= 1;
3680 };);
3681 }
3682
3683 end:
3684 /*
3685 Probably we have set thd->query, thd->db, thd->catalog to point to places
3686 in the data_buf of this event. Now the event is going to be deleted
3687 probably, so data_buf will be freed, so the thd->... listed above will be
3688 pointers to freed memory.
3689 So we must set them to 0, so that those bad pointers values are not later
3690 used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
3691 don't suffer from these assignments to 0 as DROP TEMPORARY
3692 TABLE uses the db.table syntax.
3693 */
3694 thd->catalog= 0;
3695 thd->set_db(NULL, 0); /* will free the current database */
3696 thd->reset_query();
3697 DBUG_PRINT("info", ("end: query= 0"));
3698 /*
3699 As a disk space optimization, future masters will not log an event for
3700 LAST_INSERT_ID() if that function returned 0 (and thus they will be able
3701 to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
3702 variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
3703 resetting below we are ready to support that.
3704 */
3705 thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
3706 thd->first_successful_insert_id_in_prev_stmt= 0;
3707 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
3708 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3709 return thd->is_slave_error;
3710 }
3711
do_update_pos(Relay_log_info * rli)3712 int Query_log_event::do_update_pos(Relay_log_info *rli)
3713 {
3714 /*
3715 Note that we will not increment group* positions if we are just
3716 after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
3717 from its following updating query.
3718 */
3719 if (thd->one_shot_set)
3720 {
3721 rli->inc_event_relay_log_pos();
3722 return 0;
3723 }
3724 else
3725 return Log_event::do_update_pos(rli);
3726 }
3727
3728
3729 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)3730 Query_log_event::do_shall_skip(Relay_log_info *rli)
3731 {
3732 DBUG_ENTER("Query_log_event::do_shall_skip");
3733 DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
3734 DBUG_ASSERT(query && q_len > 0);
3735
3736 if (rli->slave_skip_counter > 0)
3737 {
3738 if (strcmp("BEGIN", query) == 0)
3739 {
3740 thd->variables.option_bits|= OPTION_BEGIN;
3741 DBUG_RETURN(Log_event::continue_group(rli));
3742 }
3743
3744 if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
3745 {
3746 thd->variables.option_bits&= ~OPTION_BEGIN;
3747 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
3748 }
3749 }
3750 DBUG_RETURN(Log_event::do_shall_skip(rli));
3751 }
3752
3753 #endif
3754
3755
3756 /**************************************************************************
3757 Start_log_event_v3 methods
3758 **************************************************************************/
3759
3760 #ifndef MYSQL_CLIENT
Start_log_event_v3()3761 Start_log_event_v3::Start_log_event_v3()
3762 :Log_event(), created(0), binlog_version(BINLOG_VERSION),
3763 dont_set_created(0)
3764 {
3765 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
3766 }
3767 #endif
3768
3769 /*
3770 Start_log_event_v3::pack_info()
3771 */
3772
3773 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)3774 void Start_log_event_v3::pack_info(Protocol *protocol)
3775 {
3776 char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
3777 pos= strmov(buf, "Server ver: ");
3778 pos= strmov(pos, server_version);
3779 pos= strmov(pos, ", Binlog ver: ");
3780 pos= int10_to_str(binlog_version, pos, 10);
3781 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3782 }
3783 #endif
3784
3785
3786 /*
3787 Start_log_event_v3::print()
3788 */
3789
3790 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)3791 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3792 {
3793 DBUG_ENTER("Start_log_event_v3::print");
3794
3795 Write_on_release_cache cache(&print_event_info->head_cache, file,
3796 Write_on_release_cache::FLUSH_F);
3797
3798 if (!print_event_info->short_form)
3799 {
3800 print_header(&cache, print_event_info, FALSE);
3801 my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
3802 binlog_version, server_version);
3803 print_timestamp(&cache);
3804 if (created)
3805 my_b_printf(&cache," at startup");
3806 my_b_printf(&cache, "\n");
3807 if (flags & LOG_EVENT_BINLOG_IN_USE_F)
3808 my_b_printf(&cache, "# Warning: this binlog is either in use or was not "
3809 "closed properly.\n");
3810 }
3811 if (!is_artificial_event() && created)
3812 {
3813 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
3814 /*
3815 This is for mysqlbinlog: like in replication, we want to delete the stale
3816 tmp files left by an unclean shutdown of mysqld (temporary tables)
3817 and rollback unfinished transaction.
3818 Probably this can be done with RESET CONNECTION (syntax to be defined).
3819 */
3820 my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
3821 #else
3822 my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
3823 #endif
3824 }
3825 if (temp_buf &&
3826 print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
3827 !print_event_info->short_form)
3828 {
3829 if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
3830 my_b_printf(&cache, "BINLOG '\n");
3831 print_base64(&cache, print_event_info, FALSE);
3832 print_event_info->printed_fd_event= TRUE;
3833 }
3834 DBUG_VOID_RETURN;
3835 }
3836 #endif /* MYSQL_CLIENT */
3837
3838 /*
3839 Start_log_event_v3::Start_log_event_v3()
3840 */
3841
Start_log_event_v3(const char * buf,uint event_len,const Format_description_log_event * description_event)3842 Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
3843 const Format_description_log_event
3844 *description_event)
3845 :Log_event(buf, description_event), binlog_version(BINLOG_VERSION)
3846 {
3847 if (event_len < (uint)description_event->common_header_len +
3848 ST_COMMON_HEADER_LEN_OFFSET)
3849 {
3850 server_version[0]= 0;
3851 return;
3852 }
3853 buf+= description_event->common_header_len;
3854 binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
3855 memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
3856 ST_SERVER_VER_LEN);
3857 // prevent overrun if log is corrupted on disk
3858 server_version[ST_SERVER_VER_LEN-1]= 0;
3859 created= uint4korr(buf+ST_CREATED_OFFSET);
3860 dont_set_created= 1;
3861 }
3862
3863
3864 /*
3865 Start_log_event_v3::write()
3866 */
3867
3868 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)3869 bool Start_log_event_v3::write(IO_CACHE* file)
3870 {
3871 char buff[START_V3_HEADER_LEN];
3872 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
3873 memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
3874 if (!dont_set_created)
3875 created= when= get_time();
3876 int4store(buff + ST_CREATED_OFFSET,created);
3877 return (write_header(file, sizeof(buff)) ||
3878 my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
3879 }
3880 #endif
3881
3882
3883 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3884
3885 /**
3886 Start_log_event_v3::do_apply_event() .
3887 The master started
3888
3889 IMPLEMENTATION
3890 - To handle the case where the master died without having time to write
3891 DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
3892 TODO), we clean up all temporary tables that we got, if we are sure we
3893 can (see below).
3894
3895 @todo
3896 - Remove all active user locks.
3897 Guilhem 2003-06: this is true but not urgent: the worst it can cause is
3898 the use of a bit of memory for a user lock which will not be used
3899 anymore. If the user lock is later used, the old one will be released. In
3900 other words, no deadlock problem.
3901 */
3902
do_apply_event(Relay_log_info const * rli)3903 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
3904 {
3905 DBUG_ENTER("Start_log_event_v3::do_apply_event");
3906 int error= 0;
3907 switch (binlog_version)
3908 {
3909 case 3:
3910 case 4:
3911 /*
3912 This can either be 4.x (then a Start_log_event_v3 is only at master
3913 startup so we are sure the master has restarted and cleared his temp
3914 tables; the event always has 'created'>0) or 5.0 (then we have to test
3915 'created').
3916 */
3917 if (created)
3918 {
3919 error= close_temporary_tables(thd);
3920 cleanup_load_tmpdir();
3921 }
3922 else
3923 {
3924 /*
3925 Set all temporary tables thread references to the current thread
3926 as they may point to the "old" SQL slave thread in case of its
3927 restart.
3928 */
3929 TABLE *table;
3930 for (table= thd->temporary_tables; table; table= table->next)
3931 table->in_use= thd;
3932 }
3933 break;
3934
3935 /*
3936 Now the older formats; in that case load_tmpdir is cleaned up by the I/O
3937 thread.
3938 */
3939 case 1:
3940 if (strncmp(rli->relay_log.description_event_for_exec->server_version,
3941 "3.23.57",7) >= 0 && created)
3942 {
3943 /*
3944 Can distinguish, based on the value of 'created': this event was
3945 generated at master startup.
3946 */
3947 error= close_temporary_tables(thd);
3948 }
3949 /*
3950 Otherwise, can't distinguish a Start_log_event generated at
3951 master startup and one generated by master FLUSH LOGS, so cannot
3952 be sure temp tables have to be dropped. So do nothing.
3953 */
3954 break;
3955 default:
3956 /*
3957 This case is not expected. It can be either an event corruption or an
3958 unsupported binary log version.
3959 */
3960 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3961 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
3962 "Binlog version not supported");
3963 DBUG_RETURN(1);
3964 }
3965 DBUG_RETURN(error);
3966 }
3967 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
3968
3969 /***************************************************************************
3970 Format_description_log_event methods
3971 ****************************************************************************/
3972
3973 /**
3974 Format_description_log_event 1st ctor.
3975
3976 Ctor. Can be used to create the event to write to the binary log (when the
3977 server starts or when FLUSH LOGS), or to create artificial events to parse
3978 binlogs from MySQL 3.23 or 4.x.
3979 When in a client, only the 2nd use is possible.
3980
3981 @param binlog_version the binlog version for which we want to build
3982 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
3983 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
3984 old 4.0 (binlog version 2) is not supported;
3985 it should not be used for replication with
3986 5.0.
3987 */
3988
3989 Format_description_log_event::
Format_description_log_event(uint8 binlog_ver,const char * server_ver)3990 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
3991 :Start_log_event_v3(), event_type_permutation(0)
3992 {
3993 binlog_version= binlog_ver;
3994 switch (binlog_ver) {
3995 case 4: /* MySQL 5.0 */
3996 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
3997 DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
3998 strmov(server_version, "5.0.34"););
3999 common_header_len= LOG_EVENT_HEADER_LEN;
4000 number_of_event_types= LOG_EVENT_TYPES;
4001 /* we'll catch my_malloc() error in is_valid() */
4002 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
4003 MYF(0));
4004
4005 /*
4006 This long list of assignments is not beautiful, but I see no way to
4007 make it nicer, as the right members are #defines, not array members, so
4008 it's impossible to write a loop.
4009 */
4010 if (post_header_len)
4011 {
4012 #ifndef DBUG_OFF
4013 // Allows us to sanity-check that all events initialized their
4014 // events (see the end of this 'if' block).
4015 memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
4016 #endif
4017
4018 /* Note: all event types must explicitly fill in their lengths here. */
4019 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
4020 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
4021 post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
4022 post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
4023 post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
4024 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
4025 post_header_len[SLAVE_EVENT-1]= SLAVE_HEADER_LEN;
4026 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
4027 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
4028 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
4029 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
4030 post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
4031 post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
4032 post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
4033 post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
4034 post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
4035 post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
4036 post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
4037 /*
4038 The PRE_GA events are never be written to any binlog, but
4039 their lengths are included in Format_description_log_event.
4040 Hence, we need to be assign some value here, to avoid reading
4041 uninitialized memory when the array is written to disk.
4042 */
4043 post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
4044 post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
4045 post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
4046
4047 post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
4048 post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
4049 post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
4050 post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
4051 /*
4052 We here have the possibility to simulate a master of before we changed
4053 the table map id to be stored in 6 bytes: when it was stored in 4
4054 bytes (=> post_header_len was 6). This is used to test backward
4055 compatibility.
4056 This code can be removed after a few months (today is Dec 21st 2005),
4057 when we know that the 4-byte masters are not deployed anymore (check
4058 with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
4059 too.
4060 */
4061 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
4062 post_header_len[TABLE_MAP_EVENT-1]=
4063 post_header_len[WRITE_ROWS_EVENT-1]=
4064 post_header_len[UPDATE_ROWS_EVENT-1]=
4065 post_header_len[DELETE_ROWS_EVENT-1]= 6;);
4066 post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
4067 post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
4068
4069 // Sanity-check that all post header lengths are initialized.
4070 int i;
4071 for (i=0; i<number_of_event_types; i++)
4072 DBUG_ASSERT(post_header_len[i] != 255);
4073 }
4074 break;
4075
4076 case 1: /* 3.23 */
4077 case 3: /* 4.0.x x>=2 */
4078 /*
4079 We build an artificial (i.e. not sent by the master) event, which
4080 describes what those old master versions send.
4081 */
4082 if (binlog_ver==1)
4083 strmov(server_version, server_ver ? server_ver : "3.23");
4084 else
4085 strmov(server_version, server_ver ? server_ver : "4.0");
4086 common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
4087 LOG_EVENT_MINIMAL_HEADER_LEN;
4088 /*
4089 The first new event in binlog version 4 is Format_desc. So any event type
4090 after that does not exist in older versions. We use the events known by
4091 version 3, even if version 1 had only a subset of them (this is not a
4092 problem: it uses a few bytes for nothing but unifies code; it does not
4093 make the slave detect less corruptions).
4094 */
4095 number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
4096 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
4097 MYF(0));
4098 if (post_header_len)
4099 {
4100 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
4101 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
4102 post_header_len[STOP_EVENT-1]= 0;
4103 post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
4104 post_header_len[INTVAR_EVENT-1]= 0;
4105 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
4106 post_header_len[SLAVE_EVENT-1]= 0;
4107 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
4108 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
4109 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
4110 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
4111 post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
4112 post_header_len[RAND_EVENT-1]= 0;
4113 post_header_len[USER_VAR_EVENT-1]= 0;
4114 }
4115 break;
4116 default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
4117 post_header_len= 0; /* will make is_valid() fail */
4118 break;
4119 }
4120 calc_server_version_split();
4121 }
4122
4123
4124 /**
4125 The problem with this constructor is that the fixed header may have a
4126 length different from this version, but we don't know this length as we
4127 have not read the Format_description_log_event which says it, yet. This
4128 length is in the post-header of the event, but we don't know where the
4129 post-header starts.
4130
4131 So this type of event HAS to:
4132 - either have the header's length at the beginning (in the header, at a
4133 fixed position which will never be changed), not in the post-header. That
4134 would make the header be "shifted" compared to other events.
4135 - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
4136 versions, so that we know for sure.
4137
4138 I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
4139 it is sent before Format_description_log_event).
4140 */
4141
4142 Format_description_log_event::
Format_description_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)4143 Format_description_log_event(const char* buf,
4144 uint event_len,
4145 const
4146 Format_description_log_event*
4147 description_event)
4148 :Start_log_event_v3(buf, event_len, description_event),
4149 common_header_len(0), post_header_len(NULL), event_type_permutation(0)
4150 {
4151 DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
4152 if (!Start_log_event_v3::is_valid())
4153 DBUG_VOID_RETURN; /* sanity check */
4154 buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
4155 if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
4156 DBUG_VOID_RETURN; /* sanity check */
4157 number_of_event_types=
4158 event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
4159 DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
4160 common_header_len, number_of_event_types));
4161 /* If alloc fails, we'll detect it in is_valid() */
4162 post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
4163 number_of_event_types*
4164 sizeof(*post_header_len), MYF(0));
4165 calc_server_version_split();
4166
4167 /*
4168 In some previous versions, the events were given other event type
4169 id numbers than in the present version. When replicating from such
4170 a version, we therefore set up an array that maps those id numbers
4171 to the id numbers of the present server.
4172
4173 If post_header_len is null, it means malloc failed, and is_valid
4174 will fail, so there is no need to do anything.
4175
4176 The trees in which events have wrong id's are:
4177
4178 mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
4179 mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
4180 mysql-5.1-wl2325-no-dd
4181
4182 (this was found by grepping for two lines in sequence where the
4183 first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
4184 "TABLE_MAP_EVENT," in log_event.h in all trees)
4185
4186 In these trees, the following server_versions existed since
4187 TABLE_MAP_EVENT was introduced:
4188
4189 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
4190 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
4191 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
4192 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
4193 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
4194 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
4195 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
4196 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
4197 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
4198 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
4199 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
4200 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
4201 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
4202 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
4203 5.2.2-a_drop6p13c
4204
4205 (this was found by grepping for "mysql," in all historical
4206 versions of configure.in in the trees listed above).
4207
4208 There are 5.1.1-alpha versions that use the new event id's, so we
4209 do not test that version string. So replication from 5.1.1-alpha
4210 with the other event id's to a new version does not work.
4211 Moreover, we can safely ignore the part after drop[56]. This
4212 allows us to simplify the big list above to the following regexes:
4213
4214 5\.1\.[1-5]-a_drop5.*
4215 5\.1\.4-a_drop6.*
4216 5\.2\.[0-2]-a_drop6.*
4217
4218 This is what we test for in the 'if' below.
4219 */
4220 if (post_header_len &&
4221 server_version[0] == '5' && server_version[1] == '.' &&
4222 server_version[3] == '.' &&
4223 strncmp(server_version + 5, "-a_drop", 7) == 0 &&
4224 ((server_version[2] == '1' &&
4225 server_version[4] >= '1' && server_version[4] <= '5' &&
4226 server_version[12] == '5') ||
4227 (server_version[2] == '1' &&
4228 server_version[4] == '4' &&
4229 server_version[12] == '6') ||
4230 (server_version[2] == '2' &&
4231 server_version[4] >= '0' && server_version[4] <= '2' &&
4232 server_version[12] == '6')))
4233 {
4234 if (number_of_event_types != 22)
4235 {
4236 DBUG_PRINT("info", (" number_of_event_types=%d",
4237 number_of_event_types));
4238 /* this makes is_valid() return false. */
4239 my_free(post_header_len);
4240 post_header_len= NULL;
4241 DBUG_VOID_RETURN;
4242 }
4243 static const uint8 perm[23]=
4244 {
4245 UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
4246 INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
4247 APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
4248 NEW_LOAD_EVENT,
4249 RAND_EVENT, USER_VAR_EVENT,
4250 FORMAT_DESCRIPTION_EVENT,
4251 TABLE_MAP_EVENT,
4252 PRE_GA_WRITE_ROWS_EVENT,
4253 PRE_GA_UPDATE_ROWS_EVENT,
4254 PRE_GA_DELETE_ROWS_EVENT,
4255 XID_EVENT,
4256 BEGIN_LOAD_QUERY_EVENT,
4257 EXECUTE_LOAD_QUERY_EVENT,
4258 };
4259 event_type_permutation= perm;
4260 /*
4261 Since we use (permuted) event id's to index the post_header_len
4262 array, we need to permute the post_header_len array too.
4263 */
4264 uint8 post_header_len_temp[23];
4265 for (int i= 1; i < 23; i++)
4266 post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
4267 for (int i= 0; i < 22; i++)
4268 post_header_len[i] = post_header_len_temp[i];
4269 }
4270 DBUG_VOID_RETURN;
4271 }
4272
4273 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)4274 bool Format_description_log_event::write(IO_CACHE* file)
4275 {
4276 /*
4277 We don't call Start_log_event_v3::write() because this would make 2
4278 my_b_safe_write().
4279 */
4280 uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
4281 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
4282 memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
4283 if (!dont_set_created)
4284 created= when= get_time();
4285 int4store(buff + ST_CREATED_OFFSET,created);
4286 buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
4287 memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
4288 LOG_EVENT_TYPES);
4289 return (write_header(file, sizeof(buff)) ||
4290 my_b_safe_write(file, buff, sizeof(buff)));
4291 }
4292 #endif
4293
4294 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)4295 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
4296 {
4297 int ret= 0;
4298 DBUG_ENTER("Format_description_log_event::do_apply_event");
4299
4300 /*
4301 As a transaction NEVER spans on 2 or more binlogs:
4302 if we have an active transaction at this point, the master died
4303 while writing the transaction to the binary log, i.e. while
4304 flushing the binlog cache to the binlog. XA guarantees that master has
4305 rolled back. So we roll back.
4306 Note: this event could be sent by the master to inform us of the
4307 format of its binlog; in other words maybe it is not at its
4308 original place when it comes to us; we'll know this by checking
4309 log_pos ("artificial" events have log_pos == 0).
4310 */
4311 if (!is_artificial_event() && created && thd->transaction.all.ha_list)
4312 {
4313 /* This is not an error (XA is safe), just an information */
4314 rli->report(INFORMATION_LEVEL, 0,
4315 "Rolling back unfinished transaction (no COMMIT "
4316 "or ROLLBACK in relay log). A probable cause is that "
4317 "the master died while writing the transaction to "
4318 "its binary log, thus rolled back too.");
4319 const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
4320 }
4321
4322 /*
4323 If this event comes from ourselves, there is no cleaning task to
4324 perform, we don't call Start_log_event_v3::do_apply_event()
4325 (this was just to update the log's description event).
4326 */
4327 if (server_id != (uint32) ::server_id)
4328 {
4329 /*
4330 If the event was not requested by the slave i.e. the master sent
4331 it while the slave asked for a position >4, the event will make
4332 rli->group_master_log_pos advance. Say that the slave asked for
4333 position 1000, and the Format_desc event's end is 96. Then in
4334 the beginning of replication rli->group_master_log_pos will be
4335 0, then 96, then jump to first really asked event (which is
4336 >96). So this is ok.
4337 */
4338 ret= Start_log_event_v3::do_apply_event(rli);
4339 }
4340
4341 if (!ret)
4342 {
4343 /* Save the information describing this binlog */
4344 delete rli->relay_log.description_event_for_exec;
4345 const_cast<Relay_log_info *>(rli)->relay_log.description_event_for_exec= this;
4346 }
4347
4348 DBUG_RETURN(ret);
4349 }
4350
do_update_pos(Relay_log_info * rli)4351 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
4352 {
4353 if (server_id == (uint32) ::server_id)
4354 {
4355 /*
4356 We only increase the relay log position if we are skipping
4357 events and do not touch any group_* variables, nor flush the
4358 relay log info. If there is a crash, we will have to re-skip
4359 the events again, but that is a minor issue.
4360
4361 If we do not skip stepping the group log position (and the
4362 server id was changed when restarting the server), it might well
4363 be that we start executing at a position that is invalid, e.g.,
4364 at a Rows_log_event or a Query_log_event preceeded by a
4365 Intvar_log_event instead of starting at a Table_map_log_event or
4366 the Intvar_log_event respectively.
4367 */
4368 rli->inc_event_relay_log_pos();
4369 return 0;
4370 }
4371 else
4372 {
4373 return Log_event::do_update_pos(rli);
4374 }
4375 }
4376
4377 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)4378 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
4379 {
4380 return Log_event::EVENT_SKIP_NOT;
4381 }
4382
4383 #endif
4384
4385
4386 /**
4387 Splits the event's 'server_version' string into three numeric pieces stored
4388 into 'server_version_split':
4389 X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
4390 X.Yabc -> {X,Y,0}
4391 'server_version_split' is then used for lookups to find if the server which
4392 created this event has some known bug.
4393 */
calc_server_version_split()4394 void Format_description_log_event::calc_server_version_split()
4395 {
4396 char *p= server_version, *r;
4397 ulong number;
4398 for (uint i= 0; i<=2; i++)
4399 {
4400 number= strtoul(p, &r, 10);
4401 /*
4402 It is an invalid version if any version number greater than 255 or
4403 first number is not followed by '.'.
4404 */
4405 if (number < 256 && (*r == '.' || i != 0))
4406 server_version_split[i]= (uchar)number;
4407 else
4408 {
4409 server_version_split[0]= 0;
4410 server_version_split[1]= 0;
4411 server_version_split[2]= 0;
4412 break;
4413 }
4414
4415 p= r;
4416 if (*r == '.')
4417 p++; // skip the dot
4418 }
4419 DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
4420 " '%s' %d %d %d", server_version,
4421 server_version_split[0],
4422 server_version_split[1], server_version_split[2]));
4423 }
4424
4425
4426 /**************************************************************************
4427 Load_log_event methods
4428 General note about Load_log_event: the binlogging of LOAD DATA INFILE is
4429 going to be changed in 5.0 (or maybe in 5.1; not decided yet).
4430 However, the 5.0 slave could still have to read such events (from a 4.x
4431 master), convert them (which just means maybe expand the header, when 5.0
4432 servers have a UID in events) (remember that whatever is after the header
4433 will be like in 4.x, as this event's format is not modified in 5.0 as we
4434 will use new types of events to log the new LOAD DATA INFILE features).
4435 To be able to read/convert, we just need to not assume that the common
4436 header is of length LOG_EVENT_HEADER_LEN (we must use the description
4437 event).
4438 Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
4439 between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
4440 positions displayed in SHOW SLAVE STATUS then are fine too).
4441 **************************************************************************/
4442
4443 /*
4444 Load_log_event::pack_info()
4445 */
4446
4447 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_query_buffer_length()4448 uint Load_log_event::get_query_buffer_length()
4449 {
4450 return
4451 //the DB name may double if we escape the quote character
4452 5 + 2*db_len + 3 +
4453 18 + fname_len*4 + 2 + // "LOAD DATA INFILE 'file''"
4454 11 + // "CONCURRENT "
4455 7 + // LOCAL
4456 9 + // " REPLACE or IGNORE "
4457 13 + table_name_len*2 + // "INTO TABLE `table`"
4458 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
4459 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
4460 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
4461 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
4462 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
4463 15 + 22 + // " IGNORE xxx LINES"
4464 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
4465 }
4466
4467
print_query(bool need_db,const char * cs,char * buf,char ** end,char ** fn_start,char ** fn_end)4468 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
4469 char **end, char **fn_start, char **fn_end)
4470 {
4471 char quoted_id[1 + NAME_LEN * 2 + 2];//quoted length
4472 int quoted_id_len= 0;
4473 char *pos= buf;
4474
4475 if (need_db && db && db_len)
4476 {
4477 pos= strmov(pos, "use ");
4478 #ifdef MYSQL_SERVER
4479 quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
4480 db, 0);
4481 #else
4482 quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
4483 #endif
4484 quoted_id[quoted_id_len]= '\0';
4485 pos= strmov(pos, quoted_id);
4486 pos= strmov(pos, "; ");
4487 }
4488
4489 pos= strmov(pos, "LOAD DATA ");
4490
4491 if (is_concurrent)
4492 pos= strmov(pos, "CONCURRENT ");
4493
4494 if (fn_start)
4495 *fn_start= pos;
4496
4497 if (check_fname_outside_temp_buf())
4498 pos= strmov(pos, "LOCAL ");
4499 pos= strmov(pos, "INFILE ");
4500 pos= pretty_print_str(pos, fname, fname_len);
4501 pos= strmov(pos, " ");
4502
4503 if (sql_ex.opt_flags & REPLACE_FLAG)
4504 pos= strmov(pos, "REPLACE ");
4505 else if (sql_ex.opt_flags & IGNORE_FLAG)
4506 pos= strmov(pos, "IGNORE ");
4507
4508 pos= strmov(pos ,"INTO");
4509
4510 if (fn_end)
4511 *fn_end= pos;
4512
4513 pos= strmov(pos ," TABLE ");
4514 memcpy(pos, table_name, table_name_len);
4515 pos+= table_name_len;
4516
4517 if (cs != NULL)
4518 {
4519 pos= strmov(pos ," CHARACTER SET ");
4520 pos= strmov(pos , cs);
4521 }
4522
4523 /* We have to create all optional fields as the default is not empty */
4524 pos= strmov(pos, " FIELDS TERMINATED BY ");
4525 pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
4526 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
4527 pos= strmov(pos, " OPTIONALLY ");
4528 pos= strmov(pos, " ENCLOSED BY ");
4529 pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
4530
4531 pos= strmov(pos, " ESCAPED BY ");
4532 pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
4533
4534 pos= strmov(pos, " LINES TERMINATED BY ");
4535 pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
4536 if (sql_ex.line_start_len)
4537 {
4538 pos= strmov(pos, " STARTING BY ");
4539 pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
4540 }
4541
4542 if ((long) skip_lines > 0)
4543 {
4544 pos= strmov(pos, " IGNORE ");
4545 pos= longlong10_to_str((longlong) skip_lines, pos, 10);
4546 pos= strmov(pos," LINES ");
4547 }
4548
4549 if (num_fields)
4550 {
4551 uint i;
4552 const char *field= fields;
4553 pos= strmov(pos, " (");
4554 for (i = 0; i < num_fields; i++)
4555 {
4556 if (i)
4557 {
4558 *pos++= ' ';
4559 *pos++= ',';
4560 }
4561 quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
4562 0);
4563 memcpy(pos, quoted_id, quoted_id_len);
4564 }
4565 *pos++= ')';
4566 }
4567
4568 *end= pos;
4569 }
4570
4571
pack_info(Protocol * protocol)4572 void Load_log_event::pack_info(Protocol *protocol)
4573 {
4574 char *buf, *end;
4575
4576 if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
4577 return;
4578 print_query(TRUE, NULL, buf, &end, 0, 0);
4579 protocol->store(buf, end-buf, &my_charset_bin);
4580 my_free(buf);
4581 }
4582 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4583
4584
4585 #ifndef MYSQL_CLIENT
4586
4587 /*
4588 Load_log_event::write_data_header()
4589 */
4590
write_data_header(IO_CACHE * file)4591 bool Load_log_event::write_data_header(IO_CACHE* file)
4592 {
4593 char buf[LOAD_HEADER_LEN];
4594 int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
4595 int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
4596 int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
4597 buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
4598 buf[L_DB_LEN_OFFSET] = (char)db_len;
4599 int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
4600 return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
4601 }
4602
4603
4604 /*
4605 Load_log_event::write_data_body()
4606 */
4607
write_data_body(IO_CACHE * file)4608 bool Load_log_event::write_data_body(IO_CACHE* file)
4609 {
4610 if (sql_ex.write_data(file))
4611 return 1;
4612 if (num_fields && fields && field_lens)
4613 {
4614 if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
4615 my_b_safe_write(file, (uchar*)fields, field_block_len))
4616 return 1;
4617 }
4618 return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
4619 my_b_safe_write(file, (uchar*)db, db_len + 1) ||
4620 my_b_safe_write(file, (uchar*)fname, fname_len));
4621 }
4622
4623
4624 /*
4625 Load_log_event::Load_log_event()
4626 */
4627
Load_log_event(THD * thd_arg,sql_exchange * ex,const char * db_arg,const char * table_name_arg,List<Item> & fields_arg,bool is_concurrent_arg,enum enum_duplicates handle_dup,bool ignore,bool using_trans)4628 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
4629 const char *db_arg, const char *table_name_arg,
4630 List<Item> &fields_arg,
4631 bool is_concurrent_arg,
4632 enum enum_duplicates handle_dup,
4633 bool ignore, bool using_trans)
4634 :Log_event(thd_arg,
4635 thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
4636 using_trans),
4637 thread_id(thd_arg->thread_id),
4638 slave_proxy_id(thd_arg->variables.pseudo_thread_id),
4639 num_fields(0),fields(0),
4640 field_lens(0),field_block_len(0),
4641 table_name(table_name_arg ? table_name_arg : ""),
4642 db(db_arg), fname(ex->file_name), local_fname(FALSE),
4643 is_concurrent(is_concurrent_arg)
4644 {
4645 time_t end_time;
4646 time(&end_time);
4647 exec_time = (ulong) (end_time - thd_arg->start_time);
4648 /* db can never be a zero pointer in 4.0 */
4649 db_len = (uint32) strlen(db);
4650 table_name_len = (uint32) strlen(table_name);
4651 fname_len = (fname) ? (uint) strlen(fname) : 0;
4652 sql_ex.field_term = (char*) ex->field_term->ptr();
4653 sql_ex.field_term_len = (uint8) ex->field_term->length();
4654 sql_ex.enclosed = (char*) ex->enclosed->ptr();
4655 sql_ex.enclosed_len = (uint8) ex->enclosed->length();
4656 sql_ex.line_term = (char*) ex->line_term->ptr();
4657 sql_ex.line_term_len = (uint8) ex->line_term->length();
4658 sql_ex.line_start = (char*) ex->line_start->ptr();
4659 sql_ex.line_start_len = (uint8) ex->line_start->length();
4660 sql_ex.escaped = (char*) ex->escaped->ptr();
4661 sql_ex.escaped_len = (uint8) ex->escaped->length();
4662 sql_ex.opt_flags = 0;
4663 sql_ex.cached_new_format = -1;
4664
4665 if (ex->dumpfile)
4666 sql_ex.opt_flags|= DUMPFILE_FLAG;
4667 if (ex->opt_enclosed)
4668 sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
4669
4670 sql_ex.empty_flags= 0;
4671
4672 switch (handle_dup) {
4673 case DUP_REPLACE:
4674 sql_ex.opt_flags|= REPLACE_FLAG;
4675 break;
4676 case DUP_UPDATE: // Impossible here
4677 case DUP_ERROR:
4678 break;
4679 }
4680 if (ignore)
4681 sql_ex.opt_flags|= IGNORE_FLAG;
4682
4683 if (!ex->field_term->length())
4684 sql_ex.empty_flags |= FIELD_TERM_EMPTY;
4685 if (!ex->enclosed->length())
4686 sql_ex.empty_flags |= ENCLOSED_EMPTY;
4687 if (!ex->line_term->length())
4688 sql_ex.empty_flags |= LINE_TERM_EMPTY;
4689 if (!ex->line_start->length())
4690 sql_ex.empty_flags |= LINE_START_EMPTY;
4691 if (!ex->escaped->length())
4692 sql_ex.empty_flags |= ESCAPED_EMPTY;
4693
4694 skip_lines = ex->skip_lines;
4695
4696 List_iterator<Item> li(fields_arg);
4697 field_lens_buf.length(0);
4698 fields_buf.length(0);
4699 Item* item;
4700 while ((item = li++))
4701 {
4702 num_fields++;
4703 uchar len = (uchar) strlen(item->name);
4704 field_block_len += len + 1;
4705 fields_buf.append(item->name, len + 1);
4706 field_lens_buf.append((char*)&len, 1);
4707 }
4708
4709 field_lens = (const uchar*)field_lens_buf.ptr();
4710 fields = fields_buf.ptr();
4711 }
4712 #endif /* !MYSQL_CLIENT */
4713
4714
4715 /**
4716 @note
4717 The caller must do buf[event_len] = 0 before he starts using the
4718 constructed event.
4719 */
Load_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)4720 Load_log_event::Load_log_event(const char *buf, uint event_len,
4721 const Format_description_log_event *description_event)
4722 :Log_event(buf, description_event), num_fields(0), fields(0),
4723 field_lens(0),field_block_len(0),
4724 table_name(0), db(0), fname(0), local_fname(FALSE),
4725 /*
4726 Load_log_event which comes from the binary log does not contain
4727 information about the type of insert which was used on the master.
4728 Assume that it was an ordinary, non-concurrent LOAD DATA.
4729 */
4730 is_concurrent(FALSE)
4731 {
4732 DBUG_ENTER("Load_log_event");
4733 /*
4734 I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
4735 4.0->5.0 and 5.0->5.0 and it works.
4736 */
4737 if (event_len)
4738 copy_log_event(buf, event_len,
4739 ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
4740 LOAD_HEADER_LEN +
4741 description_event->common_header_len :
4742 LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
4743 description_event);
4744 /* otherwise it's a derived class, will call copy_log_event() itself */
4745 DBUG_VOID_RETURN;
4746 }
4747
4748
4749 /*
4750 Load_log_event::copy_log_event()
4751 */
4752
copy_log_event(const char * buf,ulong event_len,int body_offset,const Format_description_log_event * description_event)4753 int Load_log_event::copy_log_event(const char *buf, ulong event_len,
4754 int body_offset,
4755 const Format_description_log_event *description_event)
4756 {
4757 DBUG_ENTER("Load_log_event::copy_log_event");
4758 uint data_len;
4759 char* buf_end = (char*)buf + event_len;
4760 /* this is the beginning of the post-header */
4761 const char* data_head = buf + description_event->common_header_len;
4762 slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
4763 exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
4764 skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
4765 table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
4766 db_len = (uint)data_head[L_DB_LEN_OFFSET];
4767 num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
4768
4769 if ((int) event_len < body_offset)
4770 DBUG_RETURN(1);
4771 /*
4772 Sql_ex.init() on success returns the pointer to the first byte after
4773 the sql_ex structure, which is the start of field lengths array.
4774 */
4775 if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
4776 buf_end,
4777 buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
4778 DBUG_RETURN(1);
4779
4780 data_len = event_len - body_offset;
4781 if (num_fields > data_len) // simple sanity check against corruption
4782 DBUG_RETURN(1);
4783 for (uint i = 0; i < num_fields; i++)
4784 field_block_len += (uint)field_lens[i] + 1;
4785
4786 fields = (char*)field_lens + num_fields;
4787 table_name = fields + field_block_len;
4788 if (strlen(table_name) > NAME_LEN)
4789 goto err;
4790
4791 db = table_name + table_name_len + 1;
4792 DBUG_EXECUTE_IF ("simulate_invalid_address",
4793 db_len = data_len;);
4794 fname = db + db_len + 1;
4795 if ((db_len > data_len) || (fname > buf_end))
4796 goto err;
4797 fname_len = (uint) strlen(fname);
4798 if ((fname_len > data_len) || (fname + fname_len > buf_end))
4799 goto err;
4800 // null termination is accomplished by the caller doing buf[event_len]=0
4801
4802 DBUG_RETURN(0);
4803
4804 err:
4805 // Invalid event.
4806 table_name = 0;
4807 DBUG_RETURN(1);
4808 }
4809
4810
4811 /*
4812 Load_log_event::print()
4813 */
4814
4815 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)4816 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4817 {
4818 print(file, print_event_info, 0);
4819 }
4820
4821
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info,bool commented)4822 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
4823 bool commented)
4824 {
4825 size_t id_len= 0;
4826 char temp_buf[1 + 2*FN_REFLEN + 2];
4827 Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
4828
4829 DBUG_ENTER("Load_log_event::print");
4830 if (!print_event_info->short_form)
4831 {
4832 print_header(&cache, print_event_info, FALSE);
4833 my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
4834 thread_id, exec_time);
4835 }
4836
4837 bool different_db= 1;
4838 if (db)
4839 {
4840 /*
4841 If the database is different from the one of the previous statement, we
4842 need to print the "use" command, and we update the last_db.
4843 But if commented, the "use" is going to be commented so we should not
4844 update the last_db.
4845 */
4846 if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
4847 !commented)
4848 memcpy(print_event_info->db, db, db_len + 1);
4849 }
4850
4851 if (db && db[0] && different_db)
4852 {
4853 #ifdef MYSQL_SERVER
4854 id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
4855 #else
4856 id_len= my_strmov_quoted_identifier(temp_buf, db);
4857 #endif
4858 temp_buf[id_len]= '\0';
4859 my_b_printf(&cache, "%suse %s%s\n",
4860 commented ? "# " : "", temp_buf, print_event_info->delimiter);
4861 }
4862 if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
4863 my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
4864 commented ? "# " : "", (ulong)thread_id,
4865 print_event_info->delimiter);
4866 my_b_printf(&cache, "%sLOAD DATA ",
4867 commented ? "# " : "");
4868 if (check_fname_outside_temp_buf())
4869 my_b_printf(&cache, "LOCAL ");
4870 my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
4871
4872 if (sql_ex.opt_flags & REPLACE_FLAG)
4873 my_b_printf(&cache,"REPLACE ");
4874 else if (sql_ex.opt_flags & IGNORE_FLAG)
4875 my_b_printf(&cache,"IGNORE ");
4876
4877 #ifdef MYSQL_SERVER
4878 id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
4879 #else
4880 id_len= my_strmov_quoted_identifier(temp_buf, table_name);
4881 #endif
4882 temp_buf[id_len]= '\0';
4883 my_b_printf(&cache, "INTO TABLE %s", temp_buf);
4884 my_b_printf(&cache, " FIELDS TERMINATED BY ");
4885 pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
4886
4887 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
4888 my_b_printf(&cache," OPTIONALLY ");
4889 my_b_printf(&cache, " ENCLOSED BY ");
4890 pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
4891
4892 my_b_printf(&cache, " ESCAPED BY ");
4893 pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
4894
4895 my_b_printf(&cache," LINES TERMINATED BY ");
4896 pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
4897
4898
4899 if (sql_ex.line_start)
4900 {
4901 my_b_printf(&cache," STARTING BY ");
4902 pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
4903 }
4904 if ((long) skip_lines > 0)
4905 my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
4906
4907 if (num_fields)
4908 {
4909 uint i;
4910 const char* field = fields;
4911 my_b_printf(&cache, " (");
4912 for (i = 0; i < num_fields; i++)
4913 {
4914 if (i)
4915 my_b_printf(&cache, ",");
4916 id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
4917 temp_buf[id_len]= '\0';
4918 my_b_printf(&cache, "%s", temp_buf);
4919
4920 field += field_lens[i] + 1;
4921 }
4922 my_b_printf(&cache, ")");
4923 }
4924
4925 my_b_printf(&cache, "%s\n", print_event_info->delimiter);
4926 DBUG_VOID_RETURN;
4927 }
4928 #endif /* MYSQL_CLIENT */
4929
4930 #ifndef MYSQL_CLIENT
4931
4932 /**
4933 Load_log_event::set_fields()
4934
4935 @note
4936 This function can not use the member variable
4937 for the database, since LOAD DATA INFILE on the slave
4938 can be for a different database than the current one.
4939 This is the reason for the affected_db argument to this method.
4940 */
4941
set_fields(const char * affected_db,List<Item> & field_list,Name_resolution_context * context)4942 void Load_log_event::set_fields(const char* affected_db,
4943 List<Item> &field_list,
4944 Name_resolution_context *context)
4945 {
4946 uint i;
4947 const char* field = fields;
4948 for (i= 0; i < num_fields; i++)
4949 {
4950 field_list.push_back(new Item_field(context,
4951 affected_db, table_name, field));
4952 field+= field_lens[i] + 1;
4953 }
4954 }
4955 #endif /* !MYSQL_CLIENT */
4956
4957
4958 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4959 /**
4960 Does the data loading job when executing a LOAD DATA on the slave.
4961
4962 @param net
4963 @param rli
4964 @param use_rli_only_for_errors If set to 1, rli is provided to
4965 Load_log_event::exec_event only for this
4966 function to have RPL_LOG_NAME and
4967 rli->last_slave_error, both being used by
4968 error reports. rli's position advancing
4969 is skipped (done by the caller which is
4970 Execute_load_log_event::exec_event).
4971 If set to 0, rli is provided for full use,
4972 i.e. for error reports and position
4973 advancing.
4974
4975 @todo
4976 fix this; this can be done by testing rules in
4977 Create_file_log_event::exec_event() and then discarding Append_block and
4978 al.
4979 @todo
4980 this is a bug - this needs to be moved to the I/O thread
4981
4982 @retval
4983 0 Success
4984 @retval
4985 1 Failure
4986 */
4987
do_apply_event(NET * net,Relay_log_info const * rli,bool use_rli_only_for_errors)4988 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
4989 bool use_rli_only_for_errors)
4990 {
4991 LEX_STRING new_db;
4992 new_db.length= db_len;
4993 new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
4994 thd->set_db(new_db.str, new_db.length);
4995 DBUG_ASSERT(thd->query() == 0);
4996 thd->reset_query_inner(); // Should not be needed
4997 thd->is_slave_error= 0;
4998 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4999
5000 /* see Query_log_event::do_apply_event() and BUG#13360 */
5001 DBUG_ASSERT(!rli->m_table_map.count());
5002 /*
5003 Usually lex_start() is called by mysql_parse(), but we need it here
5004 as the present method does not call mysql_parse().
5005 */
5006 lex_start(thd);
5007 thd->lex->local_file= local_fname;
5008 mysql_reset_thd_for_next_command(thd);
5009
5010 if (!use_rli_only_for_errors)
5011 {
5012 /*
5013 Saved for InnoDB, see comment in
5014 Query_log_event::do_apply_event()
5015 */
5016 const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
5017 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
5018 }
5019
5020 /*
5021 We test replicate_*_db rules. Note that we have already prepared
5022 the file to load, even if we are going to ignore and delete it
5023 now. So it is possible that we did a lot of disk writes for
5024 nothing. In other words, a big LOAD DATA INFILE on the master will
5025 still consume a lot of space on the slave (space in the relay log
5026 + space of temp files: twice the space of the file to load...)
5027 even if it will finally be ignored. TODO: fix this; this can be
5028 done by testing rules in Create_file_log_event::do_apply_event()
5029 and then discarding Append_block and al. Another way is do the
5030 filtering in the I/O thread (more efficient: no disk writes at
5031 all).
5032
5033
5034 Note: We do not need to execute reset_one_shot_variables() if this
5035 db_ok() test fails.
5036 Reason: The db stored in binlog events is the same for SET and for
5037 its companion query. If the SET is ignored because of
5038 db_ok(), the companion query will also be ignored, and if
5039 the companion query is ignored in the db_ok() test of
5040 ::do_apply_event(), then the companion SET also have so
5041 we don't need to reset_one_shot_variables().
5042 */
5043 if (rpl_filter->db_ok(thd->db))
5044 {
5045 thd->set_time((time_t)when);
5046 thd->set_query_id(next_query_id());
5047 thd->warning_info->opt_clear_warning_info(thd->query_id);
5048
5049 TABLE_LIST tables;
5050 tables.init_one_table(thd->strmake(thd->db, thd->db_length),
5051 thd->db_length,
5052 table_name, strlen(table_name),
5053 table_name, TL_WRITE);
5054 tables.updating= 1;
5055
5056 // the table will be opened in mysql_load
5057 if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
5058 {
5059 // TODO: this is a bug - this needs to be moved to the I/O thread
5060 if (net)
5061 skip_load_data_infile(net);
5062 }
5063 else
5064 {
5065 char llbuff[22];
5066 char *end;
5067 enum enum_duplicates handle_dup;
5068 bool ignore= 0;
5069 char *load_data_query;
5070
5071 /*
5072 Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
5073 and written to slave's binlog if binlogging is on.
5074 */
5075 if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
5076 {
5077 /*
5078 This will set thd->fatal_error in case of OOM. So we surely will notice
5079 that something is wrong.
5080 */
5081 goto error;
5082 }
5083
5084 print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
5085 *end= 0;
5086 thd->set_query(load_data_query, (uint) (end - load_data_query));
5087
5088 if (sql_ex.opt_flags & REPLACE_FLAG)
5089 handle_dup= DUP_REPLACE;
5090 else if (sql_ex.opt_flags & IGNORE_FLAG)
5091 {
5092 ignore= 1;
5093 handle_dup= DUP_ERROR;
5094 }
5095 else
5096 {
5097 /*
5098 When replication is running fine, if it was DUP_ERROR on the
5099 master then we could choose IGNORE here, because if DUP_ERROR
5100 suceeded on master, and data is identical on the master and slave,
5101 then there should be no uniqueness errors on slave, so IGNORE is
5102 the same as DUP_ERROR. But in the unlikely case of uniqueness errors
5103 (because the data on the master and slave happen to be different
5104 (user error or bug), we want LOAD DATA to print an error message on
5105 the slave to discover the problem.
5106
5107 If reading from net (a 3.23 master), mysql_load() will change this
5108 to IGNORE.
5109 */
5110 handle_dup= DUP_ERROR;
5111 }
5112 /*
5113 We need to set thd->lex->sql_command and thd->lex->duplicates
5114 since InnoDB tests these variables to decide if this is a LOAD
5115 DATA ... REPLACE INTO ... statement even though mysql_parse()
5116 is not called. This is not needed in 5.0 since there the LOAD
5117 DATA ... statement is replicated using mysql_parse(), which
5118 sets the thd->lex fields correctly.
5119 */
5120 thd->lex->sql_command= SQLCOM_LOAD;
5121 thd->lex->duplicates= handle_dup;
5122
5123 sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
5124 String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
5125 String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
5126 String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
5127 String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
5128 String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
5129 ex.field_term= &field_term;
5130 ex.enclosed= &enclosed;
5131 ex.line_term= &line_term;
5132 ex.line_start= &line_start;
5133 ex.escaped= &escaped;
5134
5135 ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
5136 if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
5137 ex.field_term->length(0);
5138
5139 ex.skip_lines = skip_lines;
5140 List<Item> field_list;
5141 thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
5142 set_fields(tables.db, field_list, &thd->lex->select_lex.context);
5143 thd->variables.pseudo_thread_id= thread_id;
5144 if (net)
5145 {
5146 // mysql_load will use thd->net to read the file
5147 thd->net.vio = net->vio;
5148 // Make sure the client does not get confused about the packet sequence
5149 thd->net.pkt_nr = net->pkt_nr;
5150 }
5151 /*
5152 It is safe to use tmp_list twice because we are not going to
5153 update it inside mysql_load().
5154 */
5155 List<Item> tmp_list;
5156 if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
5157 handle_dup, ignore, net != 0))
5158 thd->is_slave_error= 1;
5159 if (thd->cuted_fields)
5160 {
5161 /* log_pos is the position of the LOAD event in the master log */
5162 sql_print_warning("Slave: load data infile on table '%s' at "
5163 "log position %s in log '%s' produced %ld "
5164 "warning(s). Default database: '%s'",
5165 (char*) table_name,
5166 llstr(log_pos,llbuff), RPL_LOG_NAME,
5167 (ulong) thd->cuted_fields,
5168 print_slave_db_safe(thd->db));
5169 }
5170 if (net)
5171 net->pkt_nr= thd->net.pkt_nr;
5172 }
5173 }
5174 else
5175 {
5176 /*
5177 We will just ask the master to send us /dev/null if we do not
5178 want to load the data.
5179 TODO: this a bug - needs to be done in I/O thread
5180 */
5181 if (net)
5182 skip_load_data_infile(net);
5183 }
5184
5185 error:
5186 thd->net.vio = 0;
5187 const char *remember_db= thd->db;
5188 thd->catalog= 0;
5189 thd->set_db(NULL, 0); /* will free the current database */
5190 thd->reset_query();
5191 thd->stmt_da->can_overwrite_status= TRUE;
5192 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
5193 thd->stmt_da->can_overwrite_status= FALSE;
5194 close_thread_tables(thd);
5195 /*
5196 - If transaction rollback was requested due to deadlock
5197 perform it and release metadata locks.
5198 - If inside a multi-statement transaction,
5199 defer the release of metadata locks until the current
5200 transaction is either committed or rolled back. This prevents
5201 other statements from modifying the table for the entire
5202 duration of this transaction. This provides commit ordering
5203 and guarantees serializability across multiple transactions.
5204 - If in autocommit mode, or outside a transactional context,
5205 automatically release metadata locks of the current statement.
5206 */
5207 if (thd->transaction_rollback_request)
5208 {
5209 trans_rollback_implicit(thd);
5210 thd->mdl_context.release_transactional_locks();
5211 }
5212 else if (! thd->in_multi_stmt_transaction_mode())
5213 thd->mdl_context.release_transactional_locks();
5214 else
5215 thd->mdl_context.release_statement_locks();
5216
5217 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
5218 thd->is_slave_error= 0; thd->is_fatal_error= 1;);
5219
5220 if (thd->is_slave_error)
5221 {
5222 /* this err/sql_errno code is copy-paste from net_send_error() */
5223 const char *err;
5224 int sql_errno;
5225 if (thd->is_error())
5226 {
5227 err= thd->stmt_da->message();
5228 sql_errno= thd->stmt_da->sql_errno();
5229 }
5230 else
5231 {
5232 sql_errno=ER_UNKNOWN_ERROR;
5233 err=ER(sql_errno);
5234 }
5235 rli->report(ERROR_LEVEL, sql_errno,"\
5236 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
5237 err, (char*)table_name, print_slave_db_safe(remember_db));
5238 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5239 return 1;
5240 }
5241 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5242
5243 if (thd->is_fatal_error)
5244 {
5245 char buf[256];
5246 my_snprintf(buf, sizeof(buf),
5247 "Running LOAD DATA INFILE on table '%-.64s'."
5248 " Default database: '%-.64s'",
5249 (char*)table_name,
5250 print_slave_db_safe(remember_db));
5251
5252 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5253 ER(ER_SLAVE_FATAL_ERROR), buf);
5254 return 1;
5255 }
5256
5257 return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
5258 }
5259 #endif
5260
5261
5262 /**************************************************************************
5263 Rotate_log_event methods
5264 **************************************************************************/
5265
5266 /*
5267 Rotate_log_event::pack_info()
5268 */
5269
5270 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5271 void Rotate_log_event::pack_info(Protocol *protocol)
5272 {
5273 char buf1[256], buf[22];
5274 String tmp(buf1, sizeof(buf1), log_cs);
5275 tmp.length(0);
5276 tmp.append(new_log_ident, ident_len);
5277 tmp.append(STRING_WITH_LEN(";pos="));
5278 tmp.append(llstr(pos,buf));
5279 protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
5280 }
5281 #endif
5282
5283
5284 /*
5285 Rotate_log_event::print()
5286 */
5287
5288 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5289 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5290 {
5291 char buf[22];
5292 Write_on_release_cache cache(&print_event_info->head_cache, file,
5293 Write_on_release_cache::FLUSH_F);
5294
5295 if (print_event_info->short_form)
5296 return;
5297 print_header(&cache, print_event_info, FALSE);
5298 my_b_printf(&cache, "\tRotate to ");
5299 if (new_log_ident)
5300 my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
5301 my_b_printf(&cache, " pos: %s\n", llstr(pos, buf));
5302 }
5303 #endif /* MYSQL_CLIENT */
5304
5305
5306
5307 /*
5308 Rotate_log_event::Rotate_log_event() (2 constructors)
5309 */
5310
5311
5312 #ifndef MYSQL_CLIENT
Rotate_log_event(const char * new_log_ident_arg,uint ident_len_arg,ulonglong pos_arg,uint flags_arg)5313 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
5314 uint ident_len_arg, ulonglong pos_arg,
5315 uint flags_arg)
5316 :Log_event(), new_log_ident(new_log_ident_arg),
5317 pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
5318 (uint) strlen(new_log_ident_arg)), flags(flags_arg)
5319 {
5320 #ifndef DBUG_OFF
5321 char buff[22];
5322 DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
5323 DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
5324 llstr(pos_arg, buff), (ulong) flags));
5325 #endif
5326 if (flags & DUP_NAME)
5327 new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
5328 if (flags & RELAY_LOG)
5329 set_relay_log_event();
5330 DBUG_VOID_RETURN;
5331 }
5332 #endif
5333
5334
Rotate_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5335 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
5336 const Format_description_log_event* description_event)
5337 :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
5338 {
5339 DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
5340 // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
5341 uint8 header_size= description_event->common_header_len;
5342 uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
5343 uint ident_offset;
5344 if (event_len < header_size)
5345 DBUG_VOID_RETURN;
5346 buf += header_size;
5347 pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
5348 ident_len = (uint)(event_len -
5349 (header_size+post_header_len));
5350 ident_offset = post_header_len;
5351 set_if_smaller(ident_len,FN_REFLEN-1);
5352 new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
5353 DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
5354 DBUG_VOID_RETURN;
5355 }
5356
5357
5358 /*
5359 Rotate_log_event::write()
5360 */
5361
5362 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5363 bool Rotate_log_event::write(IO_CACHE* file)
5364 {
5365 char buf[ROTATE_HEADER_LEN];
5366 int8store(buf + R_POS_OFFSET, pos);
5367 return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
5368 my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
5369 my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
5370 }
5371 #endif
5372
5373
5374 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5375
5376 /*
5377 Got a rotate log event from the master.
5378
5379 This is mainly used so that we can later figure out the logname and
5380 position for the master.
5381
5382 We can't rotate the slave's BINlog as this will cause infinitive rotations
5383 in a A -> B -> A setup.
5384 The NOTES below is a wrong comment which will disappear when 4.1 is merged.
5385
5386 @retval
5387 0 ok
5388 */
do_update_pos(Relay_log_info * rli)5389 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
5390 {
5391 DBUG_ENTER("Rotate_log_event::do_update_pos");
5392 #ifndef DBUG_OFF
5393 char buf[32];
5394 #endif
5395
5396 DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
5397 (ulong) this->server_id, (ulong) ::server_id));
5398 DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
5399 DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
5400
5401 /*
5402 If we are in a transaction or in a group: the only normal case is
5403 when the I/O thread was copying a big transaction, then it was
5404 stopped and restarted: we have this in the relay log:
5405
5406 BEGIN
5407 ...
5408 ROTATE (a fake one)
5409 ...
5410 COMMIT or ROLLBACK
5411
5412 In that case, we don't want to touch the coordinates which
5413 correspond to the beginning of the transaction. Starting from
5414 5.0.0, there also are some rotates from the slave itself, in the
5415 relay log, which shall not change the group positions.
5416 */
5417 if ((server_id != ::server_id || rli->replicate_same_server_id) &&
5418 !is_relay_log_event() &&
5419 !rli->is_in_group())
5420 {
5421 mysql_mutex_lock(&rli->data_lock);
5422 DBUG_PRINT("info", ("old group_master_log_name: '%s' "
5423 "old group_master_log_pos: %lu",
5424 rli->group_master_log_name,
5425 (ulong) rli->group_master_log_pos));
5426 memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
5427 rli->notify_group_master_log_name_update();
5428 rli->inc_group_relay_log_pos(pos, TRUE /* skip_lock */);
5429 DBUG_PRINT("info", ("new group_master_log_name: '%s' "
5430 "new group_master_log_pos: %lu",
5431 rli->group_master_log_name,
5432 (ulong) rli->group_master_log_pos));
5433 mysql_mutex_unlock(&rli->data_lock);
5434 flush_relay_log_info(rli);
5435
5436 /*
5437 Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
5438 a master's downgrade from 5.0 to 4.0.
5439 However, no need to reset description_event_for_exec: indeed, if the next
5440 master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
5441 master is 4.0 then the events are in the slave's format (conversion).
5442 */
5443 set_slave_thread_options(thd);
5444 set_slave_thread_default_charset(thd, rli);
5445 thd->variables.sql_mode= global_system_variables.sql_mode;
5446 thd->variables.auto_increment_increment=
5447 thd->variables.auto_increment_offset= 1;
5448 }
5449 else
5450 rli->inc_event_relay_log_pos();
5451
5452
5453 DBUG_RETURN(0);
5454 }
5455
5456
5457 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5458 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
5459 {
5460 enum_skip_reason reason= Log_event::do_shall_skip(rli);
5461
5462 switch (reason) {
5463 case Log_event::EVENT_SKIP_NOT:
5464 case Log_event::EVENT_SKIP_COUNT:
5465 return Log_event::EVENT_SKIP_NOT;
5466
5467 case Log_event::EVENT_SKIP_IGNORE:
5468 return Log_event::EVENT_SKIP_IGNORE;
5469 }
5470 DBUG_ASSERT(0);
5471 return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
5472 }
5473
5474 #endif
5475
5476
5477 /**************************************************************************
5478 Intvar_log_event methods
5479 **************************************************************************/
5480
5481 /*
5482 Intvar_log_event::pack_info()
5483 */
5484
5485 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5486 void Intvar_log_event::pack_info(Protocol *protocol)
5487 {
5488 char buf[256], *pos;
5489 pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
5490 *pos++= '=';
5491 pos= longlong10_to_str(val, pos, -10);
5492 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5493 }
5494 #endif
5495
5496
5497 /*
5498 Intvar_log_event::Intvar_log_event()
5499 */
5500
Intvar_log_event(const char * buf,const Format_description_log_event * description_event)5501 Intvar_log_event::Intvar_log_event(const char* buf,
5502 const Format_description_log_event* description_event)
5503 :Log_event(buf, description_event)
5504 {
5505 /* The Post-Header is empty. The Varible Data part begins immediately. */
5506 buf+= description_event->common_header_len +
5507 description_event->post_header_len[INTVAR_EVENT-1];
5508 type= buf[I_TYPE_OFFSET];
5509 val= uint8korr(buf+I_VAL_OFFSET);
5510 }
5511
5512
5513 /*
5514 Intvar_log_event::get_var_type_name()
5515 */
5516
get_var_type_name()5517 const char* Intvar_log_event::get_var_type_name()
5518 {
5519 switch(type) {
5520 case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
5521 case INSERT_ID_EVENT: return "INSERT_ID";
5522 default: /* impossible */ return "UNKNOWN";
5523 }
5524 }
5525
5526
5527 /*
5528 Intvar_log_event::write()
5529 */
5530
5531 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5532 bool Intvar_log_event::write(IO_CACHE* file)
5533 {
5534 uchar buf[9];
5535 buf[I_TYPE_OFFSET]= (uchar) type;
5536 int8store(buf + I_VAL_OFFSET, val);
5537 return (write_header(file, sizeof(buf)) ||
5538 my_b_safe_write(file, buf, sizeof(buf)));
5539 }
5540 #endif
5541
5542
5543 /*
5544 Intvar_log_event::print()
5545 */
5546
5547 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5548 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5549 {
5550 char llbuff[22];
5551 const char *msg;
5552 LINT_INIT(msg);
5553 Write_on_release_cache cache(&print_event_info->head_cache, file,
5554 Write_on_release_cache::FLUSH_F);
5555
5556 if (!print_event_info->short_form)
5557 {
5558 print_header(&cache, print_event_info, FALSE);
5559 my_b_printf(&cache, "\tIntvar\n");
5560 }
5561
5562 my_b_printf(&cache, "SET ");
5563 switch (type) {
5564 case LAST_INSERT_ID_EVENT:
5565 msg="LAST_INSERT_ID";
5566 break;
5567 case INSERT_ID_EVENT:
5568 msg="INSERT_ID";
5569 break;
5570 case INVALID_INT_EVENT:
5571 default: // cannot happen
5572 msg="INVALID_INT";
5573 break;
5574 }
5575 my_b_printf(&cache, "%s=%s%s\n",
5576 msg, llstr(val,llbuff), print_event_info->delimiter);
5577 }
5578 #endif
5579
5580
5581 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
5582
5583 /*
5584 Intvar_log_event::do_apply_event()
5585 */
5586
do_apply_event(Relay_log_info const * rli)5587 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
5588 {
5589 /*
5590 We are now in a statement until the associated query log event has
5591 been processed.
5592 */
5593 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
5594
5595 if (rli->deferred_events_collecting)
5596 return rli->deferred_events->add(this);
5597
5598 switch (type) {
5599 case LAST_INSERT_ID_EVENT:
5600 thd->first_successful_insert_id_in_prev_stmt= val;
5601 break;
5602 case INSERT_ID_EVENT:
5603 thd->force_one_auto_inc_interval(val);
5604 break;
5605 }
5606 return 0;
5607 }
5608
do_update_pos(Relay_log_info * rli)5609 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
5610 {
5611 rli->inc_event_relay_log_pos();
5612 return 0;
5613 }
5614
5615
5616 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5617 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
5618 {
5619 /*
5620 It is a common error to set the slave skip counter to 1 instead of
5621 2 when recovering from an insert which used a auto increment,
5622 rand, or user var. Therefore, if the slave skip counter is 1, we
5623 just say that this event should be skipped by ignoring it, meaning
5624 that we do not change the value of the slave skip counter since it
5625 will be decreased by the following insert event.
5626 */
5627 return continue_group(rli);
5628 }
5629
5630 #endif
5631
5632
5633 /**************************************************************************
5634 Rand_log_event methods
5635 **************************************************************************/
5636
5637 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5638 void Rand_log_event::pack_info(Protocol *protocol)
5639 {
5640 char buf1[256], *pos;
5641 pos= strmov(buf1,"rand_seed1=");
5642 pos= int10_to_str((long) seed1, pos, 10);
5643 pos= strmov(pos, ",rand_seed2=");
5644 pos= int10_to_str((long) seed2, pos, 10);
5645 protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
5646 }
5647 #endif
5648
5649
Rand_log_event(const char * buf,const Format_description_log_event * description_event)5650 Rand_log_event::Rand_log_event(const char* buf,
5651 const Format_description_log_event* description_event)
5652 :Log_event(buf, description_event)
5653 {
5654 /* The Post-Header is empty. The Variable Data part begins immediately. */
5655 buf+= description_event->common_header_len +
5656 description_event->post_header_len[RAND_EVENT-1];
5657 seed1= uint8korr(buf+RAND_SEED1_OFFSET);
5658 seed2= uint8korr(buf+RAND_SEED2_OFFSET);
5659 }
5660
5661
5662 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5663 bool Rand_log_event::write(IO_CACHE* file)
5664 {
5665 uchar buf[16];
5666 int8store(buf + RAND_SEED1_OFFSET, seed1);
5667 int8store(buf + RAND_SEED2_OFFSET, seed2);
5668 return (write_header(file, sizeof(buf)) ||
5669 my_b_safe_write(file, buf, sizeof(buf)));
5670 }
5671 #endif
5672
5673
5674 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5675 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5676 {
5677 Write_on_release_cache cache(&print_event_info->head_cache, file,
5678 Write_on_release_cache::FLUSH_F);
5679
5680 char llbuff[22],llbuff2[22];
5681 if (!print_event_info->short_form)
5682 {
5683 print_header(&cache, print_event_info, FALSE);
5684 my_b_printf(&cache, "\tRand\n");
5685 }
5686 my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
5687 llstr(seed1, llbuff),llstr(seed2, llbuff2),
5688 print_event_info->delimiter);
5689 }
5690 #endif /* MYSQL_CLIENT */
5691
5692
5693 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5694 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
5695 {
5696 /*
5697 We are now in a statement until the associated query log event has
5698 been processed.
5699 */
5700 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
5701
5702 if (rli->deferred_events_collecting)
5703 return rli->deferred_events->add(this);
5704
5705 thd->rand.seed1= (ulong) seed1;
5706 thd->rand.seed2= (ulong) seed2;
5707 return 0;
5708 }
5709
do_update_pos(Relay_log_info * rli)5710 int Rand_log_event::do_update_pos(Relay_log_info *rli)
5711 {
5712 rli->inc_event_relay_log_pos();
5713 return 0;
5714 }
5715
5716
5717 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5718 Rand_log_event::do_shall_skip(Relay_log_info *rli)
5719 {
5720 /*
5721 It is a common error to set the slave skip counter to 1 instead of
5722 2 when recovering from an insert which used a auto increment,
5723 rand, or user var. Therefore, if the slave skip counter is 1, we
5724 just say that this event should be skipped by ignoring it, meaning
5725 that we do not change the value of the slave skip counter since it
5726 will be decreased by the following insert event.
5727 */
5728 return continue_group(rli);
5729 }
5730
5731 /**
5732 Exec deferred Int-, Rand- and User- var events prefixing
5733 a Query-log-event event.
5734
5735 @param thd THD handle
5736
5737 @return false on success, true if a failure in an event applying occurred.
5738 */
slave_execute_deferred_events(THD * thd)5739 bool slave_execute_deferred_events(THD *thd)
5740 {
5741 bool res= false;
5742 Relay_log_info *rli= thd->rli_slave;
5743
5744 DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
5745
5746 if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
5747 return res;
5748
5749 res= rli->deferred_events->execute(rli);
5750
5751 return res;
5752 }
5753
5754 #endif /* !MYSQL_CLIENT */
5755
5756
5757 /**************************************************************************
5758 Xid_log_event methods
5759 **************************************************************************/
5760
5761 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5762 void Xid_log_event::pack_info(Protocol *protocol)
5763 {
5764 char buf[128], *pos;
5765 pos= strmov(buf, "COMMIT /* xid=");
5766 pos= longlong10_to_str(xid, pos, 10);
5767 pos= strmov(pos, " */");
5768 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5769 }
5770 #endif
5771
5772 /**
5773 @note
5774 It's ok not to use int8store here,
5775 as long as xid_t::set(ulonglong) and
5776 xid_t::get_my_xid doesn't do it either.
5777 We don't care about actual values of xids as long as
5778 identical numbers compare identically
5779 */
5780
5781 Xid_log_event::
Xid_log_event(const char * buf,const Format_description_log_event * description_event)5782 Xid_log_event(const char* buf,
5783 const Format_description_log_event *description_event)
5784 :Log_event(buf, description_event)
5785 {
5786 /* The Post-Header is empty. The Variable Data part begins immediately. */
5787 buf+= description_event->common_header_len +
5788 description_event->post_header_len[XID_EVENT-1];
5789 memcpy((char*) &xid, buf, sizeof(xid));
5790 }
5791
5792
5793 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5794 bool Xid_log_event::write(IO_CACHE* file)
5795 {
5796 DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
5797 return write_header(file, sizeof(xid)) ||
5798 my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
5799 }
5800 #endif
5801
5802
5803 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5804 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5805 {
5806 Write_on_release_cache cache(&print_event_info->head_cache, file,
5807 Write_on_release_cache::FLUSH_F);
5808
5809 if (!print_event_info->short_form)
5810 {
5811 char buf[64];
5812 longlong10_to_str(xid, buf, 10);
5813
5814 print_header(&cache, print_event_info, FALSE);
5815 my_b_printf(&cache, "\tXid = %s\n", buf);
5816 }
5817 my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
5818 }
5819 #endif /* MYSQL_CLIENT */
5820
5821
5822 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5823 int Xid_log_event::do_apply_event(Relay_log_info const *rli)
5824 {
5825 bool res;
5826 /* For a slave Xid_log_event is COMMIT */
5827 general_log_print(thd, COM_QUERY,
5828 "COMMIT /* implicit, from Xid_log_event */");
5829 res= trans_commit(thd); /* Automatically rolls back on error. */
5830 thd->mdl_context.release_transactional_locks();
5831
5832 /*
5833 Increment the global status commit count variable
5834 */
5835 status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
5836
5837 return res;
5838 }
5839
5840 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5841 Xid_log_event::do_shall_skip(Relay_log_info *rli)
5842 {
5843 DBUG_ENTER("Xid_log_event::do_shall_skip");
5844 if (rli->slave_skip_counter > 0) {
5845 thd->variables.option_bits&= ~OPTION_BEGIN;
5846 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5847 }
5848 DBUG_RETURN(Log_event::do_shall_skip(rli));
5849 }
5850 #endif /* !MYSQL_CLIENT */
5851
5852
5853 /**************************************************************************
5854 User_var_log_event methods
5855 **************************************************************************/
5856
5857 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5858 void User_var_log_event::pack_info(Protocol* protocol)
5859 {
5860 char *buf= 0;
5861 char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
5862 int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, 0);
5863 quoted_id[id_len]= '\0';
5864 uint val_offset= 2 + id_len;
5865 uint event_len= val_offset;
5866
5867 if (is_null)
5868 {
5869 if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
5870 return;
5871 strmov(buf + val_offset, "NULL");
5872 event_len= val_offset + 4;
5873 }
5874 else
5875 {
5876 switch (type) {
5877 case REAL_RESULT:
5878 double real_val;
5879 float8get(real_val, val);
5880 if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
5881 MYF(MY_WME))))
5882 return;
5883 event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
5884 buf + val_offset, NULL);
5885 break;
5886 case INT_RESULT:
5887 if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
5888 return;
5889 event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
5890 ((flags & User_var_log_event::UNSIGNED_F) ?
5891 10 : -10))-buf;
5892 break;
5893 case DECIMAL_RESULT:
5894 {
5895 if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
5896 MYF(MY_WME))))
5897 return;
5898 String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
5899 my_decimal dec;
5900 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
5901 val[1]);
5902 my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
5903 event_len= str.length() + val_offset;
5904 break;
5905 }
5906 case STRING_RESULT:
5907 /* 15 is for 'COLLATE' and other chars */
5908 buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
5909 MYF(MY_WME));
5910 CHARSET_INFO *cs;
5911 if (!buf)
5912 return;
5913 if (!(cs= get_charset(charset_number, MYF(0))))
5914 {
5915 strmov(buf+val_offset, "???");
5916 event_len+= 3;
5917 }
5918 else
5919 {
5920 char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
5921 p= str_to_hex(p, val, val_len);
5922 p= strxmov(p, " COLLATE ", cs->name, NullS);
5923 event_len= p-buf;
5924 }
5925 break;
5926 case ROW_RESULT:
5927 default:
5928 DBUG_ASSERT(1);
5929 return;
5930 }
5931 }
5932 buf[0]= '@';
5933 memcpy(buf + 1, quoted_id, id_len);
5934 buf[1 + id_len]= '=';
5935 protocol->store(buf, event_len, &my_charset_bin);
5936 my_free(buf);
5937 }
5938 #endif /* !MYSQL_CLIENT */
5939
5940
5941 User_var_log_event::
User_var_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5942 User_var_log_event(const char* buf, uint event_len,
5943 const Format_description_log_event* description_event)
5944 :Log_event(buf, description_event)
5945 #ifndef MYSQL_CLIENT
5946 , deferred(false), query_id(0)
5947 #endif
5948 {
5949 bool error= false;
5950 const char* buf_start= buf;
5951 /* The Post-Header is empty. The Variable Data part begins immediately. */
5952 const char *start= buf;
5953 buf+= description_event->common_header_len +
5954 description_event->post_header_len[USER_VAR_EVENT-1];
5955 name_len= uint4korr(buf);
5956 /* Avoid reading out of buffer */
5957 if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
5958 {
5959 error= true;
5960 goto err;
5961 }
5962
5963 name= (char *) buf + UV_NAME_LEN_SIZE;
5964
5965 /*
5966 We don't know yet is_null value, so we must assume that name_len
5967 may have the bigger value possible, is_null= True and there is no
5968 payload for val, or even that name_len is 0.
5969 */
5970 if (!valid_buffer_range<uint>(name_len, buf_start, name,
5971 event_len - UV_VAL_IS_NULL))
5972 {
5973 error= true;
5974 goto err;
5975 }
5976
5977 buf+= UV_NAME_LEN_SIZE + name_len;
5978 is_null= (bool) *buf;
5979 flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
5980 if (is_null)
5981 {
5982 type= STRING_RESULT;
5983 charset_number= my_charset_bin.number;
5984 val_len= 0;
5985 val= 0;
5986 }
5987 else
5988 {
5989 if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
5990 + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
5991 buf_start, buf, event_len))
5992 {
5993 error= true;
5994 goto err;
5995 }
5996
5997 type= (Item_result) buf[UV_VAL_IS_NULL];
5998 charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
5999 val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
6000 UV_CHARSET_NUMBER_SIZE);
6001 val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
6002 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
6003
6004 if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
6005 {
6006 error= true;
6007 goto err;
6008 }
6009
6010 /**
6011 We need to check if this is from an old server
6012 that did not pack information for flags.
6013 We do this by checking if there are extra bytes
6014 after the packed value. If there are we take the
6015 extra byte and it's value is assumed to contain
6016 the flags value.
6017
6018 Old events will not have this extra byte, thence,
6019 we keep the flags set to UNDEF_F.
6020 */
6021 uint bytes_read= ((val + val_len) - start);
6022 if (bytes_read > event_len)
6023 {
6024 error= true;
6025 goto err;
6026 }
6027 if ((data_written - bytes_read) > 0)
6028 {
6029 flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
6030 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
6031 val_len);
6032 }
6033 }
6034
6035 err:
6036 if (error)
6037 name= 0;
6038 }
6039
6040
6041 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6042 bool User_var_log_event::write(IO_CACHE* file)
6043 {
6044 char buf[UV_NAME_LEN_SIZE];
6045 char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
6046 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
6047 uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
6048 uint unsigned_len= 0;
6049 uint buf1_length;
6050 ulong event_length;
6051
6052 int4store(buf, name_len);
6053
6054 if ((buf1[0]= is_null))
6055 {
6056 buf1_length= 1;
6057 val_len= 0; // Length of 'pos'
6058 }
6059 else
6060 {
6061 buf1[1]= type;
6062 int4store(buf1 + 2, charset_number);
6063
6064 switch (type) {
6065 case REAL_RESULT:
6066 float8store(buf2, *(double*) val);
6067 break;
6068 case INT_RESULT:
6069 int8store(buf2, *(longlong*) val);
6070 unsigned_len= 1;
6071 break;
6072 case DECIMAL_RESULT:
6073 {
6074 my_decimal *dec= (my_decimal *)val;
6075 dec->fix_buffer_pointer();
6076 buf2[0]= (char)(dec->intg + dec->frac);
6077 buf2[1]= (char)dec->frac;
6078 decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
6079 val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
6080 break;
6081 }
6082 case STRING_RESULT:
6083 pos= (uchar*) val;
6084 break;
6085 case ROW_RESULT:
6086 default:
6087 DBUG_ASSERT(1);
6088 return 0;
6089 }
6090 int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
6091 buf1_length= 10;
6092 }
6093
6094 /* Length of the whole event */
6095 event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
6096
6097 return (write_header(file, event_length) ||
6098 my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
6099 my_b_safe_write(file, (uchar*) name, name_len) ||
6100 my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
6101 my_b_safe_write(file, pos, val_len) ||
6102 my_b_safe_write(file, &flags, unsigned_len));
6103 }
6104 #endif
6105
6106
6107 /*
6108 User_var_log_event::print()
6109 */
6110
6111 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6112 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6113 {
6114 char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
6115 int quoted_len= 0;
6116 Write_on_release_cache cache(&print_event_info->head_cache, file,
6117 Write_on_release_cache::FLUSH_F);
6118
6119 if (!print_event_info->short_form)
6120 {
6121 print_header(&cache, print_event_info, FALSE);
6122 my_b_printf(&cache, "\tUser_var\n");
6123 }
6124
6125 my_b_printf(&cache, "SET @");
6126 quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
6127 (const char *) name);
6128 quoted_id[quoted_len]= '\0';
6129 my_b_write(&cache, (uchar*) quoted_id, (uint) quoted_len);
6130
6131 if (is_null)
6132 {
6133 my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
6134 }
6135 else
6136 {
6137 switch (type) {
6138 case REAL_RESULT:
6139 double real_val;
6140 char real_buf[FMT_G_BUFSIZE(14)];
6141 float8get(real_val, val);
6142 sprintf(real_buf, "%.14g", real_val);
6143 my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
6144 break;
6145 case INT_RESULT:
6146 char int_buf[22];
6147 longlong10_to_str(uint8korr(val), int_buf,
6148 ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
6149 my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
6150 break;
6151 case DECIMAL_RESULT:
6152 {
6153 char str_buf[200];
6154 int str_len= sizeof(str_buf) - 1;
6155 int precision= (int)val[0];
6156 int scale= (int)val[1];
6157 decimal_digit_t dec_buf[10];
6158 decimal_t dec;
6159 dec.len= 10;
6160 dec.buf= dec_buf;
6161
6162 bin2decimal((uchar*) val+2, &dec, precision, scale);
6163 decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
6164 str_buf[str_len]= 0;
6165 my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
6166 break;
6167 }
6168 case STRING_RESULT:
6169 {
6170 /*
6171 Let's express the string in hex. That's the most robust way. If we
6172 print it in character form instead, we need to escape it with
6173 character_set_client which we don't know (we will know it in 5.0, but
6174 in 4.1 we don't know it easily when we are printing
6175 User_var_log_event). Explanation why we would need to bother with
6176 character_set_client (quoting Bar):
6177 > Note, the parser doesn't switch to another unescaping mode after
6178 > it has met a character set introducer.
6179 > For example, if an SJIS client says something like:
6180 > SET @a= _ucs2 \0a\0b'
6181 > the string constant is still unescaped according to SJIS, not
6182 > according to UCS2.
6183 */
6184 char *hex_str;
6185 CHARSET_INFO *cs;
6186
6187 hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
6188 if (!hex_str)
6189 return;
6190 str_to_hex(hex_str, val, val_len);
6191 /*
6192 For proper behaviour when mysqlbinlog|mysql, we need to explicitely
6193 specify the variable's collation. It will however cause problems when
6194 people want to mysqlbinlog|mysql into another server not supporting the
6195 character set. But there's not much to do about this and it's unlikely.
6196 */
6197 if (!(cs= get_charset(charset_number, MYF(0))))
6198 /*
6199 Generate an unusable command (=> syntax error) is probably the best
6200 thing we can do here.
6201 */
6202 my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
6203 else
6204 my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
6205 cs->csname, hex_str, cs->name,
6206 print_event_info->delimiter);
6207 my_free(hex_str);
6208 }
6209 break;
6210 case ROW_RESULT:
6211 default:
6212 DBUG_ASSERT(1);
6213 return;
6214 }
6215 }
6216 }
6217 #endif
6218
6219
6220 /*
6221 User_var_log_event::do_apply_event()
6222 */
6223
6224 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)6225 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
6226 {
6227 Item *it= 0;
6228 CHARSET_INFO *charset;
6229 query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
6230
6231 if (rli->deferred_events_collecting)
6232 {
6233 set_deferred(current_thd->query_id);
6234 return rli->deferred_events->add(this);
6235 } else if (is_deferred())
6236 {
6237 sav_query_id= current_thd->query_id;
6238 current_thd->query_id= query_id; /* recreating original time context */
6239 }
6240
6241 if (!(charset= get_charset(charset_number, MYF(MY_WME))))
6242 {
6243 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6244 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
6245 "Invalid character set for User var event");
6246 return 1;
6247 }
6248 LEX_STRING user_var_name;
6249 user_var_name.str= name;
6250 user_var_name.length= name_len;
6251 double real_val;
6252 longlong int_val;
6253
6254 /*
6255 We are now in a statement until the associated query log event has
6256 been processed.
6257 */
6258 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
6259
6260 if (is_null)
6261 {
6262 it= new Item_null();
6263 }
6264 else
6265 {
6266 switch (type) {
6267 case REAL_RESULT:
6268 if (val_len != 8)
6269 {
6270 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6271 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
6272 "Invalid variable length at User var event");
6273 return 1;
6274 }
6275 float8get(real_val, val);
6276 it= new Item_float(real_val, 0);
6277 val= (char*) &real_val; // Pointer to value in native format
6278 val_len= 8;
6279 break;
6280 case INT_RESULT:
6281 if (val_len != 8)
6282 {
6283 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6284 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
6285 "Invalid variable length at User var event");
6286 return 1;
6287 }
6288 int_val= (longlong) uint8korr(val);
6289 it= new Item_int(int_val);
6290 val= (char*) &int_val; // Pointer to value in native format
6291 val_len= 8;
6292 break;
6293 case DECIMAL_RESULT:
6294 {
6295 if (val_len < 3)
6296 {
6297 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6298 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
6299 "Invalid variable length at User var event");
6300 return 1;
6301 }
6302 Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
6303 it= dec;
6304 val= (char *)dec->val_decimal(NULL);
6305 val_len= sizeof(my_decimal);
6306 break;
6307 }
6308 case STRING_RESULT:
6309 it= new Item_string(val, val_len, charset);
6310 break;
6311 case ROW_RESULT:
6312 default:
6313 DBUG_ASSERT(1);
6314 return 0;
6315 }
6316 }
6317
6318 Item_func_set_user_var *e=
6319 new Item_func_set_user_var(user_var_name, it, false);
6320 /*
6321 Item_func_set_user_var can't substitute something else on its place =>
6322 0 can be passed as last argument (reference on item)
6323
6324 Fix_fields() can fail, in which case a call of update_hash() might
6325 crash the server, so if fix fields fails, we just return with an
6326 error.
6327 */
6328 if (e->fix_fields(thd, 0))
6329 return 1;
6330
6331 /*
6332 A variable can just be considered as a table with
6333 a single record and with a single column. Thus, like
6334 a column value, it could always have IMPLICIT derivation.
6335 */
6336 e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
6337 (flags & User_var_log_event::UNSIGNED_F));
6338 if (!is_deferred())
6339 free_root(thd->mem_root, 0);
6340 else
6341 current_thd->query_id= sav_query_id; /* restore current query's context */
6342
6343 return 0;
6344 }
6345
do_update_pos(Relay_log_info * rli)6346 int User_var_log_event::do_update_pos(Relay_log_info *rli)
6347 {
6348 rli->inc_event_relay_log_pos();
6349 return 0;
6350 }
6351
6352 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)6353 User_var_log_event::do_shall_skip(Relay_log_info *rli)
6354 {
6355 /*
6356 It is a common error to set the slave skip counter to 1 instead
6357 of 2 when recovering from an insert which used a auto increment,
6358 rand, or user var. Therefore, if the slave skip counter is 1, we
6359 just say that this event should be skipped by ignoring it, meaning
6360 that we do not change the value of the slave skip counter since it
6361 will be decreased by the following insert event.
6362 */
6363 return continue_group(rli);
6364 }
6365 #endif /* !MYSQL_CLIENT */
6366
6367
6368 /**************************************************************************
6369 Slave_log_event methods
6370 **************************************************************************/
6371
6372 #ifdef HAVE_REPLICATION
6373 #ifdef MYSQL_CLIENT
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info)6374 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
6375 {
6376 Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
6377
6378 if (print_event_info->short_form)
6379 return;
6380 print_header(&cache, print_event_info, FALSE);
6381 my_b_printf(&cache, "\n# %s", "Unknown event\n");
6382 }
6383 #endif
6384
6385 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)6386 void Slave_log_event::pack_info(Protocol *protocol)
6387 {
6388 char buf[256+HOSTNAME_LENGTH], *pos;
6389 pos= strmov(buf, "host=");
6390 pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
6391 pos= strmov(pos, ",port=");
6392 pos= int10_to_str((long) master_port, pos, 10);
6393 pos= strmov(pos, ",log=");
6394 pos= strmov(pos, master_log);
6395 pos= strmov(pos, ",pos=");
6396 pos= longlong10_to_str(master_pos, pos, 10);
6397 protocol->store(buf, pos-buf, &my_charset_bin);
6398 }
6399 #endif /* !MYSQL_CLIENT */
6400
6401
6402 #ifndef MYSQL_CLIENT
6403 /**
6404 @todo
6405 re-write this better without holding both locks at the same time
6406 */
Slave_log_event(THD * thd_arg,Relay_log_info * rli)6407 Slave_log_event::Slave_log_event(THD* thd_arg,
6408 Relay_log_info* rli)
6409 :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
6410 {
6411 DBUG_ENTER("Slave_log_event");
6412 if (!rli->inited) // QQ When can this happen ?
6413 DBUG_VOID_RETURN;
6414
6415 Master_info* mi = rli->mi;
6416 // TODO: re-write this better without holding both locks at the same time
6417 mysql_mutex_lock(&mi->data_lock);
6418 mysql_mutex_lock(&rli->data_lock);
6419 master_host_len = strlen(mi->host);
6420 master_log_len = strlen(rli->group_master_log_name);
6421 // on OOM, just do not initialize the structure and print the error
6422 if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
6423 MYF(MY_WME))))
6424 {
6425 master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
6426 memcpy(master_host, mi->host, master_host_len + 1);
6427 master_log = master_host + master_host_len + 1;
6428 memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
6429 master_port = mi->port;
6430 master_pos = rli->group_master_log_pos;
6431 DBUG_PRINT("info", ("master_log: %s pos: %lu", master_log,
6432 (ulong) master_pos));
6433 }
6434 else
6435 sql_print_error("Out of memory while recording slave event");
6436 mysql_mutex_unlock(&rli->data_lock);
6437 mysql_mutex_unlock(&mi->data_lock);
6438 DBUG_VOID_RETURN;
6439 }
6440 #endif /* !MYSQL_CLIENT */
6441
6442
~Slave_log_event()6443 Slave_log_event::~Slave_log_event()
6444 {
6445 my_free(mem_pool);
6446 }
6447
6448
6449 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6450 void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6451 {
6452 Write_on_release_cache cache(&print_event_info->head_cache, file);
6453
6454 char llbuff[22];
6455 if (print_event_info->short_form)
6456 return;
6457 print_header(&cache, print_event_info, FALSE);
6458 my_b_printf(&cache, "\n\
6459 Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n",
6460 master_host, master_port, master_log, llstr(master_pos, llbuff));
6461 }
6462 #endif /* MYSQL_CLIENT */
6463
6464
get_data_size()6465 int Slave_log_event::get_data_size()
6466 {
6467 return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
6468 }
6469
6470
6471 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6472 bool Slave_log_event::write(IO_CACHE* file)
6473 {
6474 ulong event_length= get_data_size();
6475 int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
6476 int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
6477 // log and host are already there
6478
6479 return (write_header(file, event_length) ||
6480 my_b_safe_write(file, (uchar*) mem_pool, event_length));
6481 }
6482 #endif
6483
6484
init_from_mem_pool(int data_size)6485 void Slave_log_event::init_from_mem_pool(int data_size)
6486 {
6487 master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
6488 master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
6489 master_host = mem_pool + SL_MASTER_HOST_OFFSET;
6490 master_host_len = (uint) strlen(master_host);
6491 // safety
6492 master_log = master_host + master_host_len + 1;
6493 if (master_log > mem_pool + data_size)
6494 {
6495 master_host = 0;
6496 return;
6497 }
6498 master_log_len = (uint) strlen(master_log);
6499 }
6500
6501
6502 /** This code is not used, so has not been updated to be format-tolerant. */
6503 /* We are using description_event so that slave does not crash on Log_event
6504 constructor */
Slave_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6505 Slave_log_event::Slave_log_event(const char* buf,
6506 uint event_len,
6507 const Format_description_log_event* description_event)
6508 :Log_event(buf,description_event),mem_pool(0),master_host(0)
6509 {
6510 if (event_len < LOG_EVENT_HEADER_LEN)
6511 return;
6512 event_len -= LOG_EVENT_HEADER_LEN;
6513 if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
6514 return;
6515 memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
6516 mem_pool[event_len] = 0;
6517 init_from_mem_pool(event_len);
6518 }
6519
6520
6521 #ifndef MYSQL_CLIENT
do_apply_event(Relay_log_info const * rli)6522 int Slave_log_event::do_apply_event(Relay_log_info const *rli)
6523 {
6524 if (mysql_bin_log.is_open())
6525 return mysql_bin_log.write(this);
6526 return 0;
6527 }
6528 #endif /* !MYSQL_CLIENT */
6529
6530
6531 /**************************************************************************
6532 Stop_log_event methods
6533 **************************************************************************/
6534
6535 /*
6536 Stop_log_event::print()
6537 */
6538
6539 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6540 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6541 {
6542 Write_on_release_cache cache(&print_event_info->head_cache, file,
6543 Write_on_release_cache::FLUSH_F);
6544
6545 if (print_event_info->short_form)
6546 return;
6547
6548 print_header(&cache, print_event_info, FALSE);
6549 my_b_printf(&cache, "\tStop\n");
6550 }
6551 #endif /* MYSQL_CLIENT */
6552
6553
6554 #ifndef MYSQL_CLIENT
6555 /*
6556 The master stopped. We used to clean up all temporary tables but
6557 this is useless as, as the master has shut down properly, it has
6558 written all DROP TEMPORARY TABLE (prepared statements' deletion is
6559 TODO only when we binlog prep stmts). We used to clean up
6560 slave_load_tmpdir, but this is useless as it has been cleared at the
6561 end of LOAD DATA INFILE. So we have nothing to do here. The place
6562 were we must do this cleaning is in
6563 Start_log_event_v3::do_apply_event(), not here. Because if we come
6564 here, the master was sane.
6565 */
do_update_pos(Relay_log_info * rli)6566 int Stop_log_event::do_update_pos(Relay_log_info *rli)
6567 {
6568 /*
6569 We do not want to update master_log pos because we get a rotate event
6570 before stop, so by now group_master_log_name is set to the next log.
6571 If we updated it, we will have incorrect master coordinates and this
6572 could give false triggers in MASTER_POS_WAIT() that we have reached
6573 the target position when in fact we have not.
6574 */
6575 if (thd->variables.option_bits & OPTION_BEGIN)
6576 rli->inc_event_relay_log_pos();
6577 else
6578 {
6579 rli->inc_group_relay_log_pos(0);
6580 flush_relay_log_info(rli);
6581 }
6582 return 0;
6583 }
6584
6585 #endif /* !MYSQL_CLIENT */
6586 #endif /* HAVE_REPLICATION */
6587
6588
6589 /**************************************************************************
6590 Create_file_log_event methods
6591 **************************************************************************/
6592
6593 /*
6594 Create_file_log_event ctor
6595 */
6596
6597 #ifndef MYSQL_CLIENT
6598 Create_file_log_event::
Create_file_log_event(THD * thd_arg,sql_exchange * ex,const char * db_arg,const char * table_name_arg,List<Item> & fields_arg,bool is_concurrent_arg,enum enum_duplicates handle_dup,bool ignore,uchar * block_arg,uint block_len_arg,bool using_trans)6599 Create_file_log_event(THD* thd_arg, sql_exchange* ex,
6600 const char* db_arg, const char* table_name_arg,
6601 List<Item>& fields_arg,
6602 bool is_concurrent_arg,
6603 enum enum_duplicates handle_dup,
6604 bool ignore,
6605 uchar* block_arg, uint block_len_arg, bool using_trans)
6606 :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
6607 is_concurrent_arg,
6608 handle_dup, ignore, using_trans),
6609 fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
6610 file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
6611 {
6612 DBUG_ENTER("Create_file_log_event");
6613 sql_ex.force_new_format();
6614 DBUG_VOID_RETURN;
6615 }
6616
6617
6618 /*
6619 Create_file_log_event::write_data_body()
6620 */
6621
write_data_body(IO_CACHE * file)6622 bool Create_file_log_event::write_data_body(IO_CACHE* file)
6623 {
6624 bool res;
6625 if ((res= Load_log_event::write_data_body(file)) || fake_base)
6626 return res;
6627 return (my_b_safe_write(file, (uchar*) "", 1) ||
6628 my_b_safe_write(file, (uchar*) block, block_len));
6629 }
6630
6631
6632 /*
6633 Create_file_log_event::write_data_header()
6634 */
6635
write_data_header(IO_CACHE * file)6636 bool Create_file_log_event::write_data_header(IO_CACHE* file)
6637 {
6638 bool res;
6639 uchar buf[CREATE_FILE_HEADER_LEN];
6640 if ((res= Load_log_event::write_data_header(file)) || fake_base)
6641 return res;
6642 int4store(buf + CF_FILE_ID_OFFSET, file_id);
6643 return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
6644 }
6645
6646
6647 /*
6648 Create_file_log_event::write_base()
6649 */
6650
write_base(IO_CACHE * file)6651 bool Create_file_log_event::write_base(IO_CACHE* file)
6652 {
6653 bool res;
6654 fake_base= 1; // pretend we are Load event
6655 res= write(file);
6656 fake_base= 0;
6657 return res;
6658 }
6659
6660 #endif /* !MYSQL_CLIENT */
6661
6662 /*
6663 Create_file_log_event ctor
6664 */
6665
Create_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)6666 Create_file_log_event::Create_file_log_event(const char* buf, uint len,
6667 const Format_description_log_event* description_event)
6668 :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
6669 {
6670 DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
6671 uint block_offset;
6672 uint header_len= description_event->common_header_len;
6673 uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
6674 uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
6675 if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
6676 copy_log_event(event_buf,len,
6677 ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
6678 load_header_len + header_len :
6679 (fake_base ? (header_len+load_header_len) :
6680 (header_len+load_header_len) +
6681 create_file_header_len)),
6682 description_event))
6683 DBUG_VOID_RETURN;
6684 if (description_event->binlog_version!=1)
6685 {
6686 file_id= uint4korr(buf +
6687 header_len +
6688 load_header_len + CF_FILE_ID_OFFSET);
6689 /*
6690 Note that it's ok to use get_data_size() below, because it is computed
6691 with values we have already read from this event (because we called
6692 copy_log_event()); we are not using slave's format info to decode
6693 master's format, we are really using master's format info.
6694 Anyway, both formats should be identical (except the common_header_len)
6695 as these Load events are not changed between 4.0 and 5.0 (as logging of
6696 LOAD DATA INFILE does not use Load_log_event in 5.0).
6697
6698 The + 1 is for \0 terminating fname
6699 */
6700 block_offset= (description_event->common_header_len +
6701 Load_log_event::get_data_size() +
6702 create_file_header_len + 1);
6703 if (len < block_offset)
6704 DBUG_VOID_RETURN;
6705 block = (uchar*)buf + block_offset;
6706 block_len = len - block_offset;
6707 }
6708 else
6709 {
6710 sql_ex.force_new_format();
6711 inited_from_old = 1;
6712 }
6713 DBUG_VOID_RETURN;
6714 }
6715
6716
6717 /*
6718 Create_file_log_event::print()
6719 */
6720
6721 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info,bool enable_local)6722 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
6723 bool enable_local)
6724 {
6725 Write_on_release_cache cache(&print_event_info->head_cache, file);
6726
6727 if (print_event_info->short_form)
6728 {
6729 if (enable_local && check_fname_outside_temp_buf())
6730 Load_log_event::print(file, print_event_info);
6731 return;
6732 }
6733
6734 if (enable_local)
6735 {
6736 Load_log_event::print(file, print_event_info,
6737 !check_fname_outside_temp_buf());
6738 /**
6739 reduce the size of io cache so that the write function is called
6740 for every call to my_b_printf().
6741 */
6742 DBUG_EXECUTE_IF ("simulate_create_event_write_error",
6743 {(&cache)->write_pos= (&cache)->write_end;
6744 DBUG_SET("+d,simulate_file_write_error");});
6745 /*
6746 That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
6747 SHOW BINLOG EVENTS we don't.
6748 */
6749 my_b_printf(&cache, "#");
6750 }
6751
6752 my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len);
6753 }
6754
6755
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6756 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6757 {
6758 print(file, print_event_info, 0);
6759 }
6760 #endif /* MYSQL_CLIENT */
6761
6762
6763 /*
6764 Create_file_log_event::pack_info()
6765 */
6766
6767 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6768 void Create_file_log_event::pack_info(Protocol *protocol)
6769 {
6770 char buf[NAME_LEN*2 + 30 + 21*2], *pos;
6771 pos= strmov(buf, "db=");
6772 memcpy(pos, db, db_len);
6773 pos= strmov(pos + db_len, ";table=");
6774 memcpy(pos, table_name, table_name_len);
6775 pos= strmov(pos + table_name_len, ";file_id=");
6776 pos= int10_to_str((long) file_id, pos, 10);
6777 pos= strmov(pos, ";block_len=");
6778 pos= int10_to_str((long) block_len, pos, 10);
6779 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
6780 }
6781 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6782
6783
6784 /**
6785 Create_file_log_event::do_apply_event()
6786 Constructor for Create_file_log_event to intantiate an event
6787 from the relay log on the slave.
6788
6789 @retval
6790 0 Success
6791 @retval
6792 1 Failure
6793 */
6794
6795 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)6796 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
6797 {
6798 char proc_info[17+FN_REFLEN+10], *fname_buf;
6799 char *ext;
6800 int fd = -1;
6801 IO_CACHE file;
6802 int error = 1;
6803
6804 bzero((char*)&file, sizeof(file));
6805 fname_buf= strmov(proc_info, "Making temp file ");
6806 ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
6807 thd_proc_info(thd, proc_info);
6808 /* old copy may exist already */
6809 mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
6810 if ((fd= mysql_file_create(key_file_log_event_info,
6811 fname_buf, CREATE_MODE,
6812 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
6813 MYF(MY_WME))) < 0 ||
6814 init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
6815 MYF(MY_WME|MY_NABP)))
6816 {
6817 rli->report(ERROR_LEVEL, my_errno,
6818 "Error in Create_file event: could not open file '%s'",
6819 fname_buf);
6820 goto err;
6821 }
6822
6823 // a trick to avoid allocating another buffer
6824 fname= fname_buf;
6825 fname_len= (uint) (strmov(ext, ".data") - fname);
6826 if (write_base(&file))
6827 {
6828 strmov(ext, ".info"); // to have it right in the error message
6829 rli->report(ERROR_LEVEL, my_errno,
6830 "Error in Create_file event: could not write to file '%s'",
6831 fname_buf);
6832 goto err;
6833 }
6834 end_io_cache(&file);
6835 mysql_file_close(fd, MYF(0));
6836
6837 // fname_buf now already has .data, not .info, because we did our trick
6838 /* old copy may exist already */
6839 mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
6840 if ((fd= mysql_file_create(key_file_log_event_data,
6841 fname_buf, CREATE_MODE,
6842 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
6843 MYF(MY_WME))) < 0)
6844 {
6845 rli->report(ERROR_LEVEL, my_errno,
6846 "Error in Create_file event: could not open file '%s'",
6847 fname_buf);
6848 goto err;
6849 }
6850 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
6851 {
6852 rli->report(ERROR_LEVEL, my_errno,
6853 "Error in Create_file event: write to '%s' failed",
6854 fname_buf);
6855 goto err;
6856 }
6857 error=0; // Everything is ok
6858
6859 err:
6860 if (error)
6861 end_io_cache(&file);
6862 if (fd >= 0)
6863 mysql_file_close(fd, MYF(0));
6864 thd_proc_info(thd, 0);
6865 return error != 0;
6866 }
6867 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6868
6869
6870 /**************************************************************************
6871 Append_block_log_event methods
6872 **************************************************************************/
6873
6874 /*
6875 Append_block_log_event ctor
6876 */
6877
6878 #ifndef MYSQL_CLIENT
Append_block_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)6879 Append_block_log_event::Append_block_log_event(THD *thd_arg,
6880 const char *db_arg,
6881 uchar *block_arg,
6882 uint block_len_arg,
6883 bool using_trans)
6884 :Log_event(thd_arg,0, using_trans), block(block_arg),
6885 block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
6886 {
6887 }
6888 #endif
6889
6890
6891 /*
6892 Append_block_log_event ctor
6893 */
6894
Append_block_log_event(const char * buf,uint len,const Format_description_log_event * description_event)6895 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
6896 const Format_description_log_event* description_event)
6897 :Log_event(buf, description_event),block(0)
6898 {
6899 DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
6900 uint8 common_header_len= description_event->common_header_len;
6901 uint8 append_block_header_len=
6902 description_event->post_header_len[APPEND_BLOCK_EVENT-1];
6903 uint total_header_len= common_header_len+append_block_header_len;
6904 if (len < total_header_len)
6905 DBUG_VOID_RETURN;
6906 file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
6907 block= (uchar*)buf + total_header_len;
6908 block_len= len - total_header_len;
6909 DBUG_VOID_RETURN;
6910 }
6911
6912
6913 /*
6914 Append_block_log_event::write()
6915 */
6916
6917 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6918 bool Append_block_log_event::write(IO_CACHE* file)
6919 {
6920 uchar buf[APPEND_BLOCK_HEADER_LEN];
6921 int4store(buf + AB_FILE_ID_OFFSET, file_id);
6922 return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
6923 my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
6924 my_b_safe_write(file, (uchar*) block, block_len));
6925 }
6926 #endif
6927
6928
6929 /*
6930 Append_block_log_event::print()
6931 */
6932
6933 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6934 void Append_block_log_event::print(FILE* file,
6935 PRINT_EVENT_INFO* print_event_info)
6936 {
6937 Write_on_release_cache cache(&print_event_info->head_cache, file);
6938
6939 if (print_event_info->short_form)
6940 return;
6941 print_header(&cache, print_event_info, FALSE);
6942 my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
6943 get_type_str(), file_id, block_len);
6944 }
6945 #endif /* MYSQL_CLIENT */
6946
6947
6948 /*
6949 Append_block_log_event::pack_info()
6950 */
6951
6952 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6953 void Append_block_log_event::pack_info(Protocol *protocol)
6954 {
6955 char buf[256];
6956 size_t length;
6957 length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
6958 file_id, block_len);
6959 protocol->store(buf, length, &my_charset_bin);
6960 }
6961
6962
6963 /*
6964 Append_block_log_event::get_create_or_append()
6965 */
6966
get_create_or_append() const6967 int Append_block_log_event::get_create_or_append() const
6968 {
6969 return 0; /* append to the file, fail if not exists */
6970 }
6971
6972 /*
6973 Append_block_log_event::do_apply_event()
6974 */
6975
do_apply_event(Relay_log_info const * rli)6976 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
6977 {
6978 char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
6979 int fd;
6980 int error = 1;
6981 DBUG_ENTER("Append_block_log_event::do_apply_event");
6982
6983 fname= strmov(proc_info, "Making temp file ");
6984 slave_load_file_stem(fname, file_id, server_id, ".data");
6985 thd_proc_info(thd, proc_info);
6986 if (get_create_or_append())
6987 {
6988 /*
6989 Usually lex_start() is called by mysql_parse(), but we need it here
6990 as the present method does not call mysql_parse().
6991 */
6992 lex_start(thd);
6993 mysql_reset_thd_for_next_command(thd);
6994 /* old copy may exist already */
6995 mysql_file_delete(key_file_log_event_data, fname, MYF(0));
6996 if ((fd= mysql_file_create(key_file_log_event_data,
6997 fname, CREATE_MODE,
6998 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
6999 MYF(MY_WME))) < 0)
7000 {
7001 rli->report(ERROR_LEVEL, my_errno,
7002 "Error in %s event: could not create file '%s'",
7003 get_type_str(), fname);
7004 goto err;
7005 }
7006 }
7007 else if ((fd= mysql_file_open(key_file_log_event_data,
7008 fname,
7009 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
7010 MYF(MY_WME))) < 0)
7011 {
7012 rli->report(ERROR_LEVEL, my_errno,
7013 "Error in %s event: could not open file '%s'",
7014 get_type_str(), fname);
7015 goto err;
7016 }
7017
7018 DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
7019 {
7020 my_delete_allow_opened(fname, MYF(0));
7021 });
7022
7023 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
7024 {
7025 rli->report(ERROR_LEVEL, my_errno,
7026 "Error in %s event: write to '%s' failed",
7027 get_type_str(), fname);
7028 goto err;
7029 }
7030 error=0;
7031
7032 err:
7033 if (fd >= 0)
7034 mysql_file_close(fd, MYF(0));
7035 thd_proc_info(thd, 0);
7036 DBUG_RETURN(error);
7037 }
7038 #endif
7039
7040
7041 /**************************************************************************
7042 Delete_file_log_event methods
7043 **************************************************************************/
7044
7045 /*
7046 Delete_file_log_event ctor
7047 */
7048
7049 #ifndef MYSQL_CLIENT
Delete_file_log_event(THD * thd_arg,const char * db_arg,bool using_trans)7050 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
7051 bool using_trans)
7052 :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
7053 {
7054 }
7055 #endif
7056
7057 /*
7058 Delete_file_log_event ctor
7059 */
7060
Delete_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)7061 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
7062 const Format_description_log_event* description_event)
7063 :Log_event(buf, description_event),file_id(0)
7064 {
7065 uint8 common_header_len= description_event->common_header_len;
7066 uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
7067 if (len < (uint)(common_header_len + delete_file_header_len))
7068 return;
7069 file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
7070 }
7071
7072
7073 /*
7074 Delete_file_log_event::write()
7075 */
7076
7077 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7078 bool Delete_file_log_event::write(IO_CACHE* file)
7079 {
7080 uchar buf[DELETE_FILE_HEADER_LEN];
7081 int4store(buf + DF_FILE_ID_OFFSET, file_id);
7082 return (write_header(file, sizeof(buf)) ||
7083 my_b_safe_write(file, buf, sizeof(buf)));
7084 }
7085 #endif
7086
7087
7088 /*
7089 Delete_file_log_event::print()
7090 */
7091
7092 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7093 void Delete_file_log_event::print(FILE* file,
7094 PRINT_EVENT_INFO* print_event_info)
7095 {
7096 Write_on_release_cache cache(&print_event_info->head_cache, file);
7097
7098 if (print_event_info->short_form)
7099 return;
7100 print_header(&cache, print_event_info, FALSE);
7101 my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
7102 }
7103 #endif /* MYSQL_CLIENT */
7104
7105 /*
7106 Delete_file_log_event::pack_info()
7107 */
7108
7109 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7110 void Delete_file_log_event::pack_info(Protocol *protocol)
7111 {
7112 char buf[64];
7113 size_t length;
7114 length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
7115 protocol->store(buf, length, &my_charset_bin);
7116 }
7117 #endif
7118
7119 /*
7120 Delete_file_log_event::do_apply_event()
7121 */
7122
7123 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)7124 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
7125 {
7126 char fname[FN_REFLEN+10];
7127 char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
7128 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
7129 strmov(ext, ".info");
7130 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
7131 return 0;
7132 }
7133 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
7134
7135
7136 /**************************************************************************
7137 Execute_load_log_event methods
7138 **************************************************************************/
7139
7140 /*
7141 Execute_load_log_event ctor
7142 */
7143
7144 #ifndef MYSQL_CLIENT
Execute_load_log_event(THD * thd_arg,const char * db_arg,bool using_trans)7145 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
7146 const char* db_arg,
7147 bool using_trans)
7148 :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
7149 {
7150 }
7151 #endif
7152
7153
7154 /*
7155 Execute_load_log_event ctor
7156 */
7157
Execute_load_log_event(const char * buf,uint len,const Format_description_log_event * description_event)7158 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
7159 const Format_description_log_event* description_event)
7160 :Log_event(buf, description_event), file_id(0)
7161 {
7162 uint8 common_header_len= description_event->common_header_len;
7163 uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
7164 if (len < (uint)(common_header_len+exec_load_header_len))
7165 return;
7166 file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
7167 }
7168
7169
7170 /*
7171 Execute_load_log_event::write()
7172 */
7173
7174 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7175 bool Execute_load_log_event::write(IO_CACHE* file)
7176 {
7177 uchar buf[EXEC_LOAD_HEADER_LEN];
7178 int4store(buf + EL_FILE_ID_OFFSET, file_id);
7179 return (write_header(file, sizeof(buf)) ||
7180 my_b_safe_write(file, buf, sizeof(buf)));
7181 }
7182 #endif
7183
7184
7185 /*
7186 Execute_load_log_event::print()
7187 */
7188
7189 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7190 void Execute_load_log_event::print(FILE* file,
7191 PRINT_EVENT_INFO* print_event_info)
7192 {
7193 Write_on_release_cache cache(&print_event_info->head_cache, file);
7194
7195 if (print_event_info->short_form)
7196 return;
7197 print_header(&cache, print_event_info, FALSE);
7198 my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
7199 file_id);
7200 }
7201 #endif
7202
7203 /*
7204 Execute_load_log_event::pack_info()
7205 */
7206
7207 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7208 void Execute_load_log_event::pack_info(Protocol *protocol)
7209 {
7210 char buf[64];
7211 size_t length;
7212 length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
7213 protocol->store(buf, length, &my_charset_bin);
7214 }
7215
7216
7217 /*
7218 Execute_load_log_event::do_apply_event()
7219 */
7220
do_apply_event(Relay_log_info const * rli)7221 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
7222 {
7223 char fname[FN_REFLEN+10];
7224 char *ext;
7225 int fd;
7226 int error= 1;
7227 IO_CACHE file;
7228 Load_log_event *lev= 0;
7229
7230 ext= slave_load_file_stem(fname, file_id, server_id, ".info");
7231 if ((fd= mysql_file_open(key_file_log_event_info,
7232 fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
7233 MYF(MY_WME))) < 0 ||
7234 init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
7235 MYF(MY_WME|MY_NABP)))
7236 {
7237 rli->report(ERROR_LEVEL, my_errno,
7238 "Error in Exec_load event: could not open file '%s'",
7239 fname);
7240 goto err;
7241 }
7242 if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
7243 (mysql_mutex_t*)0,
7244 rli->relay_log.description_event_for_exec)) ||
7245 lev->get_type_code() != NEW_LOAD_EVENT)
7246 {
7247 rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
7248 "file '%s' appears corrupted", fname);
7249 goto err;
7250 }
7251
7252 lev->thd = thd;
7253 /*
7254 lev->do_apply_event should use rli only for errors i.e. should
7255 not advance rli's position.
7256
7257 lev->do_apply_event is the place where the table is loaded (it
7258 calls mysql_load()).
7259 */
7260
7261 const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
7262 if (lev->do_apply_event(0,rli,1))
7263 {
7264 /*
7265 We want to indicate the name of the file that could not be loaded
7266 (SQL_LOADxxx).
7267 But as we are here we are sure the error is in rli->last_slave_error and
7268 rli->last_slave_errno (example of error: duplicate entry for key), so we
7269 don't want to overwrite it with the filename.
7270 What we want instead is add the filename to the current error message.
7271 */
7272 char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
7273 if (tmp)
7274 {
7275 rli->report(ERROR_LEVEL, rli->last_error().number,
7276 "%s. Failed executing load from '%s'", tmp, fname);
7277 my_free(tmp);
7278 }
7279 goto err;
7280 }
7281 /*
7282 We have an open file descriptor to the .info file; we need to close it
7283 or Windows will refuse to delete the file in mysql_file_delete().
7284 */
7285 if (fd >= 0)
7286 {
7287 mysql_file_close(fd, MYF(0));
7288 end_io_cache(&file);
7289 fd= -1;
7290 }
7291 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
7292 memcpy(ext, ".data", 6);
7293 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
7294 error = 0;
7295
7296 err:
7297 delete lev;
7298 if (fd >= 0)
7299 {
7300 mysql_file_close(fd, MYF(0));
7301 end_io_cache(&file);
7302 }
7303 return error;
7304 }
7305
7306 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
7307
7308
7309 /**************************************************************************
7310 Begin_load_query_log_event methods
7311 **************************************************************************/
7312
7313 #ifndef MYSQL_CLIENT
7314 Begin_load_query_log_event::
Begin_load_query_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)7315 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
7316 uint block_len_arg, bool using_trans)
7317 :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
7318 using_trans)
7319 {
7320 file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
7321 }
7322 #endif
7323
7324
7325 Begin_load_query_log_event::
Begin_load_query_log_event(const char * buf,uint len,const Format_description_log_event * desc_event)7326 Begin_load_query_log_event(const char* buf, uint len,
7327 const Format_description_log_event* desc_event)
7328 :Append_block_log_event(buf, len, desc_event)
7329 {
7330 }
7331
7332
7333 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_create_or_append() const7334 int Begin_load_query_log_event::get_create_or_append() const
7335 {
7336 return 1; /* create the file */
7337 }
7338 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
7339
7340
7341 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7342 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7343 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
7344 {
7345 /*
7346 If the slave skip counter is 1, then we should not start executing
7347 on the next event.
7348 */
7349 return continue_group(rli);
7350 }
7351 #endif
7352
7353
7354 /**************************************************************************
7355 Execute_load_query_log_event methods
7356 **************************************************************************/
7357
7358
7359 #ifndef MYSQL_CLIENT
7360 Execute_load_query_log_event::
Execute_load_query_log_event(THD * thd_arg,const char * query_arg,ulong query_length_arg,uint fn_pos_start_arg,uint fn_pos_end_arg,enum_load_dup_handling dup_handling_arg,bool using_trans,bool direct,bool suppress_use,int errcode)7361 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
7362 ulong query_length_arg, uint fn_pos_start_arg,
7363 uint fn_pos_end_arg,
7364 enum_load_dup_handling dup_handling_arg,
7365 bool using_trans, bool direct, bool suppress_use,
7366 int errcode):
7367 Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, direct,
7368 suppress_use, errcode),
7369 file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
7370 fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
7371 {
7372 }
7373 #endif /* !MYSQL_CLIENT */
7374
7375
7376 Execute_load_query_log_event::
Execute_load_query_log_event(const char * buf,uint event_len,const Format_description_log_event * desc_event)7377 Execute_load_query_log_event(const char* buf, uint event_len,
7378 const Format_description_log_event* desc_event):
7379 Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
7380 file_id(0), fn_pos_start(0), fn_pos_end(0)
7381 {
7382 if (!Query_log_event::is_valid())
7383 return;
7384
7385 buf+= desc_event->common_header_len;
7386
7387 fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
7388 fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
7389 dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
7390
7391 if (fn_pos_start > q_len || fn_pos_end > q_len ||
7392 dup_handling > LOAD_DUP_REPLACE)
7393 return;
7394
7395 file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
7396 }
7397
7398
get_post_header_size_for_derived()7399 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
7400 {
7401 return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
7402 }
7403
7404
7405 #ifndef MYSQL_CLIENT
7406 bool
write_post_header_for_derived(IO_CACHE * file)7407 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
7408 {
7409 uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
7410 int4store(buf, file_id);
7411 int4store(buf + 4, fn_pos_start);
7412 int4store(buf + 4 + 4, fn_pos_end);
7413 *(buf + 4 + 4 + 4)= (uchar) dup_handling;
7414 return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
7415 }
7416 #endif
7417
7418
7419 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7420 void Execute_load_query_log_event::print(FILE* file,
7421 PRINT_EVENT_INFO* print_event_info)
7422 {
7423 print(file, print_event_info, 0);
7424 }
7425
7426 /**
7427 Prints the query as LOAD DATA LOCAL and with rewritten filename.
7428 */
print(FILE * file,PRINT_EVENT_INFO * print_event_info,const char * local_fname)7429 void Execute_load_query_log_event::print(FILE* file,
7430 PRINT_EVENT_INFO* print_event_info,
7431 const char *local_fname)
7432 {
7433 Write_on_release_cache cache(&print_event_info->head_cache, file);
7434
7435 print_query_header(&cache, print_event_info);
7436 /**
7437 reduce the size of io cache so that the write function is called
7438 for every call to my_b_printf().
7439 */
7440 DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
7441 {(&cache)->write_pos= (&cache)->write_end;
7442 DBUG_SET("+d,simulate_file_write_error");});
7443
7444 if (local_fname)
7445 {
7446 my_b_write(&cache, (uchar*) query, fn_pos_start);
7447 my_b_printf(&cache, " LOCAL INFILE ");
7448 pretty_print_str(&cache, local_fname, strlen(local_fname));
7449
7450 if (dup_handling == LOAD_DUP_REPLACE)
7451 my_b_printf(&cache, " REPLACE");
7452 my_b_printf(&cache, " INTO");
7453 my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
7454 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
7455 }
7456 else
7457 {
7458 my_b_write(&cache, (uchar*) query, q_len);
7459 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
7460 }
7461
7462 if (!print_event_info->short_form)
7463 my_b_printf(&cache, "# file_id: %d \n", file_id);
7464 }
7465 #endif
7466
7467
7468 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7469 void Execute_load_query_log_event::pack_info(Protocol *protocol)
7470 {
7471 char *buf, *pos;
7472 if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
7473 MYF(MY_WME))))
7474 return;
7475 pos= buf;
7476 if (db && db_len)
7477 {
7478 /*
7479 Statically allocates room to store '\0' and an identifier
7480 that may have NAME_LEN * 2 due to quoting and there are
7481 two quoting characters that wrap them.
7482 */
7483 char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
7484 size_t size= 0;
7485 size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
7486 pos= strmov(buf, "use ");
7487 memcpy(pos, quoted_db, size);
7488 pos= strmov(pos + size, "; ");
7489 }
7490 if (query && q_len)
7491 {
7492 memcpy(pos, query, q_len);
7493 pos+= q_len;
7494 }
7495 pos= strmov(pos, " ;file_id=");
7496 pos= int10_to_str((long) file_id, pos, 10);
7497 protocol->store(buf, pos-buf, &my_charset_bin);
7498 my_free(buf);
7499 }
7500
7501
7502 int
do_apply_event(Relay_log_info const * rli)7503 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
7504 {
7505 char *p;
7506 char *buf;
7507 char *fname;
7508 char *fname_end;
7509 int error;
7510
7511 buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
7512 (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
7513
7514 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
7515
7516 /* Replace filename and LOCAL keyword in query before executing it */
7517 if (buf == NULL)
7518 {
7519 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
7520 ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
7521 return 1;
7522 }
7523
7524 p= buf;
7525 memcpy(p, query, fn_pos_start);
7526 p+= fn_pos_start;
7527 fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
7528 p= slave_load_file_stem(p, file_id, server_id, ".data");
7529 fname_end= p= strend(p); // Safer than p=p+5
7530 *(p++)='\'';
7531 switch (dup_handling) {
7532 case LOAD_DUP_IGNORE:
7533 p= strmake(p, STRING_WITH_LEN(" IGNORE"));
7534 break;
7535 case LOAD_DUP_REPLACE:
7536 p= strmake(p, STRING_WITH_LEN(" REPLACE"));
7537 break;
7538 default:
7539 /* Ordinary load data */
7540 break;
7541 }
7542 p= strmake(p, STRING_WITH_LEN(" INTO "));
7543 p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
7544
7545 error= Query_log_event::do_apply_event(rli, buf, p-buf);
7546
7547 /* Forging file name for deletion in same buffer */
7548 *fname_end= 0;
7549
7550 /*
7551 If there was an error the slave is going to stop, leave the
7552 file so that we can re-execute this event at START SLAVE.
7553 */
7554 if (!error)
7555 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
7556
7557 my_free(buf);
7558 return error;
7559 }
7560 #endif
7561
7562
7563 /**************************************************************************
7564 sql_ex_info methods
7565 **************************************************************************/
7566
7567 /*
7568 sql_ex_info::write_data()
7569 */
7570
write_data(IO_CACHE * file)7571 bool sql_ex_info::write_data(IO_CACHE* file)
7572 {
7573 if (new_format())
7574 {
7575 return (write_str(file, field_term, (uint) field_term_len) ||
7576 write_str(file, enclosed, (uint) enclosed_len) ||
7577 write_str(file, line_term, (uint) line_term_len) ||
7578 write_str(file, line_start, (uint) line_start_len) ||
7579 write_str(file, escaped, (uint) escaped_len) ||
7580 my_b_safe_write(file,(uchar*) &opt_flags,1));
7581 }
7582 else
7583 {
7584 /**
7585 @todo This is sensitive to field padding. We should write a
7586 char[7], not an old_sql_ex. /sven
7587 */
7588 old_sql_ex old_ex;
7589 old_ex.field_term= *field_term;
7590 old_ex.enclosed= *enclosed;
7591 old_ex.line_term= *line_term;
7592 old_ex.line_start= *line_start;
7593 old_ex.escaped= *escaped;
7594 old_ex.opt_flags= opt_flags;
7595 old_ex.empty_flags=empty_flags;
7596 return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
7597 }
7598 }
7599
7600
7601 /*
7602 sql_ex_info::init()
7603 */
7604
init(const char * buf,const char * buf_end,bool use_new_format)7605 const char *sql_ex_info::init(const char *buf, const char *buf_end,
7606 bool use_new_format)
7607 {
7608 cached_new_format = use_new_format;
7609 if (use_new_format)
7610 {
7611 empty_flags=0;
7612 /*
7613 The code below assumes that buf will not disappear from
7614 under our feet during the lifetime of the event. This assumption
7615 holds true in the slave thread if the log is in new format, but is not
7616 the case when we have old format because we will be reusing net buffer
7617 to read the actual file before we write out the Create_file event.
7618 */
7619 if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
7620 read_str(&buf, buf_end, &enclosed, &enclosed_len) ||
7621 read_str(&buf, buf_end, &line_term, &line_term_len) ||
7622 read_str(&buf, buf_end, &line_start, &line_start_len) ||
7623 read_str(&buf, buf_end, &escaped, &escaped_len))
7624 return 0;
7625 opt_flags = *buf++;
7626 }
7627 else
7628 {
7629 field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
7630 field_term = buf++; // Use first byte in string
7631 enclosed= buf++;
7632 line_term= buf++;
7633 line_start= buf++;
7634 escaped= buf++;
7635 opt_flags = *buf++;
7636 empty_flags= *buf++;
7637 if (empty_flags & FIELD_TERM_EMPTY)
7638 field_term_len=0;
7639 if (empty_flags & ENCLOSED_EMPTY)
7640 enclosed_len=0;
7641 if (empty_flags & LINE_TERM_EMPTY)
7642 line_term_len=0;
7643 if (empty_flags & LINE_START_EMPTY)
7644 line_start_len=0;
7645 if (empty_flags & ESCAPED_EMPTY)
7646 escaped_len=0;
7647 }
7648 return buf;
7649 }
7650
7651
7652 /**************************************************************************
7653 Rows_log_event member functions
7654 **************************************************************************/
7655
7656 #ifndef MYSQL_CLIENT
Rows_log_event(THD * thd_arg,TABLE * tbl_arg,ulong tid,MY_BITMAP const * cols,bool is_transactional)7657 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
7658 MY_BITMAP const *cols, bool is_transactional)
7659 : Log_event(thd_arg, 0, is_transactional),
7660 m_row_count(0),
7661 m_table(tbl_arg),
7662 m_table_id(tid),
7663 m_width(tbl_arg ? tbl_arg->s->fields : 1),
7664 m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
7665 #ifdef HAVE_REPLICATION
7666 , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
7667 #endif
7668 {
7669 /*
7670 We allow a special form of dummy event when the table, and cols
7671 are null and the table id is ~0UL. This is a temporary
7672 solution, to be able to terminate a started statement in the
7673 binary log: the extraneous events will be removed in the future.
7674 */
7675 DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) ||
7676 (!tbl_arg && !cols && tid == ~0UL));
7677
7678 if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
7679 set_flags(NO_FOREIGN_KEY_CHECKS_F);
7680 if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
7681 set_flags(RELAXED_UNIQUE_CHECKS_F);
7682 /* if bitmap_init fails, caught in is_valid() */
7683 if (likely(!bitmap_init(&m_cols,
7684 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
7685 m_width,
7686 false)))
7687 {
7688 /* Cols can be zero if this is a dummy binrows event */
7689 if (likely(cols != NULL))
7690 {
7691 memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
7692 create_last_word_mask(&m_cols);
7693 }
7694 }
7695 else
7696 {
7697 // Needed because bitmap_init() does not set it to null on failure
7698 m_cols.bitmap= 0;
7699 }
7700 }
7701 #endif
7702
Rows_log_event(const char * buf,uint event_len,Log_event_type event_type,const Format_description_log_event * description_event)7703 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
7704 Log_event_type event_type,
7705 const Format_description_log_event
7706 *description_event)
7707 : Log_event(buf, description_event),
7708 m_row_count(0),
7709 #ifndef MYSQL_CLIENT
7710 m_table(NULL),
7711 #endif
7712 m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
7713 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7714 , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
7715 #endif
7716 {
7717 DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
7718 uint8 const common_header_len= description_event->common_header_len;
7719 uint8 const post_header_len= description_event->post_header_len[event_type-1];
7720
7721 DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
7722 "post_header_len: %d",
7723 event_len, common_header_len,
7724 post_header_len));
7725
7726 const char *post_start= buf + common_header_len;
7727 post_start+= RW_MAPID_OFFSET;
7728 if (post_header_len == 6)
7729 {
7730 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
7731 m_table_id= uint4korr(post_start);
7732 post_start+= 4;
7733 }
7734 else
7735 {
7736 m_table_id= (ulong) uint6korr(post_start);
7737 post_start+= RW_FLAGS_OFFSET;
7738 }
7739
7740 m_flags= uint2korr(post_start);
7741
7742 uchar const *const var_start=
7743 (const uchar *)buf + common_header_len + post_header_len;
7744 uchar const *const ptr_width= var_start;
7745 uchar *ptr_after_width= (uchar*) ptr_width;
7746 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
7747 m_width = net_field_length(&ptr_after_width);
7748 DBUG_PRINT("debug", ("m_width=%lu", m_width));
7749 /* Avoid reading out of buffer */
7750 if (static_cast<unsigned int>((ptr_after_width +
7751 (m_width + 7) / 8) -
7752 (uchar*)buf) > event_len)
7753 {
7754 m_cols.bitmap= NULL;
7755 DBUG_VOID_RETURN;
7756 }
7757
7758 /* if bitmap_init fails, catched in is_valid() */
7759 if (likely(!bitmap_init(&m_cols,
7760 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
7761 m_width,
7762 false)))
7763 {
7764 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
7765 memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
7766 create_last_word_mask(&m_cols);
7767 ptr_after_width+= (m_width + 7) / 8;
7768 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
7769 }
7770 else
7771 {
7772 // Needed because bitmap_init() does not set it to null on failure
7773 m_cols.bitmap= NULL;
7774 DBUG_VOID_RETURN;
7775 }
7776
7777 m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
7778
7779 if (event_type == UPDATE_ROWS_EVENT)
7780 {
7781 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
7782
7783 /* if bitmap_init fails, caught in is_valid() */
7784 if (likely(!bitmap_init(&m_cols_ai,
7785 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
7786 m_width,
7787 false)))
7788 {
7789 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
7790 memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
7791 create_last_word_mask(&m_cols_ai);
7792 ptr_after_width+= (m_width + 7) / 8;
7793 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
7794 no_bytes_in_map(&m_cols_ai));
7795 }
7796 else
7797 {
7798 // Needed because bitmap_init() does not set it to null on failure
7799 m_cols_ai.bitmap= 0;
7800 DBUG_VOID_RETURN;
7801 }
7802 }
7803
7804 const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
7805
7806 size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
7807 if (read_size > event_len)
7808 {
7809 DBUG_VOID_RETURN;
7810 }
7811 size_t const data_size= event_len - read_size;
7812 DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
7813 m_table_id, m_flags, m_width, (ulong) data_size));
7814
7815 m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
7816 if (likely((bool)m_rows_buf))
7817 {
7818 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
7819 m_curr_row= m_rows_buf;
7820 #endif
7821 m_rows_end= m_rows_buf + data_size;
7822 m_rows_cur= m_rows_end;
7823 memcpy(m_rows_buf, ptr_rows_data, data_size);
7824 }
7825 else
7826 m_cols.bitmap= 0; // to not free it
7827
7828 DBUG_VOID_RETURN;
7829 }
7830
~Rows_log_event()7831 Rows_log_event::~Rows_log_event()
7832 {
7833 if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
7834 m_cols.bitmap= 0; // so no my_free in bitmap_free
7835 bitmap_free(&m_cols); // To pair with bitmap_init().
7836 my_free(m_rows_buf);
7837 }
7838
get_data_size()7839 int Rows_log_event::get_data_size()
7840 {
7841 int const type_code= get_type_code();
7842
7843 uchar buf[sizeof(m_width) + 1];
7844 uchar *end= net_store_length(buf, m_width);
7845
7846 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
7847 return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
7848 (type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
7849 (m_rows_cur - m_rows_buf););
7850 int data_size= ROWS_HEADER_LEN;
7851 data_size+= no_bytes_in_map(&m_cols);
7852 data_size+= (uint) (end - buf);
7853
7854 if (type_code == UPDATE_ROWS_EVENT)
7855 data_size+= no_bytes_in_map(&m_cols_ai);
7856
7857 data_size+= (uint) (m_rows_cur - m_rows_buf);
7858 return data_size;
7859 }
7860
7861
7862 #ifndef MYSQL_CLIENT
do_add_row_data(uchar * row_data,size_t length)7863 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
7864 {
7865 /*
7866 When the table has a primary key, we would probably want, by default, to
7867 log only the primary key value instead of the entire "before image". This
7868 would save binlog space. TODO
7869 */
7870 DBUG_ENTER("Rows_log_event::do_add_row_data");
7871 DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data,
7872 (ulong) length));
7873 /*
7874 Don't print debug messages when running valgrind since they can
7875 trigger false warnings.
7876 */
7877 #ifndef HAVE_purify
7878 DBUG_DUMP("row_data", row_data, min(length, 32));
7879 #endif
7880
7881 DBUG_ASSERT(m_rows_buf <= m_rows_cur);
7882 DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
7883 DBUG_ASSERT(m_rows_cur <= m_rows_end);
7884
7885 /* The cast will always work since m_rows_cur <= m_rows_end */
7886 if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
7887 {
7888 size_t const block_size= 1024;
7889 ulong cur_size= m_rows_cur - m_rows_buf;
7890 DBUG_EXECUTE_IF("simulate_too_big_row_case1",
7891 cur_size= UINT_MAX32 - (block_size * 10);
7892 length= UINT_MAX32 - (block_size * 10););
7893 DBUG_EXECUTE_IF("simulate_too_big_row_case2",
7894 cur_size= UINT_MAX32 - (block_size * 10);
7895 length= block_size * 10;);
7896 DBUG_EXECUTE_IF("simulate_too_big_row_case3",
7897 cur_size= block_size * 10;
7898 length= UINT_MAX32 - (block_size * 10););
7899 DBUG_EXECUTE_IF("simulate_too_big_row_case4",
7900 cur_size= UINT_MAX32 - (block_size * 10);
7901 length= (block_size * 10) - block_size + 1;);
7902 ulong remaining_space= UINT_MAX32 - cur_size;
7903 /* Check that the new data fits within remaining space and we can add
7904 block_size without wrapping.
7905 */
7906 if (length > remaining_space ||
7907 ((length + block_size) > remaining_space))
7908 {
7909 sql_print_error("The row data is greater than 4GB, which is too big to "
7910 "write to the binary log.");
7911 DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
7912 }
7913 ulong const new_alloc=
7914 block_size * ((cur_size + length + block_size - 1) / block_size);
7915
7916 uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
7917 MYF(MY_ALLOW_ZERO_PTR|MY_WME));
7918 if (unlikely(!new_buf))
7919 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
7920
7921 /* If the memory moved, we need to move the pointers */
7922 if (new_buf != m_rows_buf)
7923 {
7924 m_rows_buf= new_buf;
7925 m_rows_cur= m_rows_buf + cur_size;
7926 }
7927
7928 /*
7929 The end pointer should always be changed to point to the end of
7930 the allocated memory.
7931 */
7932 m_rows_end= m_rows_buf + new_alloc;
7933 }
7934
7935 DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
7936 memcpy(m_rows_cur, row_data, length);
7937 m_rows_cur+= length;
7938 m_row_count++;
7939 DBUG_RETURN(0);
7940 }
7941 #endif
7942
7943 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)7944 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
7945 {
7946 DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
7947 int error= 0;
7948 /*
7949 If m_table_id == ~0UL, then we have a dummy event that does not
7950 contain any data. In that case, we just remove all tables in the
7951 tables_to_lock list, close the thread tables, and return with
7952 success.
7953 */
7954 if (m_table_id == ~0UL)
7955 {
7956 /*
7957 This one is supposed to be set: just an extra check so that
7958 nothing strange has happened.
7959 */
7960 DBUG_ASSERT(get_flags(STMT_END_F));
7961
7962 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
7963 thd->clear_error();
7964 DBUG_RETURN(0);
7965 }
7966
7967 /*
7968 'thd' has been set by exec_relay_log_event(), just before calling
7969 do_apply_event(). We still check here to prevent future coding
7970 errors.
7971 */
7972 DBUG_ASSERT(rli->sql_thd == thd);
7973
7974 /*
7975 If there is no locks taken, this is the first binrow event seen
7976 after the table map events. We should then lock all the tables
7977 used in the transaction and proceed with execution of the actual
7978 event.
7979 */
7980 if (!thd->lock)
7981 {
7982 /*
7983 Lock_tables() reads the contents of thd->lex, so they must be
7984 initialized.
7985
7986 We also call the mysql_reset_thd_for_next_command(), since this
7987 is the logical start of the next "statement". Note that this
7988 call might reset the value of current_stmt_binlog_format, so
7989 we need to do any changes to that value after this function.
7990 */
7991 lex_start(thd);
7992 mysql_reset_thd_for_next_command(thd);
7993 /*
7994 The current statement is just about to begin and
7995 has not yet modified anything. Note, all.modified is reset
7996 by mysql_reset_thd_for_next_command.
7997 */
7998 thd->transaction.stmt.modified_non_trans_table= FALSE;
7999 /*
8000 This is a row injection, so we flag the "statement" as
8001 such. Note that this code is called both when the slave does row
8002 injections and when the BINLOG statement is used to do row
8003 injections.
8004 */
8005 thd->lex->set_stmt_row_injection();
8006
8007 /*
8008 There are a few flags that are replicated with each row event.
8009 Make sure to set/clear them before executing the main body of
8010 the event.
8011 */
8012 if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
8013 thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
8014 else
8015 thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
8016
8017 if (get_flags(RELAXED_UNIQUE_CHECKS_F))
8018 thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
8019 else
8020 thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
8021 /* A small test to verify that objects have consistent types */
8022 DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
8023
8024 if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
8025 {
8026 uint actual_error= thd->stmt_da->sql_errno();
8027 if (thd->is_slave_error || thd->is_fatal_error)
8028 {
8029 /*
8030 Error reporting borrowed from Query_log_event with many excessive
8031 simplifications.
8032 We should not honour --slave-skip-errors at this point as we are
8033 having severe errors which should not be skiped.
8034 */
8035 rli->report(ERROR_LEVEL, actual_error,
8036 "Error executing row event: '%s'",
8037 (actual_error ? thd->stmt_da->message() :
8038 "unexpected success or fatal error"));
8039 thd->is_slave_error= 1;
8040 }
8041 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
8042 DBUG_RETURN(actual_error);
8043 }
8044
8045 /*
8046 When the open and locking succeeded, we check all tables to
8047 ensure that they still have the correct type.
8048 */
8049
8050 {
8051 DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
8052 rli->tables_to_lock));
8053
8054 /**
8055 When using RBR and MyISAM MERGE tables the base tables that make
8056 up the MERGE table can be appended to the list of tables to lock.
8057
8058 Thus, we just check compatibility for those that tables that have
8059 a correspondent table map event (ie, those that are actually going
8060 to be accessed while applying the event). That's why the loop stops
8061 at rli->tables_to_lock_count .
8062
8063 NOTE: The base tables are added here are removed when
8064 close_thread_tables is called.
8065 */
8066 TABLE_LIST *table_list_ptr= rli->tables_to_lock;
8067 for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count);
8068 table_list_ptr= table_list_ptr->next_global, i++)
8069 {
8070 /*
8071 Below if condition takes care of skipping base tables that
8072 make up the MERGE table (which are added by open_tables()
8073 call). They are added next to the merge table in the list.
8074 For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
8075 are base tables for merge table 't3'), open_tables will modify
8076 the list by adding t1 and t2 again immediately after t3 in the
8077 list (*not at the end of the list*). New table_to_lock list will
8078 look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
8079 objects added by open_tables() call). There is no flag(or logic) in
8080 open_tables() that can skip adding these base tables to the list.
8081 So the logic here should take care of skipping them.
8082
8083 tables_to_lock_count logic will take care of skipping base tables
8084 that are added at the end of the list.
8085 For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
8086 the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
8087 because tables_to_lock_count logic in this for loop.
8088 */
8089 if (table_list_ptr->parent_l)
8090 continue;
8091 /*
8092 We can use a down cast here since we know that every table added
8093 to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
8094 skipped above).
8095 */
8096 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
8097 DBUG_ASSERT(ptr->m_tabledef_valid);
8098 TABLE *conv_table;
8099 if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
8100 ptr->table, &conv_table))
8101 {
8102 DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
8103 ptr->table->s->db.str,
8104 ptr->table->s->table_name.str));
8105 /*
8106 We should not honour --slave-skip-errors at this point as we are
8107 having severe errors which should not be skiped.
8108 */
8109 thd->is_slave_error= 1;
8110 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
8111 DBUG_RETURN(ERR_BAD_TABLE_DEF);
8112 }
8113 DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
8114 " - conv_table: %p",
8115 ptr->table->s->db.str,
8116 ptr->table->s->table_name.str, conv_table));
8117 ptr->m_conv_table= conv_table;
8118 }
8119 }
8120
8121 /*
8122 ... and then we add all the tables to the table map and but keep
8123 them in the tables to lock list.
8124
8125 We also invalidate the query cache for all the tables, since
8126 they will now be changed.
8127
8128 TODO [/Matz]: Maybe the query cache should not be invalidated
8129 here? It might be that a table is not changed, even though it
8130 was locked for the statement. We do know that each
8131 Rows_log_event contain at least one row, so after processing one
8132 Rows_log_event, we can invalidate the query cache for the
8133 associated table.
8134 */
8135 TABLE_LIST *ptr= rli->tables_to_lock;
8136 for (uint i=0 ; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
8137 {
8138 /*
8139 Please see comment in above 'for' loop to know the reason
8140 for this if condition
8141 */
8142 if (ptr->parent_l)
8143 continue;
8144 const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
8145 }
8146
8147 #ifdef HAVE_QUERY_CACHE
8148 query_cache.invalidate_locked_for_write(rli->tables_to_lock);
8149 #endif
8150 }
8151
8152 TABLE*
8153 table=
8154 m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
8155
8156 DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %lu", (ulong) m_table, m_table_id));
8157
8158 /*
8159 A row event comprising of a P_S table
8160 - should not be replicated (i.e executed) by the slave SQL thread.
8161 - should not be executed by the client in the form BINLOG '...' stmts.
8162 */
8163 if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
8164 table= NULL;
8165
8166 if (table)
8167 {
8168 bool transactional_table= table->file->has_transactions();
8169 /*
8170 table == NULL means that this table should not be replicated
8171 (this was set up by Table_map_log_event::do_apply_event()
8172 which tested replicate-* rules).
8173 */
8174
8175 /*
8176 It's not needed to set_time() but
8177 1) it continues the property that "Time" in SHOW PROCESSLIST shows how
8178 much slave is behind
8179 2) it will be needed when we allow replication from a table with no
8180 TIMESTAMP column to a table with one.
8181 So we call set_time(), like in SBR. Presently it changes nothing.
8182 */
8183 thd->set_time((time_t)when);
8184
8185 /*
8186 Now we are in a statement and will stay in a statement until we
8187 see a STMT_END_F.
8188
8189 We set this flag here, before actually applying any rows, in
8190 case the SQL thread is stopped and we need to detect that we're
8191 inside a statement and halting abruptly might cause problems
8192 when restarting.
8193 */
8194 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
8195
8196 if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
8197 set_flags(COMPLETE_ROWS_F);
8198
8199 /*
8200 Set tables write and read sets.
8201
8202 Read_set contains all slave columns (in case we are going to fetch
8203 a complete record from slave)
8204
8205 Write_set equals the m_cols bitmap sent from master but it can be
8206 longer if slave has extra columns.
8207 */
8208
8209 DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols);
8210
8211 bitmap_set_all(table->read_set);
8212 bitmap_set_all(table->write_set);
8213 if (!get_flags(COMPLETE_ROWS_F))
8214 bitmap_intersect(table->write_set,&m_cols);
8215
8216 this->slave_exec_mode= slave_exec_mode_options; // fix the mode
8217
8218 // Do event specific preparations
8219 error= do_before_row_operations(rli);
8220
8221 /*
8222 Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
8223 Don't allow generation of auto_increment value when processing
8224 rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
8225 to this rule happens when the auto_inc column exists on some
8226 extra columns on the slave. In that case, do not force
8227 MODE_NO_AUTO_VALUE_ON_ZERO.
8228 */
8229 ulong saved_sql_mode= thd->variables.sql_mode;
8230 if (!is_auto_inc_in_extra_columns())
8231 thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
8232
8233 // row processing loop
8234
8235 /*
8236 set the initial time of this ROWS statement if it was not done
8237 before in some other ROWS event.
8238 */
8239 const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
8240
8241 while (error == 0 && m_curr_row < m_rows_end)
8242 {
8243 /* in_use can have been set to NULL in close_tables_for_reopen */
8244 THD* old_thd= table->in_use;
8245 if (!table->in_use)
8246 table->in_use= thd;
8247
8248 error= do_exec_row(rli);
8249
8250 if (error)
8251 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
8252 DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
8253
8254 table->in_use = old_thd;
8255
8256 if (error)
8257 {
8258 int actual_error= convert_handler_error(error, thd, table);
8259 bool idempotent_error= (idempotent_error_code(error) &&
8260 (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
8261 bool ignored_error= (idempotent_error == 0 ?
8262 ignored_error_code(actual_error) : 0);
8263
8264 if (idempotent_error || ignored_error)
8265 {
8266 if (global_system_variables.log_warnings)
8267 slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
8268 get_type_str(),
8269 RPL_LOG_NAME, (ulong) log_pos);
8270 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
8271 error= 0;
8272 if (idempotent_error == 0)
8273 break;
8274 }
8275 }
8276
8277 /*
8278 If m_curr_row_end was not set during event execution (e.g., because
8279 of errors) we can't proceed to the next row. If the error is transient
8280 (i.e., error==0 at this point) we must call unpack_current_row() to set
8281 m_curr_row_end.
8282 */
8283
8284 DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
8285 (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
8286
8287 if (!m_curr_row_end && !error)
8288 error= unpack_current_row(rli);
8289
8290 // at this moment m_curr_row_end should be set
8291 DBUG_ASSERT(error || m_curr_row_end != NULL);
8292 DBUG_ASSERT(error || m_curr_row < m_curr_row_end);
8293 DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
8294
8295 m_curr_row= m_curr_row_end;
8296
8297 if (error == 0 && !transactional_table)
8298 thd->transaction.all.modified_non_trans_table=
8299 thd->transaction.stmt.modified_non_trans_table= TRUE;
8300 } // row processing loop
8301
8302 /*
8303 Restore the sql_mode after the rows event is processed.
8304 */
8305 thd->variables.sql_mode= saved_sql_mode;
8306
8307 {/**
8308 The following failure injecion works in cooperation with tests
8309 setting @@global.debug= 'd,stop_slave_middle_group'.
8310 The sql thread receives the killed status and will proceed
8311 to shutdown trying to finish incomplete events group.
8312 */
8313 DBUG_EXECUTE_IF("stop_slave_middle_group",
8314 if (thd->transaction.all.modified_non_trans_table)
8315 const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
8316 }
8317
8318 if ((error= do_after_row_operations(rli, error)) &&
8319 ignored_error_code(convert_handler_error(error, thd, table)))
8320 {
8321
8322 if (global_system_variables.log_warnings)
8323 slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
8324 get_type_str(),
8325 RPL_LOG_NAME, (ulong) log_pos);
8326 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
8327 error= 0;
8328 }
8329 } // if (table)
8330
8331
8332 if (error)
8333 {
8334 slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
8335 get_type_str(),
8336 RPL_LOG_NAME, (ulong) log_pos);
8337 /*
8338 @todo We should probably not call
8339 reset_current_stmt_binlog_format_row() from here.
8340
8341 Note: this applies to log_event_old.cc too.
8342 /Sven
8343 */
8344 thd->reset_current_stmt_binlog_format_row();
8345 thd->is_slave_error= 1;
8346 DBUG_RETURN(error);
8347 }
8348
8349 if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rli, thd)))
8350 slave_rows_error_report(ERROR_LEVEL,
8351 thd->is_error() ? 0 : error,
8352 rli, thd, table,
8353 get_type_str(),
8354 RPL_LOG_NAME, (ulong) log_pos);
8355 DBUG_RETURN(error);
8356 }
8357
8358 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)8359 Rows_log_event::do_shall_skip(Relay_log_info *rli)
8360 {
8361 /*
8362 If the slave skip counter is 1 and this event does not end a
8363 statement, then we should not start executing on the next event.
8364 Otherwise, we defer the decision to the normal skipping logic.
8365 */
8366 if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
8367 return Log_event::EVENT_SKIP_IGNORE;
8368 else
8369 return Log_event::do_shall_skip(rli);
8370 }
8371
8372 /**
8373 The function is called at Rows_log_event statement commit time,
8374 normally from Rows_log_event::do_update_pos() and possibly from
8375 Query_log_event::do_apply_event() of the COMMIT.
8376 The function commits the last statement for engines, binlog and
8377 releases resources have been allocated for the statement.
8378
8379 @retval 0 Ok.
8380 @retval non-zero Error at the commit.
8381 */
8382
rows_event_stmt_cleanup(Relay_log_info const * rli,THD * thd)8383 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
8384 {
8385 int error;
8386 {
8387 /*
8388 This is the end of a statement or transaction, so close (and
8389 unlock) the tables we opened when processing the
8390 Table_map_log_event starting the statement.
8391
8392 OBSERVER. This will clear *all* mappings, not only those that
8393 are open for the table. There is not good handle for on-close
8394 actions for tables.
8395
8396 NOTE. Even if we have no table ('table' == 0) we still need to be
8397 here, so that we increase the group relay log position. If we didn't, we
8398 could have a group relay log position which lags behind "forever"
8399 (assume the last master's transaction is ignored by the slave because of
8400 replicate-ignore rules).
8401 */
8402 error= thd->binlog_flush_pending_rows_event(TRUE);
8403
8404 /*
8405 If this event is not in a transaction, the call below will, if some
8406 transactional storage engines are involved, commit the statement into
8407 them and flush the pending event to binlog.
8408 If this event is in a transaction, the call will do nothing, but a
8409 Xid_log_event will come next which will, if some transactional engines
8410 are involved, commit the transaction and flush the pending event to the
8411 binlog.
8412 If there was a deadlock the transaction should have been rolled back
8413 already. So there should be no need to rollback the transaction.
8414 */
8415 DBUG_ASSERT(! thd->transaction_rollback_request);
8416 error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
8417
8418 /*
8419 Now what if this is not a transactional engine? we still need to
8420 flush the pending event to the binlog; we did it with
8421 thd->binlog_flush_pending_rows_event(). Note that we imitate
8422 what is done for real queries: a call to
8423 ha_autocommit_or_rollback() (sometimes only if involves a
8424 transactional engine), and a call to be sure to have the pending
8425 event flushed.
8426 */
8427
8428 /*
8429 @todo We should probably not call
8430 reset_current_stmt_binlog_format_row() from here.
8431
8432 Note: this applies to log_event_old.cc too
8433
8434 Btw, the previous comment about transactional engines does not
8435 seem related to anything that happens here.
8436 /Sven
8437 */
8438 thd->reset_current_stmt_binlog_format_row();
8439
8440 const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
8441 }
8442 return error;
8443 }
8444
8445 /**
8446 The method either increments the relay log position or
8447 commits the current statement and increments the master group
8448 possition if the event is STMT_END_F flagged and
8449 the statement corresponds to the autocommit query (i.e replicated
8450 without wrapping in BEGIN/COMMIT)
8451
8452 @retval 0 Success
8453 @retval non-zero Error in the statement commit
8454 */
8455 int
do_update_pos(Relay_log_info * rli)8456 Rows_log_event::do_update_pos(Relay_log_info *rli)
8457 {
8458 DBUG_ENTER("Rows_log_event::do_update_pos");
8459 int error= 0;
8460
8461 DBUG_PRINT("info", ("flags: %s",
8462 get_flags(STMT_END_F) ? "STMT_END_F " : ""));
8463
8464 if (get_flags(STMT_END_F))
8465 {
8466 /*
8467 Indicate that a statement is finished.
8468 Step the group log position if we are not in a transaction,
8469 otherwise increase the event log position.
8470 */
8471 rli->stmt_done(log_pos, when);
8472 /*
8473 Clear any errors in thd->net.last_err*. It is not known if this is
8474 needed or not. It is believed that any errors that may exist in
8475 thd->net.last_err* are allowed. Examples of errors are "key not
8476 found", which is produced in the test case rpl_row_conflicts.test
8477 */
8478 thd->clear_error();
8479 }
8480 else
8481 {
8482 rli->inc_event_relay_log_pos();
8483 }
8484
8485 DBUG_RETURN(error);
8486 }
8487
8488 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
8489
8490 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)8491 bool Rows_log_event::write_data_header(IO_CACHE *file)
8492 {
8493 uchar buf[ROWS_HEADER_LEN]; // No need to init the buffer
8494 DBUG_ASSERT(m_table_id != ~0UL);
8495 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
8496 {
8497 int4store(buf + 0, m_table_id);
8498 int2store(buf + 4, m_flags);
8499 return (my_b_safe_write(file, buf, 6));
8500 });
8501 int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
8502 int2store(buf + RW_FLAGS_OFFSET, m_flags);
8503 return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
8504 }
8505
write_data_body(IO_CACHE * file)8506 bool Rows_log_event::write_data_body(IO_CACHE*file)
8507 {
8508 /*
8509 Note that this should be the number of *bits*, not the number of
8510 bytes.
8511 */
8512 uchar sbuf[sizeof(m_width) + 1];
8513 my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
8514 bool res= false;
8515 uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
8516 DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
8517
8518 DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
8519 res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
8520
8521 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
8522 res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
8523 no_bytes_in_map(&m_cols));
8524 /*
8525 TODO[refactor write]: Remove the "down cast" here (and elsewhere).
8526 */
8527 if (get_type_code() == UPDATE_ROWS_EVENT)
8528 {
8529 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
8530 no_bytes_in_map(&m_cols_ai));
8531 res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
8532 no_bytes_in_map(&m_cols_ai));
8533 }
8534 DBUG_DUMP("rows", m_rows_buf, data_size);
8535 res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
8536
8537 return res;
8538
8539 }
8540 #endif
8541
8542 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8543 void Rows_log_event::pack_info(Protocol *protocol)
8544 {
8545 char buf[256];
8546 char const *const flagstr=
8547 get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
8548 size_t bytes= my_snprintf(buf, sizeof(buf),
8549 "table_id: %lu%s", m_table_id, flagstr);
8550 protocol->store(buf, bytes, &my_charset_bin);
8551 }
8552 #endif
8553
8554 #ifdef MYSQL_CLIENT
print_helper(FILE * file,PRINT_EVENT_INFO * print_event_info,char const * const name)8555 void Rows_log_event::print_helper(FILE *file,
8556 PRINT_EVENT_INFO *print_event_info,
8557 char const *const name)
8558 {
8559 IO_CACHE *const head= &print_event_info->head_cache;
8560 IO_CACHE *const body= &print_event_info->body_cache;
8561 if (!print_event_info->short_form)
8562 {
8563 bool const last_stmt_event= get_flags(STMT_END_F);
8564 print_header(head, print_event_info, !last_stmt_event);
8565 my_b_printf(head, "\t%s: table id %lu%s\n",
8566 name, m_table_id,
8567 last_stmt_event ? " flags: STMT_END_F" : "");
8568 print_base64(body, print_event_info, !last_stmt_event);
8569 }
8570
8571 if (get_flags(STMT_END_F))
8572 {
8573 copy_event_cache_to_file_and_reinit(head, file);
8574 copy_event_cache_to_file_and_reinit(body, file);
8575 }
8576 }
8577 #endif
8578
8579 /**************************************************************************
8580 Table_map_log_event member functions and support functions
8581 **************************************************************************/
8582
8583 /**
8584 @page How replication of field metadata works.
8585
8586 When a table map is created, the master first calls
8587 Table_map_log_event::save_field_metadata() which calculates how many
8588 values will be in the field metadata. Only those fields that require the
8589 extra data are added. The method also loops through all of the fields in
8590 the table calling the method Field::save_field_metadata() which returns the
8591 values for the field that will be saved in the metadata and replicated to
8592 the slave. Once all fields have been processed, the table map is written to
8593 the binlog adding the size of the field metadata and the field metadata to
8594 the end of the body of the table map.
8595
8596 When a table map is read on the slave, the field metadata is read from the
8597 table map and passed to the table_def class constructor which saves the
8598 field metadata from the table map into an array based on the type of the
8599 field. Field metadata values not present (those fields that do not use extra
8600 data) in the table map are initialized as zero (0). The array size is the
8601 same as the columns for the table on the slave.
8602
8603 Additionally, values saved for field metadata on the master are saved as a
8604 string of bytes (uchar) in the binlog. A field may require 1 or more bytes
8605 to store the information. In cases where values require multiple bytes
8606 (e.g. values > 255), the endian-safe methods are used to properly encode
8607 the values on the master and decode them on the slave. When the field
8608 metadata values are captured on the slave, they are stored in an array of
8609 type uint16. This allows the least number of casts to prevent casting bugs
8610 when the field metadata is used in comparisons of field attributes. When
8611 the field metadata is used for calculating addresses in pointer math, the
8612 type used is uint32.
8613 */
8614
8615 #if !defined(MYSQL_CLIENT)
8616 /**
8617 Save the field metadata based on the real_type of the field.
8618 The metadata saved depends on the type of the field. Some fields
8619 store a single byte for pack_length() while others store two bytes
8620 for field_length (max length).
8621
8622 @retval 0 Ok.
8623
8624 @todo
8625 We may want to consider changing the encoding of the information.
8626 Currently, the code attempts to minimize the number of bytes written to
8627 the tablemap. There are at least two other alternatives; 1) using
8628 net_store_length() to store the data allowing it to choose the number of
8629 bytes that are appropriate thereby making the code much easier to
8630 maintain (only 1 place to change the encoding), or 2) use a fixed number
8631 of bytes for each field. The problem with option 1 is that net_store_length()
8632 will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
8633 for fields like CHAR which can be no larger than 255 characters, the method
8634 will use 3 bytes when the value is > 250. Further, every value that is
8635 encoded using 2 parts (e.g., pack_length, field_length) will be numerically
8636 > 250 therefore will use 3 bytes for eah value. The problem with option 2
8637 is less wasteful for space but does waste 1 byte for every field that does
8638 not encode 2 parts.
8639 */
save_field_metadata()8640 int Table_map_log_event::save_field_metadata()
8641 {
8642 DBUG_ENTER("Table_map_log_event::save_field_metadata");
8643 int index= 0;
8644 for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
8645 {
8646 DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
8647 index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
8648 }
8649 DBUG_RETURN(index);
8650 }
8651 #endif /* !defined(MYSQL_CLIENT) */
8652
8653 /*
8654 Constructor used to build an event for writing to the binary log.
8655 Mats says tbl->s lives longer than this event so it's ok to copy pointers
8656 (tbl->s->db etc) and not pointer content.
8657 */
8658 #if !defined(MYSQL_CLIENT)
Table_map_log_event(THD * thd,TABLE * tbl,ulong tid,bool is_transactional)8659 Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
8660 bool is_transactional)
8661 : Log_event(thd, 0, is_transactional),
8662 m_table(tbl),
8663 m_dbnam(tbl->s->db.str),
8664 m_dblen(m_dbnam ? tbl->s->db.length : 0),
8665 m_tblnam(tbl->s->table_name.str),
8666 m_tbllen(tbl->s->table_name.length),
8667 m_colcnt(tbl->s->fields),
8668 m_memory(NULL),
8669 m_table_id(tid),
8670 m_flags(TM_BIT_LEN_EXACT_F),
8671 m_data_size(0),
8672 m_field_metadata(0),
8673 m_field_metadata_size(0),
8674 m_null_bits(0),
8675 m_meta_memory(NULL)
8676 {
8677 uchar cbuf[sizeof(m_colcnt) + 1];
8678 uchar *cbuf_end;
8679 DBUG_ASSERT(m_table_id != ~0UL);
8680 /*
8681 In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
8682 table.cc / alloc_table_share():
8683 Use the fact the key is db/0/table_name/0
8684 As we rely on this let's assert it.
8685 */
8686 DBUG_ASSERT((tbl->s->db.str == 0) ||
8687 (tbl->s->db.str[tbl->s->db.length] == 0));
8688 DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
8689
8690
8691 m_data_size= TABLE_MAP_HEADER_LEN;
8692 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
8693 m_data_size+= m_dblen + 2; // Include length and terminating \0
8694 m_data_size+= m_tbllen + 2; // Include length and terminating \0
8695 cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
8696 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
8697 m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
8698
8699 /* If malloc fails, caught in is_valid() */
8700 if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
8701 {
8702 m_coltype= reinterpret_cast<uchar*>(m_memory);
8703 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
8704 m_coltype[i]= m_table->field[i]->type();
8705 }
8706
8707 /*
8708 Calculate a bitmap for the results of maybe_null() for all columns.
8709 The bitmap is used to determine when there is a column from the master
8710 that is not on the slave and is null and thus not in the row data during
8711 replication.
8712 */
8713 uint num_null_bytes= (m_table->s->fields + 7) / 8;
8714 m_data_size+= num_null_bytes;
8715 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
8716 &m_null_bits, num_null_bytes,
8717 &m_field_metadata, (m_colcnt * 2),
8718 NULL);
8719
8720 bzero(m_field_metadata, (m_colcnt * 2));
8721
8722 /*
8723 Create an array for the field metadata and store it.
8724 */
8725 m_field_metadata_size= save_field_metadata();
8726 DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
8727
8728 /*
8729 Now set the size of the data to the size of the field metadata array
8730 plus one or three bytes (see pack.c:net_store_length) for number of
8731 elements in the field metadata array.
8732 */
8733 if (m_field_metadata_size < 251)
8734 m_data_size+= m_field_metadata_size + 1;
8735 else
8736 m_data_size+= m_field_metadata_size + 3;
8737
8738 bzero(m_null_bits, num_null_bytes);
8739 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
8740 if (m_table->field[i]->maybe_null())
8741 m_null_bits[(i / 8)]+= 1 << (i % 8);
8742
8743 }
8744 #endif /* !defined(MYSQL_CLIENT) */
8745
8746 /*
8747 Constructor used by slave to read the event from the binary log.
8748 */
8749 #if defined(HAVE_REPLICATION)
Table_map_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)8750 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
8751 const Format_description_log_event
8752 *description_event)
8753
8754 : Log_event(buf, description_event),
8755 #ifndef MYSQL_CLIENT
8756 m_table(NULL),
8757 #endif
8758 m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
8759 m_colcnt(0), m_coltype(0),
8760 m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
8761 m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
8762 m_null_bits(0), m_meta_memory(NULL)
8763 {
8764 unsigned int bytes_read= 0;
8765 DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
8766
8767 uint8 common_header_len= description_event->common_header_len;
8768 uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
8769 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
8770 event_len, common_header_len, post_header_len));
8771
8772 /*
8773 Don't print debug messages when running valgrind since they can
8774 trigger false warnings.
8775 */
8776 #ifndef HAVE_purify
8777 DBUG_DUMP("event buffer", (uchar*) buf, event_len);
8778 #endif
8779
8780 /* Read the post-header */
8781 const char *post_start= buf + common_header_len;
8782
8783 post_start+= TM_MAPID_OFFSET;
8784 if (post_header_len == 6)
8785 {
8786 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
8787 m_table_id= uint4korr(post_start);
8788 post_start+= 4;
8789 }
8790 else
8791 {
8792 DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
8793 m_table_id= (ulong) uint6korr(post_start);
8794 post_start+= TM_FLAGS_OFFSET;
8795 }
8796
8797 DBUG_ASSERT(m_table_id != ~0UL);
8798
8799 m_flags= uint2korr(post_start);
8800
8801 /* Read the variable part of the event */
8802 const char *const vpart= buf + common_header_len + post_header_len;
8803
8804 /* Extract the length of the various parts from the buffer */
8805 uchar const *const ptr_dblen= (uchar const*)vpart + 0;
8806 m_dblen= *(uchar*) ptr_dblen;
8807
8808 /* Length of database name + counter + terminating null */
8809 uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
8810 m_tbllen= *(uchar*) ptr_tbllen;
8811
8812 /* Length of table name + counter + terminating null */
8813 uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
8814 uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
8815 m_colcnt= net_field_length(&ptr_after_colcnt);
8816
8817 DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
8818 (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
8819 (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
8820 m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
8821
8822 /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
8823 m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
8824 &m_dbnam, (uint) m_dblen + 1,
8825 &m_tblnam, (uint) m_tbllen + 1,
8826 &m_coltype, (uint) m_colcnt,
8827 NullS);
8828
8829 if (m_memory)
8830 {
8831 /* Copy the different parts into their memory */
8832 strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
8833 strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
8834 memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
8835
8836 ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
8837 bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
8838 DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
8839 if (bytes_read < event_len)
8840 {
8841 m_field_metadata_size= net_field_length(&ptr_after_colcnt);
8842 DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
8843 uint num_null_bytes= (m_colcnt + 7) / 8;
8844 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
8845 &m_null_bits, num_null_bytes,
8846 &m_field_metadata, m_field_metadata_size,
8847 NULL);
8848 memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
8849 ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
8850 memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
8851 }
8852 }
8853
8854 DBUG_VOID_RETURN;
8855 }
8856 #endif
8857
~Table_map_log_event()8858 Table_map_log_event::~Table_map_log_event()
8859 {
8860 my_free(m_meta_memory);
8861 my_free(m_memory);
8862 }
8863
8864 /*
8865 Return value is an error code, one of:
8866
8867 -1 Failure to open table [from open_tables()]
8868 0 Success
8869 1 No room for more tables [from set_table()]
8870 2 Out of memory [from set_table()]
8871 3 Wrong table definition
8872 4 Daisy-chaining RBR with SBR not possible
8873 */
8874
8875 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
8876
8877 enum enum_tbl_map_status
8878 {
8879 /* no duplicate identifier found */
8880 OK_TO_PROCESS= 0,
8881
8882 /* this table map must be filtered out */
8883 FILTERED_OUT= 1,
8884
8885 /* identifier mapping table with different properties */
8886 SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
8887
8888 /* a duplicate identifier was found mapping the same table */
8889 SAME_ID_MAPPING_SAME_TABLE= 3
8890 };
8891
8892 /*
8893 Checks if this table map event should be processed or not. First
8894 it checks the filtering rules, and then looks for duplicate identifiers
8895 in the existing list of rli->tables_to_lock.
8896
8897 It checks that there hasn't been any corruption by verifying that there
8898 are no duplicate entries with different properties.
8899
8900 In some cases, some binary logs could get corrupted, showing several
8901 tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
8902 early sanity check for such cases and avoid that the server crashes
8903 later.
8904
8905 In some corner cases, the master logs duplicate table map events, i.e.,
8906 same id, same database name, same table name (see: BUG#37137). This is
8907 different from the above as it's the same table that is mapped again
8908 to the same identifier. Thus we cannot just check for same ids and
8909 assume that the event is corrupted we need to check every property.
8910
8911 NOTE: in the event that BUG#37137 ever gets fixed, this extra check
8912 will still be valid because we would need to support old binary
8913 logs anyway.
8914
8915 @param rli The relay log info reference.
8916 @param table_list A list element containing the table to check against.
8917 @return OK_TO_PROCESS
8918 if there was no identifier already in rli->tables_to_lock
8919
8920 FILTERED_OUT
8921 if the event is filtered according to the filtering rules
8922
8923 SAME_ID_MAPPING_DIFFERENT_TABLE
8924 if the same identifier already maps a different table in
8925 rli->tables_to_lock
8926
8927 SAME_ID_MAPPING_SAME_TABLE
8928 if the same identifier already maps the same table in
8929 rli->tables_to_lock.
8930 */
8931 static enum_tbl_map_status
check_table_map(Relay_log_info const * rli,RPL_TABLE_LIST * table_list)8932 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
8933 {
8934 DBUG_ENTER("check_table_map");
8935 enum_tbl_map_status res= OK_TO_PROCESS;
8936
8937 if (rli->sql_thd->slave_thread /* filtering is for slave only */ &&
8938 (!rpl_filter->db_ok(table_list->db) ||
8939 (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
8940 res= FILTERED_OUT;
8941 else
8942 {
8943 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
8944 for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
8945 ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
8946 {
8947 if (ptr->table_id == table_list->table_id)
8948 {
8949
8950 if (strcmp(ptr->db, table_list->db) ||
8951 strcmp(ptr->alias, table_list->table_name) ||
8952 ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
8953 res= SAME_ID_MAPPING_DIFFERENT_TABLE;
8954 else
8955 res= SAME_ID_MAPPING_SAME_TABLE;
8956
8957 break;
8958 }
8959 }
8960 }
8961
8962 DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
8963
8964 DBUG_RETURN(res);
8965 }
8966
do_apply_event(Relay_log_info const * rli)8967 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
8968 {
8969 RPL_TABLE_LIST *table_list;
8970 char *db_mem, *tname_mem;
8971 size_t dummy_len;
8972 void *memory;
8973 DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
8974 DBUG_ASSERT(rli->sql_thd == thd);
8975
8976 /* Step the query id to mark what columns that are actually used. */
8977 thd->set_query_id(next_query_id());
8978
8979 if (!(memory= my_multi_malloc(MYF(MY_WME),
8980 &table_list, (uint) sizeof(RPL_TABLE_LIST),
8981 &db_mem, (uint) NAME_LEN + 1,
8982 &tname_mem, (uint) NAME_LEN + 1,
8983 NullS)))
8984 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
8985
8986 strmov(db_mem, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
8987 strmov(tname_mem, m_tblnam);
8988
8989 table_list->init_one_table(db_mem, strlen(db_mem),
8990 tname_mem, strlen(tname_mem),
8991 tname_mem, TL_WRITE);
8992
8993 table_list->table_id= DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id);
8994 table_list->updating= 1;
8995 table_list->required_type= FRMTYPE_TABLE;
8996 DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name, table_list->table_id));
8997 enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
8998 if (tblmap_status == OK_TO_PROCESS)
8999 {
9000 DBUG_ASSERT(thd->lex->query_tables != table_list);
9001
9002 /*
9003 Use placement new to construct the table_def instance in the
9004 memory allocated for it inside table_list.
9005
9006 The memory allocated by the table_def structure (i.e., not the
9007 memory allocated *for* the table_def structure) is released
9008 inside Relay_log_info::clear_tables_to_lock() by calling the
9009 table_def destructor explicitly.
9010 */
9011 new (&table_list->m_tabledef)
9012 table_def(m_coltype, m_colcnt,
9013 m_field_metadata, m_field_metadata_size,
9014 m_null_bits, m_flags);
9015 table_list->m_tabledef_valid= TRUE;
9016 table_list->m_conv_table= NULL;
9017 table_list->open_type= OT_BASE_ONLY;
9018
9019 /*
9020 We record in the slave's information that the table should be
9021 locked by linking the table into the list of tables to lock.
9022 */
9023 table_list->next_global= table_list->next_local= rli->tables_to_lock;
9024 const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
9025 const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
9026 /* 'memory' is freed in clear_tables_to_lock */
9027 }
9028 else // FILTERED_OUT, SAME_ID_MAPPING_*
9029 {
9030 /*
9031 If mapped already but with different properties, we raise an
9032 error.
9033 If mapped already but with same properties we skip the event.
9034 If filtered out we skip the event.
9035
9036 In all three cases, we need to free the memory previously
9037 allocated.
9038 */
9039 if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
9040 {
9041 /*
9042 Something bad has happened. We need to stop the slave as strange things
9043 could happen if we proceed: slave crash, wrong table being updated, ...
9044 As a consequence we push an error in this case.
9045 */
9046
9047 char buf[256];
9048
9049 my_snprintf(buf, sizeof(buf),
9050 "Found table map event mapping table id %u which "
9051 "was already mapped but with different settings.",
9052 table_list->table_id);
9053
9054 if (thd->slave_thread)
9055 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9056 ER(ER_SLAVE_FATAL_ERROR), buf);
9057 else
9058 /*
9059 For the cases in which a 'BINLOG' statement is set to
9060 execute in a user session
9061 */
9062 my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
9063 MYF(0), buf);
9064 }
9065
9066 my_free(memory);
9067 }
9068
9069 DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
9070 }
9071
9072 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)9073 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
9074 {
9075 /*
9076 If the slave skip counter is 1, then we should not start executing
9077 on the next event.
9078 */
9079 return continue_group(rli);
9080 }
9081
do_update_pos(Relay_log_info * rli)9082 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
9083 {
9084 rli->inc_event_relay_log_pos();
9085 return 0;
9086 }
9087
9088 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
9089
9090 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)9091 bool Table_map_log_event::write_data_header(IO_CACHE *file)
9092 {
9093 DBUG_ASSERT(m_table_id != ~0UL);
9094 uchar buf[TABLE_MAP_HEADER_LEN];
9095 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9096 {
9097 int4store(buf + 0, m_table_id);
9098 int2store(buf + 4, m_flags);
9099 return (my_b_safe_write(file, buf, 6));
9100 });
9101 int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
9102 int2store(buf + TM_FLAGS_OFFSET, m_flags);
9103 return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
9104 }
9105
write_data_body(IO_CACHE * file)9106 bool Table_map_log_event::write_data_body(IO_CACHE *file)
9107 {
9108 DBUG_ASSERT(m_dbnam != NULL);
9109 DBUG_ASSERT(m_tblnam != NULL);
9110
9111 DBUG_ASSERT(m_dblen <= NAME_LEN);
9112 DBUG_ASSERT(m_tbllen <= NAME_LEN);
9113
9114 uchar const dbuf[]= { (uchar) m_dblen };
9115 uchar const tbuf[]= { (uchar) m_tbllen };
9116
9117 uchar cbuf[sizeof(m_colcnt) + 1];
9118 uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
9119 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
9120
9121 /*
9122 Store the size of the field metadata.
9123 */
9124 uchar mbuf[sizeof(m_field_metadata_size)];
9125 uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
9126
9127 return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
9128 my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
9129 my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
9130 my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
9131 my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
9132 my_b_safe_write(file, m_coltype, m_colcnt) ||
9133 my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
9134 my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
9135 my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
9136 }
9137 #endif
9138
9139 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
9140
9141 /*
9142 Print some useful information for the SHOW BINARY LOG information
9143 field.
9144 */
9145
9146 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9147 void Table_map_log_event::pack_info(Protocol *protocol)
9148 {
9149 char buf[256];
9150 size_t bytes= my_snprintf(buf, sizeof(buf),
9151 "table_id: %lu (%s.%s)",
9152 m_table_id, m_dbnam, m_tblnam);
9153 protocol->store(buf, bytes, &my_charset_bin);
9154 }
9155 #endif
9156
9157
9158 #endif
9159
9160
9161 #ifdef MYSQL_CLIENT
print(FILE *,PRINT_EVENT_INFO * print_event_info)9162 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
9163 {
9164 if (!print_event_info->short_form)
9165 {
9166 print_header(&print_event_info->head_cache, print_event_info, TRUE);
9167 my_b_printf(&print_event_info->head_cache,
9168 "\tTable_map: `%s`.`%s` mapped to number %lu\n",
9169 m_dbnam, m_tblnam, m_table_id);
9170 print_base64(&print_event_info->body_cache, print_event_info, TRUE);
9171 }
9172 }
9173 #endif
9174
9175 /**************************************************************************
9176 Write_rows_log_event member functions
9177 **************************************************************************/
9178
9179 /*
9180 Constructor used to build an event for writing to the binary log.
9181 */
9182 #if !defined(MYSQL_CLIENT)
Write_rows_log_event(THD * thd_arg,TABLE * tbl_arg,ulong tid_arg,MY_BITMAP const * cols,bool is_transactional)9183 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
9184 ulong tid_arg,
9185 MY_BITMAP const *cols,
9186 bool is_transactional)
9187 : Rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional)
9188 {
9189 }
9190 #endif
9191
9192 /*
9193 Constructor used by slave to read the event from the binary log.
9194 */
9195 #ifdef HAVE_REPLICATION
Write_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)9196 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
9197 const Format_description_log_event
9198 *description_event)
9199 : Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
9200 {
9201 }
9202 #endif
9203
9204 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9205 int
do_before_row_operations(const Slave_reporting_capability * const)9206 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
9207 {
9208 int error= 0;
9209
9210 /*
9211 Increment the global status insert count variable
9212 */
9213 if (get_flags(STMT_END_F))
9214 status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
9215
9216 /**
9217 todo: to introduce a property for the event (handler?) which forces
9218 applying the event in the replace (idempotent) fashion.
9219 */
9220 if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
9221 (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
9222 {
9223 /*
9224 We are using REPLACE semantics and not INSERT IGNORE semantics
9225 when writing rows, that is: new rows replace old rows. We need to
9226 inform the storage engine that it should use this behaviour.
9227 */
9228
9229 /* Tell the storage engine that we are using REPLACE semantics. */
9230 thd->lex->duplicates= DUP_REPLACE;
9231
9232 /*
9233 Pretend we're executing a REPLACE command: this is needed for
9234 InnoDB and NDB Cluster since they are not (properly) checking the
9235 lex->duplicates flag.
9236 */
9237 thd->lex->sql_command= SQLCOM_REPLACE;
9238 /*
9239 Do not raise the error flag in case of hitting to an unique attribute
9240 */
9241 m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
9242 /*
9243 NDB specific: update from ndb master wrapped as Write_rows
9244 so that the event should be applied to replace slave's row
9245 */
9246 m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
9247 /*
9248 NDB specific: if update from ndb master wrapped as Write_rows
9249 does not find the row it's assumed idempotent binlog applying
9250 is taking place; don't raise the error.
9251 */
9252 m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
9253 /*
9254 TODO: the cluster team (Tomas?) says that it's better if the engine knows
9255 how many rows are going to be inserted, then it can allocate needed memory
9256 from the start.
9257 */
9258 }
9259
9260 /*
9261 We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
9262 any TIMESTAMP column with data from the row but instead will use
9263 the event's current time.
9264 As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
9265 columns, we know that all TIMESTAMP columns on slave will receive explicit
9266 data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
9267 When we allow a table without TIMESTAMP to be replicated to a table having
9268 more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
9269 column to be replicated into a BIGINT column and the slave's table has a
9270 TIMESTAMP column, then the slave's TIMESTAMP column will take its value
9271 from set_time() which we called earlier (consistent with SBR). And then in
9272 some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
9273 analyze if explicit data is provided for slave's TIMESTAMP columns).
9274 */
9275 m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
9276
9277 /* Honor next number column if present */
9278 m_table->next_number_field= m_table->found_next_number_field;
9279 /*
9280 * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
9281 * sequence numbers for auto_increment fields if the values of them are 0.
9282 * If generateing a sequence number is decided by the values of
9283 * table->auto_increment_field_not_null and SQL_MODE(if includes
9284 * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
9285 * SQL_MODE of slave sql thread is always consistency with master's.
9286 * In RBR, auto_increment fields never are NULL, except if the auto_inc
9287 * column exists only on the slave side (i.e., in an extra column
9288 * on the slave's table).
9289 */
9290 if (!is_auto_inc_in_extra_columns())
9291 m_table->auto_increment_field_not_null= TRUE;
9292 else
9293 {
9294 /*
9295 Here we have checked that there is an extra field
9296 on this server's table that has an auto_inc column.
9297
9298 Mark that the auto_increment field is null and mark
9299 the read and write set bits.
9300
9301 (There can only be one AUTO_INC column, it is always
9302 indexed and it cannot have a DEFAULT value).
9303 */
9304 m_table->auto_increment_field_not_null= FALSE;
9305 m_table->mark_auto_increment_column();
9306 }
9307
9308 return error;
9309 }
9310
9311 int
do_after_row_operations(const Slave_reporting_capability * const,int error)9312 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
9313 int error)
9314 {
9315 int local_error= 0;
9316
9317 /**
9318 Clear the write_set bit for auto_inc field that only
9319 existed on the destination table as an extra column.
9320 */
9321 if (is_auto_inc_in_extra_columns())
9322 {
9323 bitmap_clear_bit(m_table->write_set, m_table->next_number_field->field_index);
9324 bitmap_clear_bit( m_table->read_set, m_table->next_number_field->field_index);
9325
9326 if (get_flags(STMT_END_F))
9327 m_table->file->ha_release_auto_increment();
9328 }
9329 m_table->next_number_field=0;
9330 m_table->auto_increment_field_not_null= FALSE;
9331 if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
9332 m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
9333 {
9334 m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
9335 m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
9336 /*
9337 resetting the extra with
9338 table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
9339 fires bug#27077
9340 explanation: file->reset() performs this duty
9341 ultimately. Still todo: fix
9342 */
9343 }
9344 if ((local_error= m_table->file->ha_end_bulk_insert()))
9345 {
9346 m_table->file->print_error(local_error, MYF(0));
9347 }
9348 return error? error : local_error;
9349 }
9350
9351 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9352
9353 /*
9354 Check if there are more UNIQUE keys after the given key.
9355 */
9356 static int
last_uniq_key(TABLE * table,uint keyno)9357 last_uniq_key(TABLE *table, uint keyno)
9358 {
9359 while (++keyno < table->s->keys)
9360 if (table->key_info[keyno].flags & HA_NOSAME)
9361 return 0;
9362 return 1;
9363 }
9364
9365 /**
9366 Check if an error is a duplicate key error.
9367
9368 This function is used to check if an error code is one of the
9369 duplicate key error, i.e., and error code for which it is sensible
9370 to do a <code>get_dup_key()</code> to retrieve the duplicate key.
9371
9372 @param errcode The error code to check.
9373
9374 @return <code>true</code> if the error code is such that
9375 <code>get_dup_key()</code> will return true, <code>false</code>
9376 otherwise.
9377 */
9378 bool
is_duplicate_key_error(int errcode)9379 is_duplicate_key_error(int errcode)
9380 {
9381 switch (errcode)
9382 {
9383 case HA_ERR_FOUND_DUPP_KEY:
9384 case HA_ERR_FOUND_DUPP_UNIQUE:
9385 return true;
9386 }
9387 return false;
9388 }
9389
9390 /**
9391 Write the current row into event's table.
9392
9393 The row is located in the row buffer, pointed by @c m_curr_row member.
9394 Number of columns of the row is stored in @c m_width member (it can be
9395 different from the number of columns in the table to which we insert).
9396 Bitmap @c m_cols indicates which columns are present in the row. It is assumed
9397 that event's table is already open and pointed by @c m_table.
9398
9399 If the same record already exists in the table it can be either overwritten
9400 or an error is reported depending on the value of @c overwrite flag
9401 (error reporting not yet implemented). Note that the matching record can be
9402 different from the row we insert if we use primary keys to identify records in
9403 the table.
9404
9405 The row to be inserted can contain values only for selected columns. The
9406 missing columns are filled with default values using @c prepare_record()
9407 function. If a matching record is found in the table and @c overwritte is
9408 true, the missing columns are taken from it.
9409
9410 @param rli Relay log info (needed for row unpacking).
9411 @param overwrite
9412 Shall we overwrite if the row already exists or signal
9413 error (currently ignored).
9414
9415 @returns Error code on failure, 0 on success.
9416
9417 This method, if successful, sets @c m_curr_row_end pointer to point at the
9418 next row in the rows buffer. This is done when unpacking the row to be
9419 inserted.
9420
9421 @note If a matching record is found, it is either updated using
9422 @c ha_update_row() or first deleted and then new record written.
9423 */
9424
9425 int
write_row(const Relay_log_info * const rli,const bool overwrite)9426 Rows_log_event::write_row(const Relay_log_info *const rli,
9427 const bool overwrite)
9428 {
9429 DBUG_ENTER("write_row");
9430 DBUG_ASSERT(m_table != NULL && thd != NULL);
9431
9432 TABLE *table= m_table; // pointer to event's table
9433 int error;
9434 int UNINIT_VAR(keynum);
9435 auto_afree_ptr<char> key(NULL);
9436
9437 prepare_record(table, m_width,
9438 table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
9439
9440 /* unpack row into table->record[0] */
9441 if ((error= unpack_current_row(rli)))
9442 DBUG_RETURN(error);
9443
9444 if (m_curr_row == m_rows_buf)
9445 {
9446 /* this is the first row to be inserted, we estimate the rows with
9447 the size of the first row and use that value to initialize
9448 storage engine for bulk insertion */
9449 ulong estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
9450 m_table->file->ha_start_bulk_insert(estimated_rows);
9451 }
9452
9453 /*
9454 Explicitly set the auto_inc to null to make sure that
9455 it gets an auto_generated value.
9456 */
9457 if (is_auto_inc_in_extra_columns())
9458 m_table->next_number_field->set_null();
9459
9460 #ifndef DBUG_OFF
9461 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
9462 DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
9463 DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
9464 #endif
9465
9466 /*
9467 Try to write record. If a corresponding record already exists in the table,
9468 we try to change it using ha_update_row() if possible. Otherwise we delete
9469 it and repeat the whole process again.
9470
9471 TODO: Add safety measures against infinite looping.
9472 */
9473
9474 while ((error= table->file->ha_write_row(table->record[0])))
9475 {
9476 if (error == HA_ERR_LOCK_DEADLOCK ||
9477 error == HA_ERR_LOCK_WAIT_TIMEOUT ||
9478 (keynum= table->file->get_dup_key(error)) < 0 ||
9479 !overwrite)
9480 {
9481 DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
9482 /*
9483 Deadlock, waiting for lock or just an error from the handler
9484 such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
9485 Retrieval of the duplicate key number may fail
9486 - either because the error was not "duplicate key" error
9487 - or because the information which key is not available
9488 */
9489 table->file->print_error(error, MYF(0));
9490 DBUG_RETURN(error);
9491 }
9492 /*
9493 We need to retrieve the old row into record[1] to be able to
9494 either update or delete the offending record. We either:
9495
9496 - use rnd_pos() with a row-id (available as dupp_row) to the
9497 offending row, if that is possible (MyISAM and Blackhole), or else
9498
9499 - use index_read_idx() with the key that is duplicated, to
9500 retrieve the offending row.
9501 */
9502 if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
9503 {
9504 DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
9505 error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
9506 if (error)
9507 {
9508 DBUG_PRINT("info",("rnd_pos() returns error %d",error));
9509 if (error == HA_ERR_RECORD_DELETED)
9510 error= HA_ERR_KEY_NOT_FOUND;
9511 table->file->print_error(error, MYF(0));
9512 DBUG_RETURN(error);
9513 }
9514 }
9515 else
9516 {
9517 DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
9518
9519 if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
9520 {
9521 DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
9522 DBUG_RETURN(my_errno);
9523 }
9524
9525 if (key.get() == NULL)
9526 {
9527 key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
9528 if (key.get() == NULL)
9529 {
9530 DBUG_PRINT("info",("Can't allocate key buffer"));
9531 DBUG_RETURN(ENOMEM);
9532 }
9533 }
9534
9535 key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
9536 0);
9537 error= table->file->index_read_idx_map(table->record[1], keynum,
9538 (const uchar*)key.get(),
9539 HA_WHOLE_KEY,
9540 HA_READ_KEY_EXACT);
9541 if (error)
9542 {
9543 DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error)));
9544 if (error == HA_ERR_RECORD_DELETED)
9545 error= HA_ERR_KEY_NOT_FOUND;
9546 table->file->print_error(error, MYF(0));
9547 DBUG_RETURN(error);
9548 }
9549 }
9550
9551 /*
9552 Now, record[1] should contain the offending row. That
9553 will enable us to update it or, alternatively, delete it (so
9554 that we can insert the new row afterwards).
9555 */
9556
9557 /*
9558 If row is incomplete we will use the record found to fill
9559 missing columns.
9560 */
9561 if (!get_flags(COMPLETE_ROWS_F))
9562 {
9563 restore_record(table,record[1]);
9564 error= unpack_current_row(rli);
9565 }
9566
9567 #ifndef DBUG_OFF
9568 DBUG_PRINT("debug",("preparing for update: before and after image"));
9569 DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
9570 DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
9571 #endif
9572
9573 /*
9574 REPLACE is defined as either INSERT or DELETE + INSERT. If
9575 possible, we can replace it with an UPDATE, but that will not
9576 work on InnoDB if FOREIGN KEY checks are necessary.
9577
9578 I (Matz) am not sure of the reason for the last_uniq_key()
9579 check as, but I'm guessing that it's something along the
9580 following lines.
9581
9582 Suppose that we got the duplicate key to be a key that is not
9583 the last unique key for the table and we perform an update:
9584 then there might be another key for which the unique check will
9585 fail, so we're better off just deleting the row and inserting
9586 the correct row.
9587 */
9588 if (last_uniq_key(table, keynum) &&
9589 !table->file->referenced_by_foreign_key())
9590 {
9591 DBUG_PRINT("info",("Updating row using ha_update_row()"));
9592 error=table->file->ha_update_row(table->record[1],
9593 table->record[0]);
9594 switch (error) {
9595
9596 case HA_ERR_RECORD_IS_THE_SAME:
9597 DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
9598 " ha_update_row()"));
9599 error= 0;
9600
9601 case 0:
9602 break;
9603
9604 default:
9605 DBUG_PRINT("info",("ha_update_row() returns error %d",error));
9606 table->file->print_error(error, MYF(0));
9607 }
9608
9609 DBUG_RETURN(error);
9610 }
9611 else
9612 {
9613 DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
9614 if ((error= table->file->ha_delete_row(table->record[1])))
9615 {
9616 DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
9617 table->file->print_error(error, MYF(0));
9618 DBUG_RETURN(error);
9619 }
9620 /* Will retry ha_write_row() with the offending row removed. */
9621 }
9622 }
9623
9624 DBUG_RETURN(error);
9625 }
9626
9627 #endif
9628
9629 int
do_exec_row(const Relay_log_info * const rli)9630 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
9631 {
9632 DBUG_ASSERT(m_table != NULL);
9633 int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
9634
9635 if (error && !thd->is_error())
9636 {
9637 DBUG_ASSERT(0);
9638 my_error(ER_UNKNOWN_ERROR, MYF(0));
9639 }
9640
9641 return error;
9642 }
9643
9644 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
9645
9646 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)9647 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
9648 {
9649 DBUG_EXECUTE_IF("simulate_cache_read_error",
9650 {DBUG_SET("+d,simulate_my_b_fill_error");});
9651 Rows_log_event::print_helper(file, print_event_info, "Write_rows");
9652 }
9653 #endif
9654
9655 /**************************************************************************
9656 Delete_rows_log_event member functions
9657 **************************************************************************/
9658
9659 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9660 /*
9661 Compares table->record[0] and table->record[1]
9662
9663 Returns TRUE if different.
9664 */
record_compare(TABLE * table)9665 static bool record_compare(TABLE *table)
9666 {
9667 /*
9668 Need to set the X bit and the filler bits in both records since
9669 there are engines that do not set it correctly.
9670
9671 In addition, since MyISAM checks that one hasn't tampered with the
9672 record, it is necessary to restore the old bytes into the record
9673 after doing the comparison.
9674
9675 TODO[record format ndb]: Remove it once NDB returns correct
9676 records. Check that the other engines also return correct records.
9677 */
9678
9679 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
9680 DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
9681
9682 bool result= FALSE;
9683 uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
9684
9685 if (table->s->null_bytes > 0)
9686 {
9687 for (int i = 0 ; i < 2 ; ++i)
9688 {
9689 /*
9690 If we have an X bit then we need to take care of it.
9691 */
9692 if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
9693 {
9694 saved_x[i]= table->record[i][0];
9695 table->record[i][0]|= 1U;
9696 }
9697
9698 /*
9699 If (last_null_bit_pos == 0 && null_bytes > 1), then:
9700
9701 X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
9702
9703 Ie, the entire byte is used.
9704 */
9705 if (table->s->last_null_bit_pos > 0)
9706 {
9707 saved_filler[i]= table->record[i][table->s->null_bytes - 1];
9708 table->record[i][table->s->null_bytes - 1]|=
9709 256U - (1U << table->s->last_null_bit_pos);
9710 }
9711 }
9712 }
9713
9714 /**
9715 Compare full record only if:
9716 - there are no blob fields (otherwise we would also need
9717 to compare blobs contents as well);
9718 - there are no varchar fields (otherwise we would also need
9719 to compare varchar contents as well);
9720 - there are no null fields, otherwise NULLed fields
9721 contents (i.e., the don't care bytes) may show arbitrary
9722 values, depending on how each engine handles internally.
9723 */
9724 if ((table->s->blob_fields +
9725 table->s->varchar_fields +
9726 table->s->null_fields) == 0)
9727 {
9728 result= cmp_record(table,record[1]);
9729 goto record_compare_exit;
9730 }
9731
9732 /* Compare null bits */
9733 if (memcmp(table->null_flags,
9734 table->null_flags+table->s->rec_buff_length,
9735 table->s->null_bytes))
9736 {
9737 result= TRUE; // Diff in NULL value
9738 goto record_compare_exit;
9739 }
9740
9741 /* Compare fields */
9742 for (Field **ptr=table->field ; *ptr ; ptr++)
9743 {
9744
9745 /**
9746 We only compare field contents that are not null.
9747 NULL fields (i.e., their null bits) were compared
9748 earlier.
9749 */
9750 if (!(*(ptr))->is_null())
9751 {
9752 if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
9753 {
9754 result= TRUE;
9755 goto record_compare_exit;
9756 }
9757 }
9758 }
9759
9760 record_compare_exit:
9761 /*
9762 Restore the saved bytes.
9763
9764 TODO[record format ndb]: Remove this code once NDB returns the
9765 correct record format.
9766 */
9767 if (table->s->null_bytes > 0)
9768 {
9769 for (int i = 0 ; i < 2 ; ++i)
9770 {
9771 if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
9772 table->record[i][0]= saved_x[i];
9773
9774 if (table->s->last_null_bit_pos)
9775 table->record[i][table->s->null_bytes - 1]= saved_filler[i];
9776 }
9777 }
9778
9779 return result;
9780 }
9781
9782 /*
9783 Check if we are already spending too much time on this statement.
9784 if we are, warn user that it might be because table does not have
9785 a PK, but only if the warning was not printed before for this STMT.
9786
9787 @param type The event type code.
9788 @param table_name The name of the table that the slave is
9789 operating.
9790 @param is_index_scan States whether the slave is doing an index scan
9791 or not.
9792 @param rli The relay metadata info.
9793 */
9794 static inline
issue_long_find_row_warning(Log_event_type type,const char * table_name,bool is_index_scan,const Relay_log_info * rli)9795 void issue_long_find_row_warning(Log_event_type type,
9796 const char *table_name,
9797 bool is_index_scan,
9798 const Relay_log_info *rli)
9799 {
9800 if ((global_system_variables.log_warnings > 1 &&
9801 !const_cast<Relay_log_info*>(rli)->is_long_find_row_note_printed()))
9802 {
9803 time_t now= my_time(0);
9804 time_t stmt_ts= const_cast<Relay_log_info*>(rli)->get_row_stmt_start_timestamp();
9805
9806 DBUG_EXECUTE_IF("inject_long_find_row_note",
9807 stmt_ts-=(LONG_FIND_ROW_THRESHOLD*2););
9808
9809 long delta= (long) (now - stmt_ts);
9810
9811 if (delta > LONG_FIND_ROW_THRESHOLD)
9812 {
9813 const_cast<Relay_log_info*>(rli)->set_long_find_row_note_printed();
9814 const char* evt_type= type == DELETE_ROWS_EVENT ? " DELETE" : "n UPDATE";
9815 const char* scan_type= is_index_scan ? "scanning an index" : "scanning the table";
9816
9817 sql_print_information("The slave is applying a ROW event on behalf of a%s statement "
9818 "on table %s and is currently taking a considerable amount "
9819 "of time (%ld seconds). This is due to the fact that it is %s "
9820 "while looking up records to be processed. Consider adding a "
9821 "primary key (or unique key) to the table to improve "
9822 "performance.", evt_type, table_name, delta, scan_type);
9823 }
9824 }
9825 }
9826
9827 /**
9828 Locate the current row in event's table.
9829
9830 The current row is pointed by @c m_curr_row. Member @c m_width tells how many
9831 columns are there in the row (this can be differnet from the number of columns
9832 in the table). It is assumed that event's table is already open and pointed
9833 by @c m_table.
9834
9835 If a corresponding record is found in the table it is stored in
9836 @c m_table->record[0]. Note that when record is located based on a primary
9837 key, it is possible that the record found differs from the row being located.
9838
9839 If no key is specified or table does not have keys, a table scan is used to
9840 find the row. In that case the row should be complete and contain values for
9841 all columns. However, it can still be shorter than the table, i.e. the table
9842 can contain extra columns not present in the row. It is also possible that
9843 the table has fewer columns than the row being located.
9844
9845 @returns Error code on failure, 0 on success.
9846
9847 @post In case of success @c m_table->record[0] contains the record found.
9848 Also, the internal "cursor" of the table is positioned at the record found.
9849
9850 @note If the engine allows random access of the records, a combination of
9851 @c position() and @c rnd_pos() will be used.
9852 */
9853
find_row(const Relay_log_info * rli)9854 int Rows_log_event::find_row(const Relay_log_info *rli)
9855 {
9856 DBUG_ENTER("Rows_log_event::find_row");
9857
9858 DBUG_ASSERT(m_table && m_table->in_use != NULL);
9859
9860 TABLE *table= m_table;
9861 int error= 0;
9862 bool is_table_scan= false, is_index_scan= false;
9863
9864 /*
9865 rpl_row_tabledefs.test specifies that
9866 if the extra field on the slave does not have a default value
9867 and this is okay with Delete or Update events.
9868 Todo: fix wl3228 hld that requires defauls for all types of events
9869 */
9870
9871 prepare_record(table, m_width, FALSE);
9872 error= unpack_current_row(rli);
9873
9874 #ifndef DBUG_OFF
9875 DBUG_PRINT("info",("looking for the following record"));
9876 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
9877 #endif
9878
9879 if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
9880 table->s->primary_key < MAX_KEY)
9881 {
9882 /*
9883 Use a more efficient method to fetch the record given by
9884 table->record[0] if the engine allows it. We first compute a
9885 row reference using the position() member function (it will be
9886 stored in table->file->ref) and the use rnd_pos() to position
9887 the "cursor" (i.e., record[0] in this case) at the correct row.
9888
9889 TODO: Add a check that the correct record has been fetched by
9890 comparing with the original record. Take into account that the
9891 record on the master and slave can be of different
9892 length. Something along these lines should work:
9893
9894 ADD>>> store_record(table,record[1]);
9895 int error= table->file->rnd_pos(table->record[0], table->file->ref);
9896 ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
9897 table->s->reclength) == 0);
9898
9899 */
9900 DBUG_PRINT("info",("locating record using primary key (position)"));
9901 int error= table->file->rnd_pos_by_record(table->record[0]);
9902 if (error)
9903 {
9904 DBUG_PRINT("info",("rnd_pos returns error %d",error));
9905 if (error == HA_ERR_RECORD_DELETED)
9906 error= HA_ERR_KEY_NOT_FOUND;
9907 table->file->print_error(error, MYF(0));
9908 }
9909 DBUG_RETURN(error);
9910 }
9911
9912 // We can't use position() - try other methods.
9913
9914 /*
9915 We need to retrieve all fields
9916 TODO: Move this out from this function to main loop
9917 */
9918 table->use_all_columns();
9919
9920 /*
9921 Save copy of the record in table->record[1]. It might be needed
9922 later if linear search is used to find exact match.
9923 */
9924 store_record(table,record[1]);
9925
9926 if (table->s->keys > 0 && table->s->keys_in_use.is_set(0))
9927 {
9928 DBUG_PRINT("info",("locating record using primary key (index_read)"));
9929
9930 /* The 0th key is active: search the table using the index */
9931 if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
9932 {
9933 DBUG_PRINT("info",("ha_index_init returns error %d",error));
9934 table->file->print_error(error, MYF(0));
9935 goto err;
9936 }
9937
9938 /* Fill key data for the row */
9939
9940 DBUG_ASSERT(m_key);
9941 key_copy(m_key, table->record[0], table->key_info, 0);
9942
9943 /*
9944 Don't print debug messages when running valgrind since they can
9945 trigger false warnings.
9946 */
9947 #ifndef HAVE_purify
9948 DBUG_DUMP("key data", m_key, table->key_info->key_length);
9949 #endif
9950
9951 /*
9952 We need to set the null bytes to ensure that the filler bit are
9953 all set when returning. There are storage engines that just set
9954 the necessary bits on the bytes and don't set the filler bits
9955 correctly.
9956 */
9957 if (table->s->null_bytes > 0)
9958 table->record[0][table->s->null_bytes - 1]|=
9959 256U - (1U << table->s->last_null_bit_pos);
9960
9961 if ((error= table->file->index_read_map(table->record[0], m_key,
9962 HA_WHOLE_KEY,
9963 HA_READ_KEY_EXACT)))
9964 {
9965 DBUG_PRINT("info",("no record matching the key found in the table"));
9966 if (error == HA_ERR_RECORD_DELETED)
9967 error= HA_ERR_KEY_NOT_FOUND;
9968 table->file->print_error(error, MYF(0));
9969 table->file->ha_index_end();
9970 goto err;
9971 }
9972
9973 /*
9974 Don't print debug messages when running valgrind since they can
9975 trigger false warnings.
9976 */
9977 #ifndef HAVE_purify
9978 DBUG_PRINT("info",("found first matching record"));
9979 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
9980 #endif
9981 /*
9982 Below is a minor "optimization". If the key (i.e., key number
9983 0) has the HA_NOSAME flag set, we know that we have found the
9984 correct record (since there can be no duplicates); otherwise, we
9985 have to compare the record with the one found to see if it is
9986 the correct one.
9987
9988 CAVEAT! This behaviour is essential for the replication of,
9989 e.g., the mysql.proc table since the correct record *shall* be
9990 found using the primary key *only*. There shall be no
9991 comparison of non-PK columns to decide if the correct record is
9992 found. I can see no scenario where it would be incorrect to
9993 chose the row to change only using a PK or an UNNI.
9994 */
9995 if (table->key_info->flags & HA_NOSAME)
9996 {
9997 /* Unique does not have non nullable part */
9998 if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
9999 {
10000 table->file->ha_index_end();
10001 goto ok;
10002 }
10003 else
10004 {
10005 KEY *keyinfo= table->key_info;
10006 /*
10007 Unique has nullable part. We need to check if there is any field in the
10008 BI image that is null and part of UNNI.
10009 */
10010 bool null_found= FALSE;
10011 for (uint i=0; i < keyinfo->key_parts && !null_found; i++)
10012 {
10013 uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
10014 Field **f= table->field+fieldnr;
10015 null_found= (*f)->is_null();
10016 }
10017
10018 if (!null_found)
10019 {
10020 table->file->ha_index_end();
10021 goto ok;
10022 }
10023
10024 /* else fall through to index scan */
10025 }
10026 }
10027
10028 is_index_scan=true;
10029
10030 /*
10031 In case key is not unique, we still have to iterate over records found
10032 and find the one which is identical to the row given. A copy of the
10033 record we are looking for is stored in record[1].
10034 */
10035 DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10036
10037 while (record_compare(table))
10038 {
10039 /*
10040 We need to set the null bytes to ensure that the filler bit
10041 are all set when returning. There are storage engines that
10042 just set the necessary bits on the bytes and don't set the
10043 filler bits correctly.
10044
10045 TODO[record format ndb]: Remove this code once NDB returns the
10046 correct record format.
10047 */
10048 if (table->s->null_bytes > 0)
10049 {
10050 table->record[0][table->s->null_bytes - 1]|=
10051 256U - (1U << table->s->last_null_bit_pos);
10052 }
10053
10054 while ((error= table->file->index_next(table->record[0])))
10055 {
10056 /* We just skip records that has already been deleted */
10057 if (error == HA_ERR_RECORD_DELETED)
10058 continue;
10059 DBUG_PRINT("info",("no record matching the given row found"));
10060 table->file->print_error(error, MYF(0));
10061 table->file->ha_index_end();
10062 goto err;
10063 }
10064 }
10065
10066 /*
10067 Have to restart the scan to be able to fetch the next row.
10068 */
10069 table->file->ha_index_end();
10070 }
10071 else
10072 {
10073 DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
10074
10075 int restart_count= 0; // Number of times scanning has restarted from top
10076
10077 /* We don't have a key: search the table using rnd_next() */
10078 if ((error= table->file->ha_rnd_init(1)))
10079 {
10080 DBUG_PRINT("info",("error initializing table scan"
10081 " (ha_rnd_init returns %d)",error));
10082 table->file->print_error(error, MYF(0));
10083 goto err;
10084 }
10085
10086 is_table_scan= true;
10087
10088 /* Continue until we find the right record or have made a full loop */
10089 do
10090 {
10091 restart_rnd_next:
10092 error= table->file->rnd_next(table->record[0]);
10093
10094 if (error)
10095 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10096 switch (error) {
10097
10098 case 0:
10099 break;
10100
10101 /*
10102 If the record was deleted, we pick the next one without doing
10103 any comparisons.
10104 */
10105 case HA_ERR_RECORD_DELETED:
10106 goto restart_rnd_next;
10107
10108 case HA_ERR_END_OF_FILE:
10109 if (++restart_count < 2)
10110 {
10111 if ((error= table->file->ha_rnd_init(1)))
10112 {
10113 table->file->print_error(error, MYF(0));
10114 goto err;
10115 }
10116 goto restart_rnd_next;
10117 }
10118 break;
10119
10120 default:
10121 DBUG_PRINT("info", ("Failed to get next record"
10122 " (rnd_next returns %d)",error));
10123 table->file->print_error(error, MYF(0));
10124 (void) table->file->ha_rnd_end();
10125 goto err;
10126 }
10127 }
10128 while (restart_count < 2 && record_compare(table));
10129
10130 /*
10131 Note: above record_compare will take into accout all record fields
10132 which might be incorrect in case a partial row was given in the event
10133 */
10134
10135 /*
10136 Have to restart the scan to be able to fetch the next row.
10137 */
10138 if (restart_count == 2)
10139 DBUG_PRINT("info", ("Record not found"));
10140 else
10141 DBUG_DUMP("record found", table->record[0], table->s->reclength);
10142 table->file->ha_rnd_end();
10143
10144 DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
10145 goto err;
10146 }
10147 ok:
10148 if (is_table_scan || is_index_scan)
10149 issue_long_find_row_warning(get_type_code(), m_table->alias,
10150 is_index_scan, rli);
10151
10152 table->default_column_bitmaps();
10153 DBUG_RETURN(0);
10154
10155 err:
10156 if (is_table_scan || is_index_scan)
10157 issue_long_find_row_warning(get_type_code(), m_table->alias,
10158 is_index_scan, rli);
10159
10160 table->default_column_bitmaps();
10161 DBUG_RETURN(error);
10162 }
10163
10164 #endif
10165
10166 /*
10167 Constructor used to build an event for writing to the binary log.
10168 */
10169
10170 #ifndef MYSQL_CLIENT
Delete_rows_log_event(THD * thd_arg,TABLE * tbl_arg,ulong tid,MY_BITMAP const * cols,bool is_transactional)10171 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
10172 ulong tid, MY_BITMAP const *cols,
10173 bool is_transactional)
10174 : Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
10175 {
10176 }
10177 #endif /* #if !defined(MYSQL_CLIENT) */
10178
10179 /*
10180 Constructor used by slave to read the event from the binary log.
10181 */
10182 #ifdef HAVE_REPLICATION
Delete_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)10183 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
10184 const Format_description_log_event
10185 *description_event)
10186 : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
10187 {
10188 }
10189 #endif
10190
10191 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10192
10193 int
do_before_row_operations(const Slave_reporting_capability * const)10194 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
10195 {
10196 /*
10197 Increment the global status delete count variable
10198 */
10199 if (get_flags(STMT_END_F))
10200 status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
10201
10202 if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
10203 m_table->s->primary_key < MAX_KEY)
10204 {
10205 /*
10206 We don't need to allocate any memory for m_key since it is not used.
10207 */
10208 return 0;
10209 }
10210
10211 if (m_table->s->keys > 0)
10212 {
10213 // Allocate buffer for key searches
10214 m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
10215 if (!m_key)
10216 return HA_ERR_OUT_OF_MEM;
10217 }
10218 return 0;
10219 }
10220
10221 int
do_after_row_operations(const Slave_reporting_capability * const,int error)10222 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
10223 int error)
10224 {
10225 /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
10226 m_table->file->ha_index_or_rnd_end();
10227 my_free(m_key);
10228 m_key= NULL;
10229
10230 return error;
10231 }
10232
do_exec_row(const Relay_log_info * const rli)10233 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
10234 {
10235 int error;
10236 DBUG_ASSERT(m_table != NULL);
10237
10238 if (!(error= find_row(rli)))
10239 {
10240 /*
10241 Delete the record found, located in record[0]
10242 */
10243 error= m_table->file->ha_delete_row(m_table->record[0]);
10244 }
10245 return error;
10246 }
10247
10248 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
10249
10250 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)10251 void Delete_rows_log_event::print(FILE *file,
10252 PRINT_EVENT_INFO* print_event_info)
10253 {
10254 Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
10255 }
10256 #endif
10257
10258
10259 /**************************************************************************
10260 Update_rows_log_event member functions
10261 **************************************************************************/
10262
10263 /*
10264 Constructor used to build an event for writing to the binary log.
10265 */
10266 #if !defined(MYSQL_CLIENT)
Update_rows_log_event(THD * thd_arg,TABLE * tbl_arg,ulong tid,MY_BITMAP const * cols_bi,MY_BITMAP const * cols_ai,bool is_transactional)10267 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
10268 ulong tid,
10269 MY_BITMAP const *cols_bi,
10270 MY_BITMAP const *cols_ai,
10271 bool is_transactional)
10272 : Rows_log_event(thd_arg, tbl_arg, tid, cols_bi, is_transactional)
10273 {
10274 init(cols_ai);
10275 }
10276
Update_rows_log_event(THD * thd_arg,TABLE * tbl_arg,ulong tid,MY_BITMAP const * cols,bool is_transactional)10277 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
10278 ulong tid,
10279 MY_BITMAP const *cols,
10280 bool is_transactional)
10281 : Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
10282 {
10283 init(cols);
10284 }
10285
init(MY_BITMAP const * cols)10286 void Update_rows_log_event::init(MY_BITMAP const *cols)
10287 {
10288 /* if bitmap_init fails, caught in is_valid() */
10289 if (likely(!bitmap_init(&m_cols_ai,
10290 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
10291 m_width,
10292 false)))
10293 {
10294 /* Cols can be zero if this is a dummy binrows event */
10295 if (likely(cols != NULL))
10296 {
10297 memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
10298 create_last_word_mask(&m_cols_ai);
10299 }
10300 }
10301 }
10302 #endif /* !defined(MYSQL_CLIENT) */
10303
10304
~Update_rows_log_event()10305 Update_rows_log_event::~Update_rows_log_event()
10306 {
10307 if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
10308 m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
10309 bitmap_free(&m_cols_ai); // To pair with bitmap_init().
10310 }
10311
10312
10313 /*
10314 Constructor used by slave to read the event from the binary log.
10315 */
10316 #ifdef HAVE_REPLICATION
Update_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)10317 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
10318 const
10319 Format_description_log_event
10320 *description_event)
10321 : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
10322 {
10323 }
10324 #endif
10325
10326 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10327
10328 int
do_before_row_operations(const Slave_reporting_capability * const)10329 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
10330 {
10331 /*
10332 Increment the global status update count variable
10333 */
10334 if (get_flags(STMT_END_F))
10335 status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
10336
10337 if (m_table->s->keys > 0)
10338 {
10339 // Allocate buffer for key searches
10340 m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
10341 if (!m_key)
10342 return HA_ERR_OUT_OF_MEM;
10343 }
10344
10345 m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
10346
10347 return 0;
10348 }
10349
10350 int
do_after_row_operations(const Slave_reporting_capability * const,int error)10351 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
10352 int error)
10353 {
10354 /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
10355 m_table->file->ha_index_or_rnd_end();
10356 my_free(m_key); // Free for multi_malloc
10357 m_key= NULL;
10358
10359 return error;
10360 }
10361
10362 int
do_exec_row(const Relay_log_info * const rli)10363 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
10364 {
10365 DBUG_ASSERT(m_table != NULL);
10366
10367 int error= find_row(rli);
10368 if (error)
10369 {
10370 /*
10371 We need to read the second image in the event of error to be
10372 able to skip to the next pair of updates
10373 */
10374 m_curr_row= m_curr_row_end;
10375 unpack_current_row(rli);
10376 return error;
10377 }
10378
10379 /*
10380 This is the situation after locating BI:
10381
10382 ===|=== before image ====|=== after image ===|===
10383 ^ ^
10384 m_curr_row m_curr_row_end
10385
10386 BI found in the table is stored in record[0]. We copy it to record[1]
10387 and unpack AI to record[0].
10388 */
10389
10390 store_record(m_table,record[1]);
10391
10392 m_curr_row= m_curr_row_end;
10393 /* this also updates m_curr_row_end */
10394 if ((error= unpack_current_row(rli)))
10395 return error;
10396
10397 /*
10398 Now we have the right row to update. The old row (the one we're
10399 looking for) is in record[1] and the new row is in record[0].
10400 */
10401 #ifndef HAVE_purify
10402 /*
10403 Don't print debug messages when running valgrind since they can
10404 trigger false warnings.
10405 */
10406 DBUG_PRINT("info",("Updating row in table"));
10407 DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
10408 DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
10409 #endif
10410
10411 error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
10412 if (error == HA_ERR_RECORD_IS_THE_SAME)
10413 error= 0;
10414
10415 return error;
10416 }
10417
10418 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
10419
10420 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)10421 void Update_rows_log_event::print(FILE *file,
10422 PRINT_EVENT_INFO* print_event_info)
10423 {
10424 Rows_log_event::print_helper(file, print_event_info, "Update_rows");
10425 }
10426 #endif
10427
10428
Incident_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)10429 Incident_log_event::Incident_log_event(const char *buf, uint event_len,
10430 const Format_description_log_event *descr_event)
10431 : Log_event(buf, descr_event)
10432 {
10433 DBUG_ENTER("Incident_log_event::Incident_log_event");
10434 uint8 const common_header_len=
10435 descr_event->common_header_len;
10436 uint8 const post_header_len=
10437 descr_event->post_header_len[INCIDENT_EVENT-1];
10438
10439 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
10440 event_len, common_header_len, post_header_len));
10441
10442 int incident_number= uint2korr(buf + common_header_len);
10443 if (incident_number >= INCIDENT_COUNT ||
10444 incident_number <= INCIDENT_NONE)
10445 {
10446 // If the incident is not recognized, this binlog event is
10447 // invalid. If we set incident_number to INCIDENT_NONE, the
10448 // invalidity will be detected by is_valid().
10449 m_incident= INCIDENT_NONE;
10450 DBUG_VOID_RETURN;
10451 }
10452 m_incident= static_cast<Incident>(incident_number);
10453 char const *ptr= buf + common_header_len + post_header_len;
10454 char const *const str_end= buf + event_len;
10455 uint8 len= 0; // Assignment to keep compiler happy
10456 const char *str= NULL; // Assignment to keep compiler happy
10457 read_str(&ptr, str_end, &str, &len);
10458 m_message.str= const_cast<char*>(str);
10459 m_message.length= len;
10460 DBUG_PRINT("info", ("m_incident: %d", m_incident));
10461 DBUG_VOID_RETURN;
10462 }
10463
10464
~Incident_log_event()10465 Incident_log_event::~Incident_log_event()
10466 {
10467 }
10468
10469
10470 const char *
description() const10471 Incident_log_event::description() const
10472 {
10473 static const char *const description[]= {
10474 "NOTHING", // Not used
10475 "LOST_EVENTS"
10476 };
10477
10478 DBUG_PRINT("info", ("m_incident: %d", m_incident));
10479
10480 return description[m_incident];
10481 }
10482
10483
10484 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)10485 void Incident_log_event::pack_info(Protocol *protocol)
10486 {
10487 char buf[256];
10488 size_t bytes;
10489 if (m_message.length > 0)
10490 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
10491 m_incident, description());
10492 else
10493 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
10494 m_incident, description(), m_message.str);
10495 protocol->store(buf, bytes, &my_charset_bin);
10496 }
10497 #endif
10498
10499
10500 #ifdef MYSQL_CLIENT
10501 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)10502 Incident_log_event::print(FILE *file,
10503 PRINT_EVENT_INFO *print_event_info)
10504 {
10505 if (print_event_info->short_form)
10506 return;
10507
10508 Write_on_release_cache cache(&print_event_info->head_cache, file);
10509 print_header(&cache, print_event_info, FALSE);
10510 my_b_printf(&cache, "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n", description());
10511 }
10512 #endif
10513
10514 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10515 int
do_apply_event(Relay_log_info const * rli)10516 Incident_log_event::do_apply_event(Relay_log_info const *rli)
10517 {
10518 DBUG_ENTER("Incident_log_event::do_apply_event");
10519 rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
10520 ER(ER_SLAVE_INCIDENT),
10521 description(),
10522 m_message.length > 0 ? m_message.str : "<none>");
10523 DBUG_RETURN(1);
10524 }
10525 #endif
10526
10527 bool
write_data_header(IO_CACHE * file)10528 Incident_log_event::write_data_header(IO_CACHE *file)
10529 {
10530 DBUG_ENTER("Incident_log_event::write_data_header");
10531 DBUG_PRINT("enter", ("m_incident: %d", m_incident));
10532 uchar buf[sizeof(int16)];
10533 int2store(buf, (int16) m_incident);
10534 DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
10535 }
10536
10537 bool
write_data_body(IO_CACHE * file)10538 Incident_log_event::write_data_body(IO_CACHE *file)
10539 {
10540 DBUG_ENTER("Incident_log_event::write_data_body");
10541 DBUG_RETURN(write_str(file, m_message.str, (uint) m_message.length));
10542 }
10543
10544
10545 #ifdef MYSQL_CLIENT
10546 /**
10547 The default values for these variables should be values that are
10548 *incorrect*, i.e., values that cannot occur in an event. This way,
10549 they will always be printed for the first event.
10550 */
st_print_event_info()10551 st_print_event_info::st_print_event_info()
10552 :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
10553 auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
10554 lc_time_names_number(~0),
10555 charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
10556 thread_id(0), thread_id_printed(false),
10557 base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
10558 {
10559 /*
10560 Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
10561 program's startup, but these explicit bzero() is for the day someone
10562 creates dynamic instances.
10563 */
10564 bzero(db, sizeof(db));
10565 bzero(charset, sizeof(charset));
10566 bzero(time_zone_str, sizeof(time_zone_str));
10567 delimiter[0]= ';';
10568 delimiter[1]= 0;
10569 myf const flags = MYF(MY_WME | MY_NABP);
10570 open_cached_file(&head_cache, NULL, NULL, 0, flags);
10571 open_cached_file(&body_cache, NULL, NULL, 0, flags);
10572 }
10573 #endif
10574
10575
10576 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)10577 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
10578 const Format_description_log_event* description_event)
10579 :Log_event(buf, description_event)
10580 {
10581 uint8 header_size= description_event->common_header_len;
10582 ident_len = event_len - header_size;
10583 set_if_smaller(ident_len,FN_REFLEN-1);
10584 log_ident= buf + header_size;
10585 }
10586 #endif
10587
10588 #ifdef MYSQL_SERVER
10589 /*
10590 This is a utility function that adds a quoted identifier into the a buffer.
10591 This also escapes any existance of the quote string inside the identifier.
10592
10593 SYNOPSIS
10594 my_strmov_quoted_identifier
10595 thd thread handler
10596 buffer target buffer
10597 identifier the identifier to be quoted
10598 length length of the identifier
10599 */
my_strmov_quoted_identifier(THD * thd,char * buffer,const char * identifier,uint length)10600 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
10601 const char* identifier,
10602 uint length)
10603 {
10604 int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
10605 return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
10606 }
10607 #else
my_strmov_quoted_identifier(char * buffer,const char * identifier)10608 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier)
10609 {
10610 int q= '`';
10611 return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
10612 }
10613
10614 #endif
10615
my_strmov_quoted_identifier_helper(int q,char * buffer,const char * identifier,uint length)10616 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
10617 const char* identifier,
10618 uint length)
10619 {
10620 size_t written= 0;
10621 char quote_char;
10622 uint id_length= (length) ? length : strlen(identifier);
10623
10624 if (q == EOF)
10625 {
10626 (void *) strncpy(buffer, identifier, id_length);
10627 return id_length;
10628 }
10629 quote_char= (char) q;
10630 *buffer++= quote_char;
10631 written++;
10632 while (id_length--)
10633 {
10634 if (*identifier == quote_char)
10635 {
10636 *buffer++= quote_char;
10637 written++;
10638 }
10639 *buffer++= *identifier++;
10640 written++;
10641 }
10642 *buffer++= quote_char;
10643 return ++written;
10644 }
10645
10646