1 /*
2 Copyright (c) 2000, 2020, 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, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24
25 #ifdef MYSQL_CLIENT
26
27 #include "sql_priv.h"
28 #include "mysqld_error.h"
29
30 #else
31
32 #include "binlog.h"
33 #include "sql_priv.h"
34 #include "unireg.h"
35 #include "my_global.h" // REQUIRED by log_event.h > m_string.h > my_bitmap.h
36 #include "log_event.h"
37 #include "sql_base.h" // close_thread_tables
38 #include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE
39 #include "sql_locale.h" // MY_LOCALE, my_locale_by_number, my_locale_en_US
40 #include "lock.h" // mysql_unlock_tables
41 #include "sql_parse.h" // mysql_test_parse_for_slave
42 #include "tztime.h" // struct Time_zone
43 #include "sql_load.h" // mysql_load
44 #include "sql_db.h" // load_db_opt_by_name
45 #include "rpl_slave.h"
46 #include "rpl_rli.h"
47 #include "rpl_mi.h"
48 #include "rpl_filter.h"
49 #include "rpl_record.h"
50 #include "transaction.h"
51 #include <my_dir.h>
52 #include "rpl_rli_pdb.h"
53 #include "sql_show.h" // append_identifier
54 #include "debug_sync.h" // debug_sync
55 #include <mysql/psi/mysql_statement.h>
56 #if WITH_WSREP
57 #include "wsrep_mysqld.h"
58 #endif
59 #define window_size Log_throttle::LOG_THROTTLE_WINDOW_SIZE
60 Error_log_throttle
61 slave_ignored_err_throttle(window_size,
62 sql_print_warning,
63 "Error log throttle: %lu time(s) Error_code: 1237"
64 " \"Slave SQL thread ignored the query because of"
65 " replicate-*-table rules\" got suppressed.");
66 #endif /* MYSQL_CLIENT */
67
68 #include <base64.h>
69 #include <my_bitmap.h>
70 #include "rpl_utility.h"
71
72 #include "sql_digest.h"
73
74 using std::min;
75 using std::max;
76
77 /* The number of event types need to be permuted. */
78 static const uint EVENT_TYPE_PERMUTATION_NUM= 23;
79
80 /**
81 BINLOG_CHECKSUM variable.
82 */
83 const char *binlog_checksum_type_names[]= {
84 "NONE",
85 "CRC32",
86 NullS
87 };
88
89 unsigned int binlog_checksum_type_length[]= {
90 sizeof("NONE") - 1,
91 sizeof("CRC32") - 1,
92 0
93 };
94
95 TYPELIB binlog_checksum_typelib=
96 {
97 array_elements(binlog_checksum_type_names) - 1, "",
98 binlog_checksum_type_names,
99 binlog_checksum_type_length
100 };
101
102
103 #define log_cs &my_charset_latin1
104
105 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
106
107 /*
108 Size of buffer for printing a double in format %.<PREC>g
109
110 optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
111 exponent digits + '\0'
112 */
113 #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
114
115 /*
116 Explicit instantiation to unsigned int of template available_buffer
117 function.
118 */
119 template unsigned int available_buffer<unsigned int>(const char*,
120 const char*,
121 unsigned int);
122
123 /*
124 Explicit instantiation to unsigned int of template valid_buffer_range
125 function.
126 */
127 template bool valid_buffer_range<unsigned int>(unsigned int,
128 const char*,
129 const char*,
130 unsigned int);
131
132 /*
133 replication event checksum is introduced in the following "checksum-home" version.
134 The checksum-aware servers extract FD's version to decide whether the FD event
135 carries checksum info.
136 */
137 const uchar checksum_version_split[3]= {5, 6, 1};
138 const ulong checksum_version_product=
139 (checksum_version_split[0] * 256 + checksum_version_split[1]) * 256 +
140 checksum_version_split[2];
141
142 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
143 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
144
HA_ERR(int i)145 static const char *HA_ERR(int i)
146 {
147 /*
148 This function should only be called in case of an error
149 was detected
150 */
151 DBUG_ASSERT(i != 0);
152 switch (i) {
153 case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
154 case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
155 case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
156 case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
157 case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
158 case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
159 case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
160 case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
161 case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
162 case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
163 case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
164 case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
165 case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
166 case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
167 case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
168 case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
169 case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
170 case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
171 case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
172 case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
173 case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
174 case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
175 case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
176 case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
177 case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
178 case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
179 case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
180 case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
181 case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
182 case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
183 case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
184 case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
185 case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
186 case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
187 case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
188 case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
189 case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
190 case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
191 case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
192 case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
193 case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
194 case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
195 case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
196 case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
197 case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
198 case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
199 case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
200 case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
201 case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
202 case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
203 case HA_ERR_INNODB_READ_ONLY: return "HA_ERR_INNODB_READ_ONLY";
204 case HA_ERR_FTS_TOO_MANY_NESTED_EXP: return "HA_ERR_FTS_TOO_MANY_NESTED_EXP";
205 }
206 return "No Error!";
207 }
208
209 /**
210 Error reporting facility for Rows_log_event::do_apply_event
211
212 @param level error, warning or info
213 @param ha_error HA_ERR_ code
214 @param rli pointer to the active Relay_log_info instance
215 @param thd pointer to the slave thread's thd
216 @param table pointer to the event's table object
217 @param type the type of the event
218 @param log_name the master binlog file name
219 @param pos the master binlog file pos (the next after the event)
220
221 */
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)222 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
223 Relay_log_info const *rli, THD *thd,
224 TABLE *table, const char * type,
225 const char *log_name, ulong pos)
226 {
227 const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
228 char buff[MAX_SLAVE_ERRMSG], *slider;
229 const char *buff_end= buff + sizeof(buff);
230 uint len;
231 Diagnostics_area::Sql_condition_iterator it=
232 thd->get_stmt_da()->sql_conditions();
233 const Sql_condition *err;
234 buff[0]= 0;
235
236 for (err= it++, slider= buff; err && slider < buff_end - 1;
237 slider += len, err= it++)
238 {
239 len= my_snprintf(slider, buff_end - slider,
240 " %s, Error_code: %d;", err->get_message_text(),
241 err->get_sql_errno());
242 }
243
244 if (ha_error != 0)
245 rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
246 "Could not execute %s event on table %s.%s;"
247 "%s handler error %s; "
248 "the event's master log %s, end_log_pos %lu",
249 type, table->s->db.str, table->s->table_name.str,
250 buff, handler_error == NULL ? "<unknown>" : handler_error,
251 log_name, pos);
252 else
253 rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
254 "Could not execute %s event on table %s.%s;"
255 "%s the event's master log %s, end_log_pos %lu",
256 type, table->s->db.str, table->s->table_name.str,
257 buff, log_name, pos);
258 }
259
set_thd_db(THD * thd,const char * db,uint32 db_len)260 static void set_thd_db(THD *thd, const char *db, uint32 db_len)
261 {
262 char lcase_db_buf[NAME_LEN +1];
263 LEX_STRING new_db;
264 new_db.length= db_len;
265 if (lower_case_table_names == 1)
266 {
267 strmov(lcase_db_buf, db);
268 my_casedn_str(system_charset_info, lcase_db_buf);
269 new_db.str= lcase_db_buf;
270 }
271 else
272 new_db.str= (char*) db;
273
274 new_db.str= (char*) rpl_filter->get_rewrite_db(new_db.str,
275 &new_db.length);
276 thd->set_db(new_db.str, new_db.length);
277 }
278
279 #endif
280
281
282 /*
283 pretty_print_str()
284 */
285
286 #ifdef MYSQL_CLIENT
pretty_print_str(IO_CACHE * cache,const char * str,int len)287 static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
288 {
289 const char* end = str + len;
290 my_b_printf(cache, "\'");
291 while (str < end)
292 {
293 char c;
294 switch ((c=*str++)) {
295 case '\n': my_b_printf(cache, "\\n"); break;
296 case '\r': my_b_printf(cache, "\\r"); break;
297 case '\\': my_b_printf(cache, "\\\\"); break;
298 case '\b': my_b_printf(cache, "\\b"); break;
299 case '\t': my_b_printf(cache, "\\t"); break;
300 case '\'': my_b_printf(cache, "\\'"); break;
301 case 0 : my_b_printf(cache, "\\0"); break;
302 default:
303 my_b_printf(cache, "%c", c);
304 break;
305 }
306 }
307 my_b_printf(cache, "\'");
308 }
309 #endif /* MYSQL_CLIENT */
310
311 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
312
clear_all_errors(THD * thd,Relay_log_info * rli)313 static void clear_all_errors(THD *thd, Relay_log_info *rli)
314 {
315 thd->is_slave_error = 0;
316 thd->clear_error();
317 rli->clear_error();
318 }
319
idempotent_error_code(int err_code)320 inline int idempotent_error_code(int err_code)
321 {
322 int ret= 0;
323
324 switch (err_code)
325 {
326 case 0:
327 ret= 1;
328 break;
329 /*
330 The following list of "idempotent" errors
331 means that an error from the list might happen
332 because of idempotent (more than once)
333 applying of a binlog file.
334 Notice, that binlog has a ddl operation its
335 second applying may cause
336
337 case HA_ERR_TABLE_DEF_CHANGED:
338 case HA_ERR_CANNOT_ADD_FOREIGN:
339
340 which are not included into to the list.
341
342 Note that HA_ERR_RECORD_DELETED is not in the list since
343 do_exec_row() should not return that error code.
344 */
345 case HA_ERR_RECORD_CHANGED:
346 case HA_ERR_KEY_NOT_FOUND:
347 case HA_ERR_END_OF_FILE:
348 case HA_ERR_FOUND_DUPP_KEY:
349 case HA_ERR_FOUND_DUPP_UNIQUE:
350 case HA_ERR_FOREIGN_DUPLICATE_KEY:
351 case HA_ERR_NO_REFERENCED_ROW:
352 case HA_ERR_ROW_IS_REFERENCED:
353 ret= 1;
354 break;
355 default:
356 ret= 0;
357 break;
358 }
359 return (ret);
360 }
361
362 /**
363 Ignore error code specified on command line.
364 */
365
ignored_error_code(int err_code)366 int ignored_error_code(int err_code)
367 {
368 #ifdef HAVE_NDB_BINLOG
369 /*
370 The following error codes are hard-coded and will always be ignored.
371 */
372 switch (err_code)
373 {
374 case ER_DB_CREATE_EXISTS:
375 case ER_DB_DROP_EXISTS:
376 return 1;
377 default:
378 /* Nothing to do */
379 break;
380 }
381 #endif
382 return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
383 (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
384 }
385
386 /*
387 This function converts an engine's error to a server error.
388
389 If the thread does not have an error already reported, it tries to
390 define it by calling the engine's method print_error. However, if a
391 mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
392 warning message.
393 */
convert_handler_error(int error,THD * thd,TABLE * table)394 int convert_handler_error(int error, THD* thd, TABLE *table)
395 {
396 uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
397 0);
398
399 if (actual_error == 0)
400 {
401 table->file->print_error(error, MYF(0));
402 actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
403 ER_UNKNOWN_ERROR);
404 if (actual_error == ER_UNKNOWN_ERROR)
405 if (log_warnings)
406 sql_print_warning("Unknown error detected %d in handler", error);
407 }
408
409 return (actual_error);
410 }
411
concurrency_error_code(int error)412 inline bool concurrency_error_code(int error)
413 {
414 switch (error)
415 {
416 case ER_LOCK_WAIT_TIMEOUT:
417 case ER_LOCK_DEADLOCK:
418 case ER_XA_RBDEADLOCK:
419 return TRUE;
420 default:
421 return (FALSE);
422 }
423 }
424
unexpected_error_code(int unexpected_error)425 inline bool unexpected_error_code(int unexpected_error)
426 {
427 switch (unexpected_error)
428 {
429 case ER_NET_READ_ERROR:
430 case ER_NET_ERROR_ON_WRITE:
431 case ER_QUERY_INTERRUPTED:
432 case ER_SERVER_SHUTDOWN:
433 case ER_NEW_ABORTING_CONNECTION:
434 return(TRUE);
435 default:
436 return(FALSE);
437 }
438 }
439
440 /*
441 pretty_print_str()
442 */
443
pretty_print_str(char * packet,const char * str,int len)444 static char *pretty_print_str(char *packet, const char *str, int len)
445 {
446 const char *end= str + len;
447 char *pos= packet;
448 *pos++= '\'';
449 while (str < end)
450 {
451 char c;
452 switch ((c=*str++)) {
453 case '\n': *pos++= '\\'; *pos++= 'n'; break;
454 case '\r': *pos++= '\\'; *pos++= 'r'; break;
455 case '\\': *pos++= '\\'; *pos++= '\\'; break;
456 case '\b': *pos++= '\\'; *pos++= 'b'; break;
457 case '\t': *pos++= '\\'; *pos++= 't'; break;
458 case '\'': *pos++= '\\'; *pos++= '\''; break;
459 case 0 : *pos++= '\\'; *pos++= '0'; break;
460 default:
461 *pos++= c;
462 break;
463 }
464 }
465 *pos++= '\'';
466 return pos;
467 }
468 #endif /* !MYSQL_CLIENT */
469
470
471 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
472
473 /**
474 Creates a temporary name for load data infile:.
475
476 @param buf Store new filename here
477 @param file_id File_id (part of file name)
478 @param event_server_id Event_id (part of file name)
479 @param ext Extension for file name
480
481 @return
482 Pointer to start of extension
483 */
484
slave_load_file_stem(char * buf,uint file_id,int event_server_id,const char * ext)485 static char *slave_load_file_stem(char *buf, uint file_id,
486 int event_server_id, const char *ext)
487 {
488 char *res;
489 fn_format(buf,PREFIX_SQL_LOAD,slave_load_tmpdir, "", MY_UNPACK_FILENAME);
490 to_unix_path(buf);
491
492 buf= strend(buf);
493 int appended_length= sprintf(buf, "%s-%d-", server_uuid, event_server_id);
494 buf+= appended_length;
495 res= int10_to_str(file_id, buf, 10);
496 strmov(res, ext); // Add extension last
497 return res; // Pointer to extension
498 }
499 #endif
500
501
502 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
503
504 /**
505 Delete all temporary files used for SQL_LOAD.
506 */
507
cleanup_load_tmpdir()508 static void cleanup_load_tmpdir()
509 {
510 MY_DIR *dirp;
511 FILEINFO *file;
512 uint i;
513 char fname[FN_REFLEN], prefbuf[TEMP_FILE_MAX_LEN], *p;
514
515 if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
516 return;
517
518 /*
519 When we are deleting temporary files, we should only remove
520 the files associated with the server id of our server.
521 We don't use event_server_id here because since we've disabled
522 direct binlogging of Create_file/Append_file/Exec_load events
523 we cannot meet Start_log event in the middle of events from one
524 LOAD DATA.
525 */
526 p= strmake(prefbuf, STRING_WITH_LEN(PREFIX_SQL_LOAD));
527 sprintf(p,"%s-",server_uuid);
528
529 for (i=0 ; i < (uint)dirp->number_off_files; i++)
530 {
531 file=dirp->dir_entry+i;
532 if (is_prefix(file->name, prefbuf))
533 {
534 fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
535 mysql_file_delete(key_file_misc, fname, MYF(0));
536 }
537 }
538
539 my_dirend(dirp);
540 }
541 #endif
542
543
544 /*
545 Stores string to IO_CACHE file.
546
547 Writes str to file in the following format:
548 1. Stores length using only one byte (255 maximum value);
549 2. Stores complete str.
550 */
551
write_str_at_most_255_bytes(IO_CACHE * file,const char * str,uint length)552 static bool write_str_at_most_255_bytes(IO_CACHE *file, const char *str,
553 uint length)
554 {
555 uchar tmp[1];
556 tmp[0]= (uchar) length;
557 return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
558 my_b_safe_write(file, (uchar*) str, length));
559 }
560
561
562 /*
563 Reads string from buf.
564
565 Reads str from buf in the following format:
566 1. Read length stored on buf first index, as it only has 1 byte values
567 bigger than 255 where lost.
568 2. Set str pointer to buf second index.
569 Despite str contains the complete stored string, when it is read until
570 len its value will be truncated if original length was bigger than 255.
571 */
572
read_str_at_most_255_bytes(const char ** buf,const char * buf_end,const char ** str,uint8 * len)573 static inline int read_str_at_most_255_bytes(const char **buf,
574 const char *buf_end,
575 const char **str,
576 uint8 *len)
577 {
578 if (*buf + ((uint) (uchar) **buf) >= buf_end)
579 return 1;
580 *len= (uint8) **buf;
581 *str= (*buf)+1;
582 (*buf)+= (uint) *len+1;
583 return 0;
584 }
585
586
587 /**
588 Transforms a string into "" or its expression in 0x... form.
589 */
590
str_to_hex(char * to,const char * from,uint len)591 char *str_to_hex(char *to, const char *from, uint len)
592 {
593 if (len)
594 {
595 *to++= '0';
596 *to++= 'x';
597 to= octet2hex(to, from, len);
598 }
599 else
600 to= strmov(to, "\"\"");
601 return to; // pointer to end 0 of 'to'
602 }
603
604 #ifndef MYSQL_CLIENT
605
606 /**
607 Append a version of the 'from' string suitable for use in a query to
608 the 'to' string. To generate a correct escaping, the character set
609 information in 'csinfo' is used.
610 */
611
612 int
append_query_string(THD * thd,const CHARSET_INFO * csinfo,String const * from,String * to)613 append_query_string(THD *thd, const CHARSET_INFO *csinfo,
614 String const *from, String *to)
615 {
616 char *beg, *ptr;
617 uint32 const orig_len= to->length();
618 if (to->reserve(orig_len + from->length()*2+3))
619 return 1;
620
621 beg= to->c_ptr_quick() + to->length();
622 ptr= beg;
623 if (csinfo->escape_with_backslash_is_dangerous)
624 ptr= str_to_hex(ptr, from->ptr(), from->length());
625 else
626 {
627 *ptr++= '\'';
628 if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
629 {
630 ptr+= escape_string_for_mysql(csinfo, ptr, 0,
631 from->ptr(), from->length());
632 }
633 else
634 {
635 const char *frm_str= from->ptr();
636
637 for (; frm_str < (from->ptr() + from->length()); frm_str++)
638 {
639 /* Using '' way to represent "'" */
640 if (*frm_str == '\'')
641 *ptr++= *frm_str;
642
643 *ptr++= *frm_str;
644 }
645 }
646
647 *ptr++= '\'';
648 }
649 to->length(orig_len + ptr - beg);
650 return 0;
651 }
652 #endif
653
654
655 /**
656 Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
657 commands just before it prints a query.
658 */
659
660 #ifdef MYSQL_CLIENT
661
print_set_option(IO_CACHE * file,uint32 bits_changed,uint32 option,uint32 flags,const char * name,bool * need_comma)662 static void print_set_option(IO_CACHE* file, uint32 bits_changed,
663 uint32 option, uint32 flags, const char* name,
664 bool* need_comma)
665 {
666 if (bits_changed & option)
667 {
668 if (*need_comma)
669 my_b_printf(file,", ");
670 my_b_printf(file,"%s=%d", name, MY_TEST(flags & option));
671 *need_comma= 1;
672 }
673 }
674 #endif
675 /**************************************************************************
676 Log_event methods (= the parent class of all events)
677 **************************************************************************/
678
679 /**
680 @return
681 returns the human readable name of the event's type
682 */
683
get_type_str(Log_event_type type)684 const char* Log_event::get_type_str(Log_event_type type)
685 {
686 switch(type) {
687 case START_EVENT_V3: return "Start_v3";
688 case STOP_EVENT: return "Stop";
689 case QUERY_EVENT: return "Query";
690 case ROTATE_EVENT: return "Rotate";
691 case INTVAR_EVENT: return "Intvar";
692 case LOAD_EVENT: return "Load";
693 case NEW_LOAD_EVENT: return "New_load";
694 case CREATE_FILE_EVENT: return "Create_file";
695 case APPEND_BLOCK_EVENT: return "Append_block";
696 case DELETE_FILE_EVENT: return "Delete_file";
697 case EXEC_LOAD_EVENT: return "Exec_load";
698 case RAND_EVENT: return "RAND";
699 case XID_EVENT: return "Xid";
700 case USER_VAR_EVENT: return "User var";
701 case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
702 case TABLE_MAP_EVENT: return "Table_map";
703 case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
704 case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
705 case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
706 case WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
707 case UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
708 case DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
709 case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
710 case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
711 case INCIDENT_EVENT: return "Incident";
712 case IGNORABLE_LOG_EVENT: return "Ignorable";
713 case ROWS_QUERY_LOG_EVENT: return "Rows_query";
714 case WRITE_ROWS_EVENT: return "Write_rows";
715 case UPDATE_ROWS_EVENT: return "Update_rows";
716 case DELETE_ROWS_EVENT: return "Delete_rows";
717 case GTID_LOG_EVENT: return "Gtid";
718 case ANONYMOUS_GTID_LOG_EVENT: return "Anonymous_Gtid";
719 case PREVIOUS_GTIDS_LOG_EVENT: return "Previous_gtids";
720 case HEARTBEAT_LOG_EVENT: return "Heartbeat";
721 default: return "Unknown"; /* impossible */
722 }
723 }
724
get_type_str()725 const char* Log_event::get_type_str()
726 {
727 return get_type_str(get_type_code());
728 }
729
730
731 /*
732 Log_event::Log_event()
733 */
734
735 #ifndef MYSQL_CLIENT
Log_event(THD * thd_arg,uint16 flags_arg,enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg)736 Log_event::Log_event(THD* thd_arg, uint16 flags_arg,
737 enum_event_cache_type cache_type_arg,
738 enum_event_logging_type logging_type_arg)
739 :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
740 event_cache_type(cache_type_arg),
741 event_logging_type(logging_type_arg),
742 crc(0), thd(thd_arg), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
743 {
744 server_id= thd->server_id;
745 unmasked_server_id= server_id;
746 when= thd->start_time;
747 }
748
749 /**
750 This minimal constructor is for when you are not even sure that there
751 is a valid THD. For example in the server when we are shutting down or
752 flushing logs after receiving a SIGHUP (then we must write a Rotate to
753 the binlog but we have no THD, so we need this minimal constructor).
754 */
755
Log_event(enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg)756 Log_event::Log_event(enum_event_cache_type cache_type_arg,
757 enum_event_logging_type logging_type_arg)
758 :temp_buf(0), exec_time(0), flags(0), event_cache_type(cache_type_arg),
759 event_logging_type(logging_type_arg), crc(0), thd(0),
760 checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
761 {
762 server_id= ::server_id;
763 unmasked_server_id= server_id;
764 /*
765 We can't call my_time() here as this would cause a call before
766 my_init() is called
767 */
768 when.tv_sec= 0;
769 when.tv_usec= 0;
770 log_pos= 0;
771 }
772 #endif /* !MYSQL_CLIENT */
773
774
775 /*
776 Log_event::Log_event()
777 */
778
Log_event(const char * buf,const Format_description_log_event * description_event)779 Log_event::Log_event(const char* buf,
780 const Format_description_log_event* description_event)
781 :temp_buf(0), exec_time(0),
782 event_cache_type(EVENT_INVALID_CACHE),
783 event_logging_type(EVENT_INVALID_LOGGING),
784 crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
785 {
786 #ifndef MYSQL_CLIENT
787 thd = 0;
788 #endif
789 when.tv_sec= uint4korr(buf);
790 when.tv_usec= 0;
791 server_id = uint4korr(buf + SERVER_ID_OFFSET);
792 unmasked_server_id = server_id;
793 /*
794 Mask out any irrelevant parts of the server_id
795 */
796 #ifdef HAVE_REPLICATION
797 server_id = unmasked_server_id & opt_server_id_mask;
798 #else
799 server_id = unmasked_server_id;
800 #endif
801 data_written= uint4korr(buf + EVENT_LEN_OFFSET);
802 if (description_event->binlog_version==1)
803 {
804 log_pos= 0;
805 flags= 0;
806 return;
807 }
808 /* 4.0 or newer */
809 log_pos= uint4korr(buf + LOG_POS_OFFSET);
810 /*
811 If the log is 4.0 (so here it can only be a 4.0 relay log read by
812 the SQL thread or a 4.0 master binlog read by the I/O thread),
813 log_pos is the beginning of the event: we transform it into the end
814 of the event, which is more useful.
815 But how do you know that the log is 4.0: you know it if
816 description_event is version 3 *and* you are not reading a
817 Format_desc (remember that mysqlbinlog starts by assuming that 5.0
818 logs are in 4.0 format, until it finds a Format_desc).
819 */
820 if (description_event->binlog_version==3 &&
821 buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
822 {
823 /*
824 If log_pos=0, don't change it. log_pos==0 is a marker to mean
825 "don't change rli->group_master_log_pos" (see
826 inc_group_relay_log_pos()). As it is unreal log_pos, adding the
827 event len's is nonsense. For example, a fake Rotate event should
828 not have its log_pos (which is 0) changed or it will modify
829 Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
830 value of (a non-zero offset which does not exist in the master's
831 binlog, so which will cause problems if the user uses this value
832 in CHANGE MASTER).
833 */
834 log_pos+= data_written; /* purecov: inspected */
835 }
836 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
837
838 flags= uint2korr(buf + FLAGS_OFFSET);
839 if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
840 (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
841 {
842 /*
843 These events always have a header which stops here (i.e. their
844 header is FROZEN).
845 */
846 /*
847 Initialization to zero of all other Log_event members as they're
848 not specified. Currently there are no such members; in the future
849 there will be an event UID (but Format_description and Rotate
850 don't need this UID, as they are not propagated through
851 --log-slave-updates (remember the UID is used to not play a query
852 twice when you have two masters which are slaves of a 3rd master).
853 Then we are done.
854 */
855 return;
856 }
857 /* otherwise, go on with reading the header from buf (nothing now) */
858 }
859
860 #ifndef MYSQL_CLIENT
861 #ifdef HAVE_REPLICATION
do_apply_event_worker(Slave_worker * w)862 inline int Log_event::do_apply_event_worker(Slave_worker *w)
863 {
864 return do_apply_event(w);
865 }
866
do_update_pos(Relay_log_info * rli)867 int Log_event::do_update_pos(Relay_log_info *rli)
868 {
869 int error= 0;
870 DBUG_ASSERT(!rli->belongs_to_client());
871 /*
872 rli is null when (as far as I (Guilhem) know) the caller is
873 Load_log_event::do_apply_event *and* that one is called from
874 Execute_load_log_event::do_apply_event. In this case, we don't
875 do anything here ; Execute_load_log_event::do_apply_event will
876 call Log_event::do_apply_event again later with the proper rli.
877 Strictly speaking, if we were sure that rli is null only in the
878 case discussed above, 'if (rli)' is useless here. But as we are
879 not 100% sure, keep it for now.
880
881 Matz: I don't think we will need this check with this refactoring.
882 */
883
884 DBUG_ASSERT(!is_mts_worker(rli->info_thd));
885
886 if (rli)
887 error= rli->stmt_done(log_pos);
888 return error;
889 }
890
891
892 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)893 Log_event::do_shall_skip(Relay_log_info *rli)
894 {
895 DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
896 " rli->replicate_same_server_id=%d,"
897 " rli->slave_skip_counter=%d",
898 (ulong) server_id, (ulong) ::server_id,
899 rli->replicate_same_server_id,
900 rli->slave_skip_counter));
901 if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
902 (rli->slave_skip_counter == 1 && rli->is_in_group()))
903 return EVENT_SKIP_IGNORE;
904 else if (rli->slave_skip_counter > 0)
905 return EVENT_SKIP_COUNT;
906 else
907 return EVENT_SKIP_NOT;
908 }
909
910
911 /*
912 Log_event::pack_info()
913 */
914
pack_info(Protocol * protocol)915 int Log_event::pack_info(Protocol *protocol)
916 {
917 protocol->store("", &my_charset_bin);
918 return 0;
919 }
920
921
922 /**
923 Only called by SHOW BINLOG EVENTS
924 */
net_send(Protocol * protocol,const char * log_name,my_off_t pos)925 int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
926 {
927 const char *p= strrchr(log_name, FN_LIBCHAR);
928 const char *event_type;
929 if (p)
930 log_name = p + 1;
931
932 protocol->prepare_for_resend();
933 protocol->store(log_name, &my_charset_bin);
934 protocol->store((ulonglong) pos);
935 event_type = get_type_str();
936 protocol->store(event_type, strlen(event_type), &my_charset_bin);
937 protocol->store((uint32) server_id);
938 protocol->store((ulonglong) log_pos);
939 if (pack_info(protocol))
940 return 1;
941 return protocol->write();
942 }
943 #endif /* HAVE_REPLICATION */
944
945
946 /**
947 init_show_field_list() prepares the column names and types for the
948 output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
949 EVENTS.
950 */
951
init_show_field_list(List<Item> * field_list)952 void Log_event::init_show_field_list(List<Item>* field_list)
953 {
954 field_list->push_back(new Item_empty_string("Log_name", 20));
955 field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
956 MYSQL_TYPE_LONGLONG));
957 field_list->push_back(new Item_empty_string("Event_type", 20));
958 field_list->push_back(new Item_return_int("Server_id", 10,
959 MYSQL_TYPE_LONG));
960 field_list->push_back(new Item_return_int("End_log_pos",
961 MY_INT32_NUM_DECIMAL_DIGITS,
962 MYSQL_TYPE_LONGLONG));
963 field_list->push_back(new Item_empty_string("Info", 20));
964 }
965
966 /**
967 A decider of whether to trigger checksum computation or not.
968 To be invoked in Log_event::write() stack.
969 The decision is positive
970
971 S,M) if it's been marked for checksumming with @c checksum_alg
972
973 M) otherwise, if @@global.binlog_checksum is not NONE and the event is
974 directly written to the binlog file.
975 The to-be-cached event decides at @c write_cache() time.
976
977 Otherwise the decision is negative.
978
979 @note A side effect of the method is altering Log_event::checksum_alg
980 it the latter was undefined at calling.
981
982 @return true (positive) or false (negative)
983 */
need_checksum()984 my_bool Log_event::need_checksum()
985 {
986 DBUG_ENTER("Log_event::need_checksum");
987 my_bool ret= FALSE;
988 /*
989 few callers of Log_event::write
990 (incl FD::write, FD constructing code on the slave side, Rotate relay log
991 and Stop event)
992 provides their checksum alg preference through Log_event::checksum_alg.
993 */
994 if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
995 ret= (checksum_alg != BINLOG_CHECKSUM_ALG_OFF);
996 else if (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF &&
997 event_cache_type == Log_event::EVENT_NO_CACHE)
998 ret= binlog_checksum_options;
999 else
1000 ret= FALSE;
1001
1002 /*
1003 FD calls the methods before data_written has been calculated.
1004 The following invariant claims if the current is not the first
1005 call (and therefore data_written is not zero) then `ret' must be
1006 TRUE. It may not be null because FD is always checksummed.
1007 */
1008
1009 DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
1010 data_written == 0);
1011
1012 if (checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
1013 checksum_alg= ret ? // calculated value stored
1014 binlog_checksum_options : (uint8) BINLOG_CHECKSUM_ALG_OFF;
1015
1016 DBUG_ASSERT(!ret ||
1017 ((checksum_alg == binlog_checksum_options ||
1018 /*
1019 Stop event closes the relay-log and its checksum alg
1020 preference is set by the caller can be different
1021 from the server's binlog_checksum_options.
1022 */
1023 get_type_code() == STOP_EVENT ||
1024 /*
1025 Rotate:s can be checksummed regardless of the server's
1026 binlog_checksum_options. That applies to both
1027 the local RL's Rotate and the master's Rotate
1028 which IO thread instantiates via queue_binlog_ver_3_event.
1029 */
1030 get_type_code() == ROTATE_EVENT ||
1031 /*
1032 The previous event has its checksum option defined
1033 according to the format description event.
1034 */
1035 get_type_code() == PREVIOUS_GTIDS_LOG_EVENT ||
1036 /* FD is always checksummed */
1037 get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
1038 checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
1039
1040 DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
1041 DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
1042 get_type_code() != STOP_EVENT) ||
1043 get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
1044 event_cache_type == Log_event::EVENT_NO_CACHE);
1045
1046 DBUG_RETURN(ret);
1047 }
1048
wrapper_my_b_safe_write(IO_CACHE * file,const uchar * buf,ulong size)1049 bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong size)
1050 {
1051 DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1052 {
1053 file->write_pos = file->write_end;
1054 DBUG_SET("+d,simulate_file_write_error");
1055 });
1056 if (need_checksum() && size != 0)
1057 crc= my_checksum(crc, buf, size);
1058 bool ret = my_b_safe_write(file, buf, size);
1059 DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1060 {
1061 DBUG_SET("-d,simulate_file_write_error");
1062 });
1063 return ret;
1064 }
1065
write_footer(IO_CACHE * file)1066 bool Log_event::write_footer(IO_CACHE* file)
1067 {
1068 /*
1069 footer contains the checksum-algorithm descriptor
1070 followed by the checksum value
1071 */
1072 if (need_checksum())
1073 {
1074 uchar buf[BINLOG_CHECKSUM_LEN];
1075 int4store(buf, crc);
1076 return (my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
1077 }
1078 return 0;
1079 }
1080
1081 /*
1082 Log_event::write()
1083 */
1084
write_header(IO_CACHE * file,ulong event_data_length)1085 bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
1086 {
1087 uchar header[LOG_EVENT_HEADER_LEN];
1088 ulong now;
1089 bool ret;
1090 DBUG_ENTER("Log_event::write_header");
1091
1092 /* Store number of bytes that will be written by this event */
1093 data_written= event_data_length + sizeof(header);
1094
1095 if (need_checksum())
1096 {
1097 crc= my_checksum(0L, NULL, 0);
1098 data_written += BINLOG_CHECKSUM_LEN;
1099 }
1100
1101 /*
1102 log_pos != 0 if this is relay-log event. In this case we should not
1103 change the position
1104 */
1105
1106 if (is_artificial_event())
1107 {
1108 /*
1109 Artificial events are automatically generated and do not exist
1110 in master's binary log, so log_pos should be set to 0.
1111 */
1112 log_pos= 0;
1113 }
1114 else if (!log_pos)
1115 {
1116 /*
1117 Calculate position of end of event
1118
1119 Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
1120 work well. So this will give slightly wrong positions for the
1121 Format_desc/Rotate/Stop events which the slave writes to its
1122 relay log. For example, the initial Format_desc will have
1123 end_log_pos=91 instead of 95. Because after writing the first 4
1124 bytes of the relay log, my_b_tell() still reports 0. Because
1125 my_b_append() does not update the counter which my_b_tell()
1126 later uses (one should probably use my_b_append_tell() to work
1127 around this). To get right positions even when writing to the
1128 relay log, we use the (new) my_b_safe_tell().
1129
1130 Note that this raises a question on the correctness of all these
1131 DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
1132
1133 If in a transaction, the log_pos which we calculate below is not
1134 very good (because then my_b_safe_tell() returns start position
1135 of the BEGIN, so it's like the statement was at the BEGIN's
1136 place), but it's not a very serious problem (as the slave, when
1137 it is in a transaction, does not take those end_log_pos into
1138 account (as it calls inc_event_relay_log_pos()). To be fixed
1139 later, so that it looks less strange. But not bug.
1140 */
1141
1142 log_pos= my_b_safe_tell(file)+data_written;
1143 }
1144
1145 now= (ulong) get_time(); // Query start time
1146 if (DBUG_EVALUATE_IF("inc_event_time_by_1_hour",1,0) &&
1147 DBUG_EVALUATE_IF("dec_event_time_by_1_hour",1,0))
1148 {
1149 /**
1150 This assertion guarantees that these debug flags are not
1151 used at the same time (they would cancel each other).
1152 */
1153 DBUG_ASSERT(0);
1154 }
1155 else
1156 {
1157 DBUG_EXECUTE_IF("inc_event_time_by_1_hour", now= now + 3600;);
1158 DBUG_EXECUTE_IF("dec_event_time_by_1_hour", now= now - 3600;);
1159 }
1160
1161 /*
1162 Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1163 FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1164 LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1165 because we read them before knowing the format).
1166 */
1167
1168 int4store(header, now); // timestamp
1169 header[EVENT_TYPE_OFFSET]= get_type_code();
1170 int4store(header+ SERVER_ID_OFFSET, server_id);
1171 int4store(header+ EVENT_LEN_OFFSET, data_written);
1172 int4store(header+ LOG_POS_OFFSET, log_pos);
1173 /*
1174 recording checksum of FD event computed with dropped
1175 possibly active LOG_EVENT_BINLOG_IN_USE_F flag.
1176 Similar step at verication: the active flag is dropped before
1177 checksum computing.
1178 */
1179 if (header[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT ||
1180 !need_checksum() || !(flags & LOG_EVENT_BINLOG_IN_USE_F))
1181 {
1182 int2store(header+ FLAGS_OFFSET, flags);
1183 ret= wrapper_my_b_safe_write(file, header, sizeof(header)) != 0;
1184 }
1185 else
1186 {
1187 ret= (wrapper_my_b_safe_write(file, header, FLAGS_OFFSET) != 0);
1188 if (!ret)
1189 {
1190 flags &= ~LOG_EVENT_BINLOG_IN_USE_F;
1191 int2store(header + FLAGS_OFFSET, flags);
1192 crc= my_checksum(crc, header + FLAGS_OFFSET, sizeof(flags));
1193 flags |= LOG_EVENT_BINLOG_IN_USE_F;
1194 int2store(header + FLAGS_OFFSET, flags);
1195 ret= (my_b_safe_write(file, header + FLAGS_OFFSET, sizeof(flags)) != 0);
1196 }
1197 if (!ret)
1198 ret= (wrapper_my_b_safe_write(file, header + FLAGS_OFFSET + sizeof(flags),
1199 sizeof(header)
1200 - (FLAGS_OFFSET + sizeof(flags))) != 0);
1201 }
1202 DBUG_RETURN( ret);
1203 }
1204
1205
1206 /**
1207 This needn't be format-tolerant, because we only read
1208 LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
1209 */
1210
read_log_event(IO_CACHE * file,String * packet,mysql_mutex_t * log_lock,uint8 checksum_alg_arg,const char * log_file_name_arg,bool * is_binlog_active)1211 int Log_event::read_log_event(IO_CACHE* file, String* packet,
1212 mysql_mutex_t* log_lock,
1213 uint8 checksum_alg_arg,
1214 const char *log_file_name_arg,
1215 bool* is_binlog_active)
1216 {
1217 ulong data_len;
1218 int result=0;
1219 char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1220 uchar ev_offset= packet->length();
1221 DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, String *, mysql_mutex_t, uint8)");
1222
1223 if (log_lock)
1224 mysql_mutex_lock(log_lock);
1225
1226 if (log_file_name_arg)
1227 *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
1228
1229 if (my_b_read(file, (uchar*) buf, sizeof(buf)))
1230 {
1231 /*
1232 If the read hits eof, we must report it as eof so the caller
1233 will know it can go into cond_wait to be woken up on the next
1234 update to the log.
1235 */
1236 DBUG_PRINT("error",("my_b_read failed. file->error: %d", file->error));
1237 if (!file->error)
1238 result= LOG_READ_EOF;
1239 else
1240 result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1241 goto end;
1242 }
1243 data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1244 if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
1245 data_len > max(current_thd->variables.max_allowed_packet,
1246 opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
1247 {
1248 DBUG_PRINT("error",("data_len is out of bounds. data_len: %lu", data_len));
1249 result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
1250 LOG_READ_TOO_LARGE);
1251 goto end;
1252 }
1253
1254 /* Append the log event header to packet */
1255 if (packet->append(buf, sizeof(buf)))
1256 {
1257 DBUG_PRINT("info", ("first packet->append failed (out of memory)"));
1258 /* Failed to allocate packet */
1259 result= LOG_READ_MEM;
1260 goto end;
1261 }
1262 data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
1263 if (data_len)
1264 {
1265 /* Append rest of event, read directly from file into packet */
1266 if (packet->append(file, data_len))
1267 {
1268 /*
1269 Fatal error occured when appending rest of the event
1270 to packet, possible failures:
1271 1. EOF occured when reading from file, it's really an error
1272 as data_len is >=0 there's supposed to be more bytes available.
1273 file->error will have been set to number of bytes left to read
1274 2. Read was interrupted, file->error would normally be set to -1
1275 3. Failed to allocate memory for packet, my_errno
1276 will be ENOMEM(file->error shuold be 0, but since the
1277 memory allocation occurs before the call to read it might
1278 be uninitialized)
1279 */
1280 DBUG_PRINT("info", ("second packet->append failed (out of memory)"));
1281 result= (my_errno == ENOMEM ? LOG_READ_MEM :
1282 (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1283 goto end;
1284 }
1285 else
1286 {
1287 /*
1288 Corrupt the event for Dump thread.
1289 We also need to exclude Previous_gtids_log_event and Gtid_log_event
1290 events from injected corruption to allow dump thread to move forward
1291 on binary log until the missing transactions from slave when
1292 MASTER_AUTO_POSITION= 1.
1293 */
1294 DBUG_EXECUTE_IF("corrupt_read_log_event",
1295 uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
1296 if (debug_event_buf_c[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT &&
1297 debug_event_buf_c[EVENT_TYPE_OFFSET] != PREVIOUS_GTIDS_LOG_EVENT &&
1298 debug_event_buf_c[EVENT_TYPE_OFFSET] != GTID_LOG_EVENT)
1299 {
1300 int debug_cor_pos = rand() % (data_len + sizeof(buf) - BINLOG_CHECKSUM_LEN);
1301 debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1302 DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
1303 }
1304 );
1305 /*
1306 CRC verification of the Dump thread
1307 */
1308 if (opt_master_verify_checksum &&
1309 event_checksum_test((uchar*) packet->ptr() + ev_offset,
1310 data_len + sizeof(buf),
1311 checksum_alg_arg))
1312 {
1313 DBUG_PRINT("info", ("checksum test failed"));
1314 result= LOG_READ_CHECKSUM_FAILURE;
1315 goto end;
1316 }
1317 }
1318 }
1319
1320 end:
1321 if (log_lock)
1322 mysql_mutex_unlock(log_lock);
1323 DBUG_PRINT("info", ("read_log_event returns %d", result));
1324 DBUG_RETURN(result);
1325 }
1326 #endif /* !MYSQL_CLIENT */
1327
1328 #ifndef MYSQL_CLIENT
1329 #define UNLOCK_MUTEX if (log_lock) mysql_mutex_unlock(log_lock);
1330 #define LOCK_MUTEX if (log_lock) mysql_mutex_lock(log_lock);
1331 #else
1332 #define UNLOCK_MUTEX
1333 #define LOCK_MUTEX
1334 #endif
1335
1336 #ifndef MYSQL_CLIENT
1337 /**
1338 @note
1339 Allocates memory; The caller is responsible for clean-up.
1340 */
read_log_event(IO_CACHE * file,mysql_mutex_t * log_lock,const Format_description_log_event * description_event,my_bool crc_check)1341 Log_event* Log_event::read_log_event(IO_CACHE* file,
1342 mysql_mutex_t* log_lock,
1343 const Format_description_log_event
1344 *description_event,
1345 my_bool crc_check)
1346 #else
1347 Log_event* Log_event::read_log_event(IO_CACHE* file,
1348 const Format_description_log_event
1349 *description_event,
1350 my_bool crc_check)
1351 #endif
1352 {
1353 DBUG_ENTER("Log_event::read_log_event(IO_CACHE *[, mysql_mutex_t *], Format_description_log_event *, my_bool)");
1354 DBUG_ASSERT(description_event != 0);
1355 char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1356 /*
1357 First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1358 check the event for sanity and to know its length; no need to really parse
1359 it. We say "at most" because this could be a 3.23 master, which has header
1360 of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
1361 "minimal" over the set {MySQL >=4.0}).
1362 */
1363 uint header_size= min<uint>(description_event->common_header_len,
1364 LOG_EVENT_MINIMAL_HEADER_LEN);
1365
1366 LOCK_MUTEX;
1367 DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
1368 if (my_b_read(file, (uchar *) head, header_size))
1369 {
1370 DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) "
1371 "failed in my_b_read((IO_CACHE*)%p, (uchar*)%p, %u)",
1372 file, head, header_size));
1373 UNLOCK_MUTEX;
1374 /*
1375 No error here; it could be that we are at the file's end. However
1376 if the next my_b_read() fails (below), it will be an error as we
1377 were able to read the first bytes.
1378 */
1379 DBUG_RETURN(0);
1380 }
1381 ulong data_len = uint4korr(head + EVENT_LEN_OFFSET);
1382 char *buf= 0;
1383 const char *error= 0;
1384 Log_event *res= 0;
1385 #ifndef max_allowed_packet
1386 THD *thd=current_thd;
1387 uint max_allowed_packet= thd ? slave_max_allowed_packet : ~0U;
1388 #endif
1389
1390 ulong const max_size=
1391 max<ulong>(max_allowed_packet,
1392 opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER);
1393 if (data_len > max_size)
1394 {
1395 error = "Event too big";
1396 goto err;
1397 }
1398
1399 if (data_len < header_size)
1400 {
1401 error = "Event too small";
1402 goto err;
1403 }
1404
1405 // some events use the extra byte to null-terminate strings
1406 if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
1407 {
1408 error = "Out of memory";
1409 goto err;
1410 }
1411 buf[data_len] = 0;
1412 memcpy(buf, head, header_size);
1413 if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1414 {
1415 error = "read error";
1416 goto err;
1417 }
1418 if ((res= read_log_event(buf, data_len, &error, description_event, crc_check)))
1419 res->register_temp_buf(buf);
1420
1421 err:
1422 UNLOCK_MUTEX;
1423 if (!res)
1424 {
1425 DBUG_ASSERT(error != 0);
1426 sql_print_error("Error in Log_event::read_log_event(): "
1427 "'%s', data_len: %lu, event_type: %d",
1428 error,data_len,head[EVENT_TYPE_OFFSET]);
1429 my_free(buf);
1430 /*
1431 The SQL slave thread will check if file->error<0 to know
1432 if there was an I/O error. Even if there is no "low-level" I/O errors
1433 with 'file', any of the high-level above errors is worrying
1434 enough to stop the SQL thread now ; as we are skipping the current event,
1435 going on with reading and successfully executing other events can
1436 only corrupt the slave's databases. So stop.
1437 The file->error is also checked to record the position of
1438 the last valid event when master server recovers.
1439 */
1440 file->error= -1;
1441 }
1442 DBUG_RETURN(res);
1443 }
1444
1445
1446 /**
1447 Binlog format tolerance is in (buf, event_len, description_event)
1448 constructors.
1449 */
1450
read_log_event(const char * buf,uint event_len,const char ** error,const Format_description_log_event * description_event,my_bool crc_check)1451 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1452 const char **error,
1453 const Format_description_log_event *description_event,
1454 my_bool crc_check)
1455 {
1456 Log_event* ev;
1457 uint8 alg;
1458 DBUG_ENTER("Log_event::read_log_event(char *, uint, char **, Format_description_log_event *, my_bool)");
1459 DBUG_ASSERT(description_event != 0);
1460 DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1461 DBUG_DUMP("data", (unsigned char*) buf, event_len);
1462
1463 /* Check the integrity */
1464 if (event_len < EVENT_LEN_OFFSET ||
1465 (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1466 {
1467 DBUG_PRINT("error", ("event_len=%u EVENT_LEN_OFFSET=%d "
1468 "buf[EVENT_TYPE_OFFSET]=%d ENUM_END_EVENT=%d "
1469 "uint4korr(buf+EVENT_LEN_OFFSET)=%d",
1470 event_len, EVENT_LEN_OFFSET,
1471 buf[EVENT_TYPE_OFFSET], ENUM_END_EVENT,
1472 uint4korr(buf+EVENT_LEN_OFFSET)));
1473 *error="Sanity check failed"; // Needed to free buffer
1474 DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1475 }
1476
1477 uint event_type= buf[EVENT_TYPE_OFFSET];
1478 // all following START events in the current file are without checksum
1479 if (event_type == START_EVENT_V3)
1480 (const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
1481 // Sanity check for Format description event
1482 if (event_type == FORMAT_DESCRIPTION_EVENT)
1483 {
1484 if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN +
1485 ST_COMMON_HEADER_LEN_OFFSET)
1486 {
1487 *error= "Found invalid Format description event in binary log";
1488 DBUG_RETURN(0);
1489 }
1490 uint tmp_header_len= buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET];
1491 if (event_len < tmp_header_len + ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
1492 {
1493 *error= "Found invalid Format description event in binary log";
1494 DBUG_RETURN(0);
1495 }
1496 }
1497 /*
1498 CRC verification by SQL and Show-Binlog-Events master side.
1499 The caller has to provide @description_event->checksum_alg to
1500 be the last seen FD's (A) descriptor.
1501 If event is FD the descriptor is in it.
1502 Notice, FD of the binlog can be only in one instance and therefore
1503 Show-Binlog-Events executing master side thread needs just to know
1504 the only FD's (A) value - whereas RL can contain more.
1505 In the RL case, the alg is kept in FD_e (@description_event) which is reset
1506 to the newer read-out event after its execution with possibly new alg descriptor.
1507 Therefore in a typical sequence of RL:
1508 {FD_s^0, FD_m, E_m^1} E_m^1
1509 will be verified with (A) of FD_m.
1510
1511 See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
1512 lines (log.h).
1513
1514 Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
1515 */
1516 alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
1517 description_event->checksum_alg : get_checksum_alg(buf, event_len);
1518 // Emulate the corruption during reading an event
1519 DBUG_EXECUTE_IF("corrupt_read_log_event_char",
1520 if (event_type != FORMAT_DESCRIPTION_EVENT)
1521 {
1522 char *debug_event_buf_c = (char *)buf;
1523 int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
1524 debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1525 DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
1526 DBUG_SET("");
1527 }
1528 );
1529 if (crc_check &&
1530 event_checksum_test((uchar *) buf, event_len, alg) &&
1531 /* Skip the crc check when simulating an unknown ignorable log event. */
1532 !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1533 {
1534 *error= "Event crc check failed! Most likely there is event corruption.";
1535 #ifdef MYSQL_CLIENT
1536 if (force_opt)
1537 {
1538 ev= new Unknown_log_event(buf, description_event);
1539 DBUG_RETURN(ev);
1540 }
1541 #endif
1542 DBUG_RETURN(NULL);
1543 }
1544
1545 if (event_type > description_event->number_of_event_types &&
1546 event_type != FORMAT_DESCRIPTION_EVENT &&
1547 /*
1548 Skip the event type check when simulating an
1549 unknown ignorable log event.
1550 */
1551 !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1552 {
1553 /*
1554 It is unsafe to use the description_event if its post_header_len
1555 array does not include the event type.
1556 */
1557 DBUG_PRINT("error", ("event type %d found, but the current "
1558 "Format_description_log_event supports only %d event "
1559 "types", event_type,
1560 description_event->number_of_event_types));
1561 ev= NULL;
1562 }
1563 else
1564 {
1565 /*
1566 In some previuos versions (see comment in
1567 Format_description_log_event::Format_description_log_event(char*,...)),
1568 event types were assigned different id numbers than in the
1569 present version. In order to replicate from such versions to the
1570 present version, we must map those event type id's to our event
1571 type id's. The mapping is done with the event_type_permutation
1572 array, which was set up when the Format_description_log_event
1573 was read.
1574 */
1575 if (description_event->event_type_permutation)
1576 {
1577 uint new_event_type;
1578 if (event_type >= EVENT_TYPE_PERMUTATION_NUM)
1579 /* Safe guard for read out of bounds of event_type_permutation. */
1580 new_event_type= UNKNOWN_EVENT;
1581 else
1582 new_event_type= description_event->event_type_permutation[event_type];
1583
1584 DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1585 event_type, new_event_type,
1586 get_type_str((Log_event_type)new_event_type)));
1587 event_type= new_event_type;
1588 }
1589
1590 if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
1591 (event_type == FORMAT_DESCRIPTION_EVENT ||
1592 alg != BINLOG_CHECKSUM_ALG_OFF))
1593 event_len= event_len - BINLOG_CHECKSUM_LEN;
1594
1595 switch(event_type) {
1596 case QUERY_EVENT:
1597 ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1598 break;
1599 case LOAD_EVENT:
1600 ev = new Load_log_event(buf, event_len, description_event);
1601 break;
1602 case NEW_LOAD_EVENT:
1603 ev = new Load_log_event(buf, event_len, description_event);
1604 break;
1605 case ROTATE_EVENT:
1606 ev = new Rotate_log_event(buf, event_len, description_event);
1607 break;
1608 case CREATE_FILE_EVENT:
1609 ev = new Create_file_log_event(buf, event_len, description_event);
1610 break;
1611 case APPEND_BLOCK_EVENT:
1612 ev = new Append_block_log_event(buf, event_len, description_event);
1613 break;
1614 case DELETE_FILE_EVENT:
1615 ev = new Delete_file_log_event(buf, event_len, description_event);
1616 break;
1617 case EXEC_LOAD_EVENT:
1618 ev = new Execute_load_log_event(buf, event_len, description_event);
1619 break;
1620 case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1621 ev = new Start_log_event_v3(buf, event_len, description_event);
1622 break;
1623 case STOP_EVENT:
1624 ev = new Stop_log_event(buf, description_event);
1625 break;
1626 case INTVAR_EVENT:
1627 ev = new Intvar_log_event(buf, description_event);
1628 break;
1629 case XID_EVENT:
1630 ev = new Xid_log_event(buf, description_event);
1631 break;
1632 case RAND_EVENT:
1633 ev = new Rand_log_event(buf, description_event);
1634 break;
1635 case USER_VAR_EVENT:
1636 ev = new User_var_log_event(buf, event_len, description_event);
1637 break;
1638 case FORMAT_DESCRIPTION_EVENT:
1639 ev = new Format_description_log_event(buf, event_len, description_event);
1640 break;
1641 #if defined(HAVE_REPLICATION)
1642 case PRE_GA_WRITE_ROWS_EVENT:
1643 ev = new Write_rows_log_event_old(buf, event_len, description_event);
1644 break;
1645 case PRE_GA_UPDATE_ROWS_EVENT:
1646 ev = new Update_rows_log_event_old(buf, event_len, description_event);
1647 break;
1648 case PRE_GA_DELETE_ROWS_EVENT:
1649 ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1650 break;
1651 case WRITE_ROWS_EVENT_V1:
1652 ev = new Write_rows_log_event(buf, event_len, description_event);
1653 break;
1654 case UPDATE_ROWS_EVENT_V1:
1655 ev = new Update_rows_log_event(buf, event_len, description_event);
1656 break;
1657 case DELETE_ROWS_EVENT_V1:
1658 ev = new Delete_rows_log_event(buf, event_len, description_event);
1659 break;
1660 case TABLE_MAP_EVENT:
1661 ev = new Table_map_log_event(buf, event_len, description_event);
1662 break;
1663 #endif
1664 case BEGIN_LOAD_QUERY_EVENT:
1665 ev = new Begin_load_query_log_event(buf, event_len, description_event);
1666 break;
1667 case EXECUTE_LOAD_QUERY_EVENT:
1668 ev= new Execute_load_query_log_event(buf, event_len, description_event);
1669 break;
1670 case INCIDENT_EVENT:
1671 ev = new Incident_log_event(buf, event_len, description_event);
1672 break;
1673 case ROWS_QUERY_LOG_EVENT:
1674 ev= new Rows_query_log_event(buf, event_len, description_event);
1675 break;
1676 case GTID_LOG_EVENT:
1677 case ANONYMOUS_GTID_LOG_EVENT:
1678 ev= new Gtid_log_event(buf, event_len, description_event);
1679 break;
1680 case PREVIOUS_GTIDS_LOG_EVENT:
1681 ev= new Previous_gtids_log_event(buf, event_len, description_event);
1682 break;
1683 #if defined(HAVE_REPLICATION)
1684 case WRITE_ROWS_EVENT:
1685 ev = new Write_rows_log_event(buf, event_len, description_event);
1686 break;
1687 case UPDATE_ROWS_EVENT:
1688 ev = new Update_rows_log_event(buf, event_len, description_event);
1689 break;
1690 case DELETE_ROWS_EVENT:
1691 ev = new Delete_rows_log_event(buf, event_len, description_event);
1692 break;
1693 #endif
1694 default:
1695 /*
1696 Create an object of Ignorable_log_event for unrecognized sub-class.
1697 So that SLAVE SQL THREAD will only update the position and continue.
1698 */
1699 if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1700 {
1701 ev= new Ignorable_log_event(buf, description_event);
1702 }
1703 else
1704 {
1705 DBUG_PRINT("error",("Unknown event code: %d",
1706 (int) buf[EVENT_TYPE_OFFSET]));
1707 ev= NULL;
1708 }
1709 break;
1710 }
1711 }
1712
1713 if (ev)
1714 {
1715 ev->checksum_alg= alg;
1716 if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1717 ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1718 ev->crc= uint4korr(buf + (event_len));
1719 }
1720
1721 DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1722 ev ? ev->get_type_str() : "<unknown>",
1723 buf[EVENT_TYPE_OFFSET],
1724 event_len));
1725 /*
1726 is_valid() are small event-specific sanity tests which are
1727 important; for example there are some my_malloc() in constructors
1728 (e.g. Query_log_event::Query_log_event(char*...)); when these
1729 my_malloc() fail we can't return an error out of the constructor
1730 (because constructor is "void") ; so instead we leave the pointer we
1731 wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1732 Same for Format_description_log_event, member 'post_header_len'.
1733
1734 SLAVE_EVENT is never used, so it should not be read ever.
1735 */
1736 if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
1737 {
1738 DBUG_PRINT("error",("Found invalid event in binary log"));
1739
1740 delete ev;
1741 #ifdef MYSQL_CLIENT
1742 if (!force_opt) /* then mysqlbinlog dies */
1743 {
1744 *error= "Found invalid event in binary log";
1745 DBUG_RETURN(0);
1746 }
1747 ev= new Unknown_log_event(buf, description_event);
1748 #else
1749 *error= "Found invalid event in binary log";
1750 DBUG_RETURN(0);
1751 #endif
1752 }
1753 DBUG_RETURN(ev);
1754 }
1755
1756 #ifdef MYSQL_CLIENT
1757
1758 /*
1759 Log_event::print_header()
1760 */
1761
print_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool is_more MY_ATTRIBUTE ((unused)))1762 void Log_event::print_header(IO_CACHE* file,
1763 PRINT_EVENT_INFO* print_event_info,
1764 bool is_more MY_ATTRIBUTE((unused)))
1765 {
1766 char llbuff[22];
1767 my_off_t hexdump_from= print_event_info->hexdump_from;
1768 DBUG_ENTER("Log_event::print_header");
1769
1770 my_b_printf(file, "#");
1771 print_timestamp(file, NULL);
1772 my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
1773 llstr(log_pos,llbuff));
1774
1775 /* print the checksum */
1776
1777 if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1778 checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1779 {
1780 char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
1781 size_t const bytes_written=
1782 my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
1783 my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
1784 my_b_printf(file, checksum_buf, bytes_written);
1785 }
1786
1787 /* mysqlbinlog --hexdump */
1788 if (print_event_info->hexdump_from)
1789 {
1790 my_b_printf(file, "\n");
1791 uchar *ptr= (uchar*)temp_buf;
1792 my_off_t size=
1793 uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1794 my_off_t i;
1795
1796 /* Header len * 4 >= header len * (2 chars + space + extra space) */
1797 char *h, hex_string[49]= {0};
1798 char *c, char_string[16+1]= {0};
1799
1800 /* Pretty-print event common header if header is exactly 19 bytes */
1801 if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1802 {
1803 char emit_buf[256]; // Enough for storing one line
1804 my_b_printf(file, "# Position Timestamp Type Master ID "
1805 "Size Master Pos Flags \n");
1806 size_t const bytes_written=
1807 my_snprintf(emit_buf, sizeof(emit_buf),
1808 "# %8.8lx %02x %02x %02x %02x %02x "
1809 "%02x %02x %02x %02x %02x %02x %02x %02x "
1810 "%02x %02x %02x %02x %02x %02x\n",
1811 (unsigned long) hexdump_from,
1812 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1813 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1814 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1815 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1816 my_b_write(file, (uchar*) emit_buf, bytes_written);
1817 ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1818 hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1819 }
1820
1821 /* Rest of event (without common header) */
1822 for (i= 0, c= char_string, h=hex_string;
1823 i < size;
1824 i++, ptr++)
1825 {
1826 my_snprintf(h, 4, (i % 16 <= 7) ? "%02x " : " %02x", *ptr);
1827 h += 3;
1828
1829 *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1830
1831 if (i % 16 == 15)
1832 {
1833 /*
1834 my_b_printf() does not support full printf() formats, so we
1835 have to do it this way.
1836
1837 TODO: Rewrite my_b_printf() to support full printf() syntax.
1838 */
1839 char emit_buf[256];
1840 size_t const bytes_written=
1841 my_snprintf(emit_buf, sizeof(emit_buf),
1842 "# %8.8lx %-48.48s |%16s|\n",
1843 (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1844 hex_string, char_string);
1845 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1846 my_b_write(file, (uchar*) emit_buf, bytes_written);
1847 hex_string[0]= 0;
1848 char_string[0]= 0;
1849 c= char_string;
1850 h= hex_string;
1851 }
1852 }
1853 *c= '\0';
1854 DBUG_ASSERT(hex_string[48] == 0);
1855
1856 if (hex_string[0])
1857 {
1858 char emit_buf[256];
1859 // Right-pad hex_string with spaces, up to 48 characters.
1860 memset(h, ' ', (sizeof(hex_string) -1) - (h - hex_string));
1861 size_t const bytes_written=
1862 my_snprintf(emit_buf, sizeof(emit_buf),
1863 "# %8.8lx %-48.48s |%s|\n",
1864 (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1865 hex_string, char_string);
1866 DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1867 my_b_write(file, (uchar*) emit_buf, bytes_written);
1868 }
1869 /*
1870 need a # to prefix the rest of printouts for example those of
1871 Rows_log_event::print_helper().
1872 */
1873 my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1874 }
1875 DBUG_VOID_RETURN;
1876 }
1877
1878
1879 /**
1880 Prints a quoted string to io cache.
1881 Control characters are displayed as hex sequence, e.g. \x00
1882
1883 @param[in] file IO cache
1884 @param[in] prt Pointer to string
1885 @param[in] length String length
1886 */
1887
1888 static void
my_b_write_quoted(IO_CACHE * file,const uchar * ptr,uint length)1889 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
1890 {
1891 const uchar *s;
1892 my_b_printf(file, "'");
1893 for (s= ptr; length > 0 ; s++, length--)
1894 {
1895 if (*s > 0x1F && *s != '\'' && *s != '\\')
1896 my_b_write(file, s, 1);
1897 else
1898 {
1899 uchar hex[10];
1900 size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
1901 my_b_write(file, hex, len);
1902 }
1903 }
1904 my_b_printf(file, "'");
1905 }
1906
1907 /**
1908 Prints a bit string to io cache in format b'1010'.
1909
1910 @param[in] file IO cache
1911 @param[in] ptr Pointer to string
1912 @param[in] nbits Number of bits
1913 */
1914 static void
my_b_write_bit(IO_CACHE * file,const uchar * ptr,uint nbits)1915 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
1916 {
1917 uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
1918 my_b_printf(file, "b'");
1919 for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
1920 {
1921 int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
1922 my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
1923 }
1924 my_b_printf(file, "'");
1925 }
1926
1927
1928 /**
1929 Prints a packed string to io cache.
1930 The string consists of length packed to 1 or 2 bytes,
1931 followed by string data itself.
1932
1933 @param[in] file IO cache
1934 @param[in] ptr Pointer to string
1935 @param[in] length String size
1936
1937 @retval - number of bytes scanned.
1938 */
1939 static size_t
my_b_write_quoted_with_length(IO_CACHE * file,const uchar * ptr,uint length)1940 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
1941 {
1942 if (length < 256)
1943 {
1944 length= *ptr;
1945 my_b_write_quoted(file, ptr + 1, length);
1946 return length + 1;
1947 }
1948 else
1949 {
1950 length= uint2korr(ptr);
1951 my_b_write_quoted(file, ptr + 2, length);
1952 return length + 2;
1953 }
1954 }
1955
1956
1957 /**
1958 Prints a 32-bit number in both signed and unsigned representation
1959
1960 @param[in] file IO cache
1961 @param[in] sl Signed number
1962 @param[in] ul Unsigned number
1963 */
1964 static void
my_b_write_sint32_and_uint32(IO_CACHE * file,int32 si,uint32 ui)1965 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
1966 {
1967 my_b_printf(file, "%d", si);
1968 if (si < 0)
1969 my_b_printf(file, " (%u)", ui);
1970 }
1971
1972
1973 /**
1974 Print a packed value of the given SQL type into IO cache
1975
1976 @param[in] file IO cache
1977 @param[in] ptr Pointer to string
1978 @param[in] type Column type
1979 @param[in] meta Column meta information
1980 @param[out] typestr SQL type string buffer (for verbose output)
1981 @param[out] typestr_length Size of typestr
1982
1983 @retval - number of bytes scanned from ptr.
1984 */
1985 static size_t
log_event_print_value(IO_CACHE * file,const uchar * ptr,uint type,uint meta,char * typestr,size_t typestr_length)1986 log_event_print_value(IO_CACHE *file, const uchar *ptr,
1987 uint type, uint meta,
1988 char *typestr, size_t typestr_length)
1989 {
1990 uint32 length= 0;
1991
1992 if (type == MYSQL_TYPE_STRING)
1993 {
1994 if (meta >= 256)
1995 {
1996 uint byte0= meta >> 8;
1997 uint byte1= meta & 0xFF;
1998
1999 if ((byte0 & 0x30) != 0x30)
2000 {
2001 /* a long CHAR() field: see #37426 */
2002 length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
2003 type= byte0 | 0x30;
2004 }
2005 else
2006 length = meta & 0xFF;
2007 }
2008 else
2009 length= meta;
2010 }
2011
2012 switch (type) {
2013 case MYSQL_TYPE_LONG:
2014 {
2015 int32 si= sint4korr(ptr);
2016 uint32 ui= uint4korr(ptr);
2017 my_b_write_sint32_and_uint32(file, si, ui);
2018 my_snprintf(typestr, typestr_length, "INT");
2019 return 4;
2020 }
2021
2022 case MYSQL_TYPE_TINY:
2023 {
2024 my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
2025 (uint) (unsigned char) *ptr);
2026 my_snprintf(typestr, typestr_length, "TINYINT");
2027 return 1;
2028 }
2029
2030 case MYSQL_TYPE_SHORT:
2031 {
2032 int32 si= (int32) sint2korr(ptr);
2033 uint32 ui= (uint32) uint2korr(ptr);
2034 my_b_write_sint32_and_uint32(file, si, ui);
2035 my_snprintf(typestr, typestr_length, "SHORTINT");
2036 return 2;
2037 }
2038
2039 case MYSQL_TYPE_INT24:
2040 {
2041 int32 si= sint3korr(ptr);
2042 uint32 ui= uint3korr(ptr);
2043 my_b_write_sint32_and_uint32(file, si, ui);
2044 my_snprintf(typestr, typestr_length, "MEDIUMINT");
2045 return 3;
2046 }
2047
2048 case MYSQL_TYPE_LONGLONG:
2049 {
2050 char tmp[64];
2051 longlong si= sint8korr(ptr);
2052 longlong10_to_str(si, tmp, -10);
2053 my_b_printf(file, "%s", tmp);
2054 if (si < 0)
2055 {
2056 ulonglong ui= uint8korr(ptr);
2057 longlong10_to_str((longlong) ui, tmp, 10);
2058 my_b_printf(file, " (%s)", tmp);
2059 }
2060 my_snprintf(typestr, typestr_length, "LONGINT");
2061 return 8;
2062 }
2063
2064 case MYSQL_TYPE_NEWDECIMAL:
2065 {
2066 uint precision= meta >> 8;
2067 uint decimals= meta & 0xFF;
2068 uint bin_size= my_decimal_get_binary_size(precision, decimals);
2069 my_decimal dec;
2070 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2071 precision, decimals);
2072 int len= DECIMAL_MAX_STR_LENGTH;
2073 char buff[DECIMAL_MAX_STR_LENGTH + 1];
2074 decimal2string(&dec,buff,&len, 0, 0, 0);
2075 my_b_printf(file, "%s", buff);
2076 my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2077 precision, decimals);
2078 return bin_size;
2079 }
2080
2081 case MYSQL_TYPE_FLOAT:
2082 {
2083 float fl;
2084 float4get(fl, ptr);
2085 char tmp[320];
2086 sprintf(tmp, "%-20g", (double) fl);
2087 my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2088 my_snprintf(typestr, typestr_length, "FLOAT");
2089 return 4;
2090 }
2091
2092 case MYSQL_TYPE_DOUBLE:
2093 {
2094 double dbl;
2095 float8get(dbl, ptr);
2096 char tmp[320];
2097 sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
2098 my_b_printf(file, "%s", tmp);
2099 strcpy(typestr, "DOUBLE");
2100 return 8;
2101 }
2102
2103 case MYSQL_TYPE_BIT:
2104 {
2105 /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2106 uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2107 length= (nbits + 7) / 8;
2108 my_b_write_bit(file, ptr, nbits);
2109 my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2110 return length;
2111 }
2112
2113 case MYSQL_TYPE_TIMESTAMP:
2114 {
2115 uint32 i32= uint4korr(ptr);
2116 my_b_printf(file, "%d", i32);
2117 my_snprintf(typestr, typestr_length, "TIMESTAMP");
2118 return 4;
2119 }
2120
2121 case MYSQL_TYPE_TIMESTAMP2:
2122 {
2123 char buf[MAX_DATE_STRING_REP_LENGTH];
2124 struct timeval tm;
2125 my_timestamp_from_binary(&tm, ptr, meta);
2126 int buflen= my_timeval_to_str(&tm, buf, meta);
2127 my_b_write(file, buf, buflen);
2128 my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2129 return my_timestamp_binary_length(meta);
2130 }
2131
2132 case MYSQL_TYPE_DATETIME:
2133 {
2134 size_t d, t;
2135 uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2136 d= i64 / 1000000;
2137 t= i64 % 1000000;
2138 my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
2139 static_cast<int>(d / 10000),
2140 static_cast<int>(d % 10000) / 100,
2141 static_cast<int>(d % 100),
2142 static_cast<int>(t / 10000),
2143 static_cast<int>(t % 10000) / 100,
2144 static_cast<int>(t % 100));
2145 my_snprintf(typestr, typestr_length, "DATETIME");
2146 return 8;
2147 }
2148
2149 case MYSQL_TYPE_DATETIME2:
2150 {
2151 char buf[MAX_DATE_STRING_REP_LENGTH];
2152 MYSQL_TIME ltime;
2153 longlong packed= my_datetime_packed_from_binary(ptr, meta);
2154 TIME_from_longlong_datetime_packed(<ime, packed);
2155 int buflen= my_datetime_to_str(<ime, buf, meta);
2156 my_b_write_quoted(file, (uchar *) buf, buflen);
2157 my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2158 return my_datetime_binary_length(meta);
2159 }
2160
2161 case MYSQL_TYPE_TIME:
2162 {
2163 uint32 i32= uint3korr(ptr);
2164 my_b_printf(file, "'%02d:%02d:%02d'",
2165 i32 / 10000, (i32 % 10000) / 100, i32 % 100);
2166 my_snprintf(typestr, typestr_length, "TIME");
2167 return 3;
2168 }
2169
2170 case MYSQL_TYPE_TIME2:
2171 {
2172 char buf[MAX_DATE_STRING_REP_LENGTH];
2173 MYSQL_TIME ltime;
2174 longlong packed= my_time_packed_from_binary(ptr, meta);
2175 TIME_from_longlong_time_packed(<ime, packed);
2176 int buflen= my_time_to_str(<ime, buf, meta);
2177 my_b_write_quoted(file, (uchar *) buf, buflen);
2178 my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2179 return my_time_binary_length(meta);
2180 }
2181
2182 case MYSQL_TYPE_NEWDATE:
2183 {
2184 uint32 tmp= uint3korr(ptr);
2185 int part;
2186 char buf[11];
2187 char *pos= &buf[10]; // start from '\0' to the beginning
2188
2189 /* Copied from field.cc */
2190 *pos--=0; // End NULL
2191 part=(int) (tmp & 31);
2192 *pos--= (char) ('0'+part%10);
2193 *pos--= (char) ('0'+part/10);
2194 *pos--= ':';
2195 part=(int) (tmp >> 5 & 15);
2196 *pos--= (char) ('0'+part%10);
2197 *pos--= (char) ('0'+part/10);
2198 *pos--= ':';
2199 part=(int) (tmp >> 9);
2200 *pos--= (char) ('0'+part%10); part/=10;
2201 *pos--= (char) ('0'+part%10); part/=10;
2202 *pos--= (char) ('0'+part%10); part/=10;
2203 *pos= (char) ('0'+part);
2204 my_b_printf(file , "'%s'", buf);
2205 my_snprintf(typestr, typestr_length, "DATE");
2206 return 3;
2207 }
2208
2209 case MYSQL_TYPE_YEAR:
2210 {
2211 uint32 i32= *ptr;
2212 my_b_printf(file, "%04d", i32+ 1900);
2213 my_snprintf(typestr, typestr_length, "YEAR");
2214 return 1;
2215 }
2216
2217 case MYSQL_TYPE_ENUM:
2218 switch (meta & 0xFF) {
2219 case 1:
2220 my_b_printf(file, "%d", (int) *ptr);
2221 my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
2222 return 1;
2223 case 2:
2224 {
2225 int32 i32= uint2korr(ptr);
2226 my_b_printf(file, "%d", i32);
2227 my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
2228 return 2;
2229 }
2230 default:
2231 my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2232 return 0;
2233 }
2234 break;
2235
2236 case MYSQL_TYPE_SET:
2237 my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2238 my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2239 return meta & 0xFF;
2240
2241 case MYSQL_TYPE_BLOB:
2242 switch (meta) {
2243 case 1:
2244 length= *ptr;
2245 my_b_write_quoted(file, ptr + 1, length);
2246 my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
2247 return length + 1;
2248 case 2:
2249 length= uint2korr(ptr);
2250 my_b_write_quoted(file, ptr + 2, length);
2251 my_snprintf(typestr, typestr_length, "BLOB/TEXT");
2252 return length + 2;
2253 case 3:
2254 length= uint3korr(ptr);
2255 my_b_write_quoted(file, ptr + 3, length);
2256 my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
2257 return length + 3;
2258 case 4:
2259 length= uint4korr(ptr);
2260 my_b_write_quoted(file, ptr + 4, length);
2261 my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
2262 return length + 4;
2263 default:
2264 my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2265 return 0;
2266 }
2267
2268 case MYSQL_TYPE_VARCHAR:
2269 case MYSQL_TYPE_VAR_STRING:
2270 length= meta;
2271 my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
2272 return my_b_write_quoted_with_length(file, ptr, length);
2273
2274 case MYSQL_TYPE_STRING:
2275 my_snprintf(typestr, typestr_length, "STRING(%d)", length);
2276 return my_b_write_quoted_with_length(file, ptr, length);
2277
2278 default:
2279 {
2280 char tmp[5];
2281 my_snprintf(tmp, sizeof(tmp), "%04x", meta);
2282 my_b_printf(file,
2283 "!! Don't know how to handle column type=%d meta=%d (%s)",
2284 type, meta, tmp);
2285 }
2286 break;
2287 }
2288 *typestr= 0;
2289 return 0;
2290 }
2291
2292
2293 /**
2294 Print a packed row into IO cache
2295
2296 @param[in] file IO cache
2297 @param[in] td Table definition
2298 @param[in] print_event_into Print parameters
2299 @param[in] cols_bitmap Column bitmaps.
2300 @param[in] value Pointer to packed row
2301 @param[in] prefix Row's SQL clause ("SET", "WHERE", etc)
2302
2303 @retval - number of bytes scanned.
2304 */
2305
2306
2307 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)2308 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
2309 PRINT_EVENT_INFO *print_event_info,
2310 MY_BITMAP *cols_bitmap,
2311 const uchar *value, const uchar *prefix)
2312 {
2313 const uchar *value0= value;
2314 const uchar *null_bits= value;
2315 uint null_bit_index= 0;
2316 char typestr[64]= "";
2317
2318 /*
2319 Skip metadata bytes which gives the information about nullabity of master
2320 columns. Master writes one bit for each affected column.
2321 */
2322 value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
2323
2324 my_b_printf(file, "%s", prefix);
2325
2326 for (size_t i= 0; i < td->size(); i ++)
2327 {
2328 int is_null= (null_bits[null_bit_index / 8]
2329 >> (null_bit_index % 8)) & 0x01;
2330
2331 if (bitmap_is_set(cols_bitmap, i) == 0)
2332 continue;
2333
2334 if (is_null)
2335 {
2336 my_b_printf(file, "### @%d=NULL", static_cast<int>(i + 1));
2337 }
2338 else
2339 {
2340 my_b_printf(file, "### @%d=", static_cast<int>(i + 1));
2341 size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
2342 if (value + fsize > m_rows_end)
2343 {
2344 my_b_printf(file, "***Corrupted replication event was detected."
2345 " Not printing the value***\n");
2346 value+= fsize;
2347 return 0;
2348 }
2349 size_t size= log_event_print_value(file, value,
2350 td->type(i), td->field_metadata(i),
2351 typestr, sizeof(typestr));
2352 if (!size)
2353 return 0;
2354
2355 value+= size;
2356 }
2357
2358 if (print_event_info->verbose > 1)
2359 {
2360 my_b_printf(file, " /* ");
2361
2362 if (typestr[0])
2363 my_b_printf(file, "%s ", typestr);
2364 else
2365 my_b_printf(file, "type=%d ", td->type(i));
2366
2367 my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
2368 td->field_metadata(i),
2369 td->maybe_null(i), is_null);
2370 my_b_printf(file, "*/");
2371 }
2372
2373 my_b_printf(file, "\n");
2374
2375 null_bit_index++;
2376 }
2377 return value - value0;
2378 }
2379
2380
2381 /**
2382 Print a row event into IO cache in human readable form (in SQL format)
2383
2384 @param[in] file IO cache
2385 @param[in] print_event_into Print parameters
2386 */
print_verbose(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)2387 void Rows_log_event::print_verbose(IO_CACHE *file,
2388 PRINT_EVENT_INFO *print_event_info)
2389 {
2390 // Quoted length of the identifier can be twice the original length
2391 char quoted_db[1 + NAME_LEN * 2 + 2];
2392 char quoted_table[1 + NAME_LEN * 2 + 2];
2393 int quoted_db_len, quoted_table_len;
2394 Table_map_log_event *map;
2395 table_def *td;
2396 const char *sql_command, *sql_clause1, *sql_clause2;
2397 Log_event_type general_type_code= get_general_type_code();
2398
2399 if (m_extra_row_data)
2400 {
2401 uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
2402 uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
2403 assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
2404
2405 my_b_printf(file, "### Extra row data format: %u, len: %u :",
2406 m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
2407 extra_payload_len);
2408 if (extra_payload_len)
2409 {
2410 /*
2411 Buffer for hex view of string, including '0x' prefix,
2412 2 hex chars / byte and trailing 0
2413 */
2414 const int buff_len= 2 + (256 * 2) + 1;
2415 char buff[buff_len];
2416 str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
2417 extra_payload_len);
2418 my_b_printf(file, "%s", buff);
2419 }
2420 my_b_printf(file, "\n");
2421 }
2422
2423 switch (general_type_code) {
2424 case WRITE_ROWS_EVENT:
2425 sql_command= "INSERT INTO";
2426 sql_clause1= "### SET\n";
2427 sql_clause2= NULL;
2428 break;
2429 case DELETE_ROWS_EVENT:
2430 sql_command= "DELETE FROM";
2431 sql_clause1= "### WHERE\n";
2432 sql_clause2= NULL;
2433 break;
2434 case UPDATE_ROWS_EVENT:
2435 sql_command= "UPDATE";
2436 sql_clause1= "### WHERE\n";
2437 sql_clause2= "### SET\n";
2438 break;
2439 default:
2440 sql_command= sql_clause1= sql_clause2= NULL;
2441 DBUG_ASSERT(0); /* Not possible */
2442 }
2443
2444 if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2445 !(td= map->create_table_def()))
2446 {
2447 char llbuff[22];
2448 my_b_printf(file, "### Row event for unknown table #%s",
2449 llstr(m_table_id, llbuff));
2450 return;
2451 }
2452
2453 /* If the write rows event contained no values for the AI */
2454 if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
2455 {
2456 my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
2457 map->get_db_name(), map->get_table_name());
2458 goto end;
2459 }
2460
2461 for (const uchar *value= m_rows_buf; value < m_rows_end; )
2462 {
2463 size_t length;
2464 #ifdef MYSQL_SERVER
2465 quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2466 map->get_db_name(), 0);
2467 quoted_table_len= my_strmov_quoted_identifier(this->thd,
2468 (char *) quoted_table,
2469 map->get_table_name(), 0);
2470 #else
2471 quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2472 map->get_db_name());
2473 quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2474 map->get_table_name());
2475 #endif
2476 quoted_db[quoted_db_len]= '\0';
2477 quoted_table[quoted_table_len]= '\0';
2478 my_b_printf(file, "### %s %s.%s\n",
2479 sql_command,
2480 quoted_db, quoted_table);
2481 /* Print the first image */
2482 if (!(length= print_verbose_one_row(file, td, print_event_info,
2483 &m_cols, value,
2484 (const uchar*) sql_clause1)))
2485 goto end;
2486 value+= length;
2487
2488 /* Print the second image (for UPDATE only) */
2489 if (sql_clause2)
2490 {
2491 if (!(length= print_verbose_one_row(file, td, print_event_info,
2492 &m_cols_ai, value,
2493 (const uchar*) sql_clause2)))
2494 goto end;
2495 value+= length;
2496 }
2497 }
2498
2499 end:
2500 delete td;
2501 }
2502
2503 #ifdef MYSQL_CLIENT
free_table_map_log_event(Table_map_log_event * event)2504 void free_table_map_log_event(Table_map_log_event *event)
2505 {
2506 delete event;
2507 }
2508 #endif
2509
print_base64(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool more)2510 void Log_event::print_base64(IO_CACHE* file,
2511 PRINT_EVENT_INFO* print_event_info,
2512 bool more)
2513 {
2514 const uchar *ptr= (const uchar *)temp_buf;
2515 uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2516 DBUG_ENTER("Log_event::print_base64");
2517
2518 uint64 const tmp_str_sz= base64_needed_encoded_length((uint64) size);
2519 char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
2520 if (!tmp_str) {
2521 fprintf(stderr, "\nError: Out of memory. "
2522 "Could not print correct binlog event.\n");
2523 DBUG_VOID_RETURN;
2524 }
2525
2526 if (base64_encode(ptr, (size_t) size, tmp_str))
2527 {
2528 DBUG_ASSERT(0);
2529 }
2530
2531 if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2532 {
2533 if (my_b_tell(file) == 0)
2534 my_b_printf(file, "\nBINLOG '\n");
2535
2536 my_b_printf(file, "%s\n", tmp_str);
2537
2538 if (!more)
2539 my_b_printf(file, "'%s\n", print_event_info->delimiter);
2540 }
2541
2542 if (print_event_info->verbose)
2543 {
2544 Rows_log_event *ev= NULL;
2545 Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
2546
2547 if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
2548 checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
2549 size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
2550
2551 switch(et)
2552 {
2553 case TABLE_MAP_EVENT:
2554 {
2555 Table_map_log_event *map;
2556 map= new Table_map_log_event((const char*) ptr, size,
2557 glob_description_event);
2558 print_event_info->m_table_map.set_table(map->get_table_id(), map);
2559 break;
2560 }
2561 case WRITE_ROWS_EVENT:
2562 case WRITE_ROWS_EVENT_V1:
2563 {
2564 ev= new Write_rows_log_event((const char*) ptr, size,
2565 glob_description_event);
2566 break;
2567 }
2568 case DELETE_ROWS_EVENT:
2569 case DELETE_ROWS_EVENT_V1:
2570 {
2571 ev= new Delete_rows_log_event((const char*) ptr, size,
2572 glob_description_event);
2573 break;
2574 }
2575 case UPDATE_ROWS_EVENT:
2576 case UPDATE_ROWS_EVENT_V1:
2577 {
2578 ev= new Update_rows_log_event((const char*) ptr, size,
2579 glob_description_event);
2580 break;
2581 }
2582 default:
2583 break;
2584 }
2585
2586 if (ev)
2587 {
2588 ev->print_verbose(file, print_event_info);
2589 delete ev;
2590 }
2591 }
2592
2593 my_free(tmp_str);
2594 DBUG_VOID_RETURN;
2595 }
2596
2597
2598 /*
2599 Log_event::print_timestamp()
2600 */
2601
print_timestamp(IO_CACHE * file,time_t * ts)2602 void Log_event::print_timestamp(IO_CACHE* file, time_t *ts)
2603 {
2604 struct tm *res;
2605 /*
2606 In some Windows versions timeval.tv_sec is defined as "long",
2607 not as "time_t" and can be of a different size.
2608 Let's use a temporary time_t variable to execute localtime()
2609 with a correct argument type.
2610 */
2611 time_t ts_tmp= ts ? *ts : (ulong)when.tv_sec;
2612 DBUG_ENTER("Log_event::print_timestamp");
2613 struct tm tm_tmp;
2614 localtime_r(&ts_tmp, (res= &tm_tmp));
2615 my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2616 res->tm_year % 100,
2617 res->tm_mon+1,
2618 res->tm_mday,
2619 res->tm_hour,
2620 res->tm_min,
2621 res->tm_sec);
2622 DBUG_VOID_RETURN;
2623 }
2624
2625 #endif /* MYSQL_CLIENT */
2626
2627
2628 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2629 inline Log_event::enum_skip_reason
continue_group(Relay_log_info * rli)2630 Log_event::continue_group(Relay_log_info *rli)
2631 {
2632 if (rli->slave_skip_counter == 1)
2633 return Log_event::EVENT_SKIP_IGNORE;
2634 return Log_event::do_shall_skip(rli);
2635 }
2636
2637 /**
2638 @param end_group_sets_max_dbs when true the group terminal event
2639 can carry partition info, see a note below.
2640 @return true in cases the current event
2641 carries partition data,
2642 false otherwise
2643
2644 @note Some events combination may force to adjust partition info.
2645 In particular BEGIN, BEGIN_LOAD_QUERY_EVENT, COMMIT
2646 where none of the events holds partitioning data
2647 causes the sequential applying of the group through
2648 assigning OVER_MAX_DBS_IN_EVENT_MTS to mts_accessed_dbs
2649 of COMMIT query event.
2650 */
contains_partition_info(bool end_group_sets_max_dbs)2651 bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2652 {
2653 bool res;
2654
2655 switch (get_type_code()) {
2656 case TABLE_MAP_EVENT:
2657 case EXECUTE_LOAD_QUERY_EVENT:
2658 res= true;
2659
2660 break;
2661
2662 case QUERY_EVENT:
2663 if (ends_group() && end_group_sets_max_dbs)
2664 {
2665 res= true;
2666 static_cast<Query_log_event*>(this)->mts_accessed_dbs=
2667 OVER_MAX_DBS_IN_EVENT_MTS;
2668 }
2669 else
2670 res= (!ends_group() && !starts_group()) ? true : false;
2671
2672 break;
2673
2674 default:
2675 res= false;
2676 }
2677
2678 return res;
2679 }
2680
2681 /**
2682 The method maps the event to a Worker and return a pointer to it.
2683 As a part of the group, an event belongs to one of the following types:
2684
2685 B - beginning of a group of events (BEGIN query_log_event)
2686 g - mini-group representative event containing the partition info
2687 (any Table_map, a Query_log_event)
2688 p - a mini-group internal event that *p*receeding its g-parent
2689 (int_, rand_, user_ var:s)
2690 r - a mini-group internal "regular" event that follows its g-parent
2691 (Delete, Update, Write -rows)
2692 T - terminator of the group (XID, COMMIT, ROLLBACK, auto-commit query)
2693
2694 Only the first g-event computes the assigned Worker which once
2695 is determined remains to be for the rest of the group.
2696 That is the g-event solely carries partitioning info.
2697 For B-event the assigned Worker is NULL to indicate Coordinator
2698 has not yet decided. The same applies to p-event.
2699
2700 Notice, these is a special group consisting of optionally multiple p-events
2701 terminating with a g-event.
2702 Such case is caused by old master binlog and a few corner-cases of
2703 the current master version (todo: to fix).
2704
2705 In case of the event accesses more than OVER_MAX_DBS the method
2706 has to ensure sure previously assigned groups to all other workers are
2707 done.
2708
2709
2710 @note The function updates GAQ queue directly, updates APH hash
2711 plus relocates some temporary tables from Coordinator's list into
2712 involved entries of APH through @c map_db_to_worker.
2713 There's few memory allocations commented where to be freed.
2714
2715 @return a pointer to the Worker struct or NULL.
2716 */
2717
get_slave_worker(Relay_log_info * rli)2718 Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
2719 {
2720 Slave_job_group group, *ptr_group= NULL;
2721 bool is_s_event;
2722 Slave_worker *ret_worker= NULL;
2723 char llbuff[22];
2724 #ifndef DBUG_OFF
2725 THD *thd= rli->info_thd;
2726 #endif
2727 Slave_committed_queue *gaq= rli->gaq;
2728
2729 /* checking partioning properties and perform corresponding actions */
2730
2731 // Beginning of a group designated explicitly with BEGIN or GTID
2732 if ((is_s_event= starts_group()) || is_gtid_event(this) ||
2733 // or DDL:s or autocommit queries possibly associated with own p-events
2734 (!rli->curr_group_seen_begin && !rli->curr_group_seen_gtid &&
2735 /*
2736 the following is a special case of B-free still multi-event group like
2737 { p_1,p_2,...,p_k, g }.
2738 In that case either GAQ is empty (the very first group is being
2739 assigned) or the last assigned group index points at one of
2740 mapped-to-a-worker.
2741 */
2742 (gaq->empty() ||
2743 gaq->get_job_group(rli->gaq->assigned_group_index)->
2744 worker_id != MTS_WORKER_UNDEF)))
2745 {
2746 if (!rli->curr_group_seen_gtid && !rli->curr_group_seen_begin)
2747 {
2748 ulong gaq_idx MY_ATTRIBUTE((unused));
2749 rli->mts_groups_assigned++;
2750
2751 rli->curr_group_isolated= FALSE;
2752 group.reset(log_pos, rli->mts_groups_assigned);
2753 // the last occupied GAQ's array index
2754 gaq_idx= gaq->assigned_group_index= gaq->en_queue((void *) &group);
2755
2756 DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF && gaq_idx < gaq->size);
2757 DBUG_ASSERT(gaq->get_job_group(rli->gaq->assigned_group_index)->
2758 group_relay_log_name == NULL);
2759 DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF); // gaq must have room
2760 DBUG_ASSERT(rli->last_assigned_worker == NULL);
2761
2762 if (is_s_event || is_gtid_event(this))
2763 {
2764 Log_event *ptr_curr_ev= this;
2765 // B-event is appended to the Deferred Array associated with GCAP
2766 insert_dynamic(&rli->curr_group_da,
2767 (uchar*) &ptr_curr_ev);
2768
2769 DBUG_ASSERT(rli->curr_group_da.elements == 1);
2770
2771 if (starts_group())
2772 {
2773 // mark the current group as started with explicit B-event
2774 rli->mts_end_group_sets_max_dbs= true;
2775 rli->curr_group_seen_begin= true;
2776 }
2777
2778 if (is_gtid_event(this))
2779 // mark the current group as started with explicit Gtid-event
2780 rli->curr_group_seen_gtid= true;
2781
2782 return ret_worker;
2783 }
2784 }
2785 else
2786 {
2787 Log_event *ptr_curr_ev= this;
2788 // B-event is appended to the Deferred Array associated with GCAP
2789 insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2790 rli->curr_group_seen_begin= true;
2791 rli->mts_end_group_sets_max_dbs= true;
2792 DBUG_ASSERT(rli->curr_group_da.elements == 2);
2793 DBUG_ASSERT(starts_group());
2794 return ret_worker;
2795 }
2796 }
2797
2798 // mini-group representative
2799
2800 if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
2801 {
2802 int i= 0;
2803 Mts_db_names mts_dbs;
2804
2805 get_mts_dbs(&mts_dbs);
2806 /*
2807 Bug 12982188 - MTS: SBR ABORTS WITH ERROR 1742 ON LOAD DATA
2808 Logging on master can create a group with no events holding
2809 the partition info.
2810 The following assert proves there's the only reason
2811 for such group.
2812 */
2813 DBUG_ASSERT(!ends_group() ||
2814 /*
2815 This is an empty group being processed due to gtids.
2816 */
2817 (rli->curr_group_seen_begin && rli->curr_group_seen_gtid &&
2818 ends_group()) ||
2819 (rli->mts_end_group_sets_max_dbs &&
2820 ((rli->curr_group_da.elements == 3 && rli->curr_group_seen_gtid) ||
2821 (rli->curr_group_da.elements == 2 && !rli->curr_group_seen_gtid)) &&
2822 ((*(Log_event **)
2823 dynamic_array_ptr(&rli->curr_group_da,
2824 rli->curr_group_da.elements - 1))->
2825 get_type_code() == BEGIN_LOAD_QUERY_EVENT)));
2826
2827 // partioning info is found which drops the flag
2828 rli->mts_end_group_sets_max_dbs= false;
2829 ret_worker= rli->last_assigned_worker;
2830 if (mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS)
2831 {
2832 // Worker with id 0 to handle serial execution
2833 if (!ret_worker)
2834 ret_worker= *(Slave_worker**) dynamic_array_ptr(&rli->workers, 0);
2835 // No need to know a possible error out of synchronization call.
2836 (void) wait_for_workers_to_finish(rli, ret_worker);
2837 /*
2838 this marking is transferred further into T-event of the current group.
2839 */
2840 rli->curr_group_isolated= TRUE;
2841 }
2842
2843 /* One run of the loop in the case of over-max-db:s */
2844 for (i= 0; i < ((mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS) ? mts_dbs.num : 1);
2845 i++)
2846 {
2847 /*
2848 The over max db:s case handled through passing to map_db_to_worker
2849 such "all" db as encoded as the "" empty string.
2850 Note, the empty string is allocated in a large buffer
2851 to satisfy hashcmp() implementation.
2852 */
2853 const char all_db[NAME_LEN]= {0};
2854 if (!(ret_worker=
2855 map_db_to_worker(mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS ?
2856 all_db : mts_dbs.name[i], rli,
2857 &mts_assigned_partitions[i],
2858 /*
2859 todo: optimize it. Although pure
2860 rows- event load in insensetive to the flag value
2861 */
2862 TRUE,
2863 ret_worker)))
2864 {
2865 llstr(rli->get_event_relay_log_pos(), llbuff);
2866 my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2867 get_type_str(), rli->get_event_relay_log_name(), llbuff,
2868 "could not distribute the event to a Worker");
2869 return ret_worker;
2870 }
2871 // all temporary tables are transferred from Coordinator in over-max case
2872 DBUG_ASSERT(mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
2873 DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db,
2874 mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS ?
2875 mts_dbs.name[i] : all_db));
2876 DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
2877 DBUG_ASSERT(mts_assigned_partitions[i]->usage >= 0);
2878 }
2879
2880 if ((ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index))->
2881 worker_id == MTS_WORKER_UNDEF)
2882 {
2883 ptr_group->worker_id= ret_worker->id;
2884
2885 DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2886 }
2887
2888 DBUG_ASSERT(i == mts_dbs.num || mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS);
2889 }
2890 else
2891 {
2892 // a mini-group internal "regular" event
2893 if (rli->last_assigned_worker)
2894 {
2895 ret_worker= rli->last_assigned_worker;
2896
2897 DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0 ||
2898 ret_worker->id == 0);
2899 }
2900 else // int_, rand_, user_ var:s, load-data events
2901 {
2902 Log_event *ptr_curr_ev= this;
2903
2904 if (!(get_type_code() == INTVAR_EVENT ||
2905 get_type_code() == RAND_EVENT ||
2906 get_type_code() == USER_VAR_EVENT ||
2907 get_type_code() == BEGIN_LOAD_QUERY_EVENT ||
2908 get_type_code() == APPEND_BLOCK_EVENT ||
2909 is_ignorable_event()))
2910 {
2911 DBUG_ASSERT(!ret_worker);
2912
2913 llstr(rli->get_event_relay_log_pos(), llbuff);
2914 my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2915 get_type_str(), rli->get_event_relay_log_name(), llbuff,
2916 "the event is a part of a group that is unsupported in "
2917 "the parallel execution mode");
2918
2919 return ret_worker;
2920 }
2921
2922 insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2923
2924 DBUG_ASSERT(!ret_worker);
2925 return ret_worker;
2926 }
2927 }
2928
2929 DBUG_ASSERT(ret_worker);
2930
2931 /*
2932 Preparing event physical coordinates info for Worker before any
2933 event got scheduled so when Worker error-stopped at the first
2934 event it would be aware of where exactly in the event stream.
2935 */
2936 if (!ret_worker->master_log_change_notified)
2937 {
2938 if (!ptr_group)
2939 ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2940 ptr_group->group_master_log_name=
2941 my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2942 ret_worker->master_log_change_notified= true;
2943
2944 DBUG_ASSERT(!ptr_group->notified);
2945 #ifndef DBUG_OFF
2946 ptr_group->notified= true;
2947 #endif
2948 }
2949
2950 // T-event: Commit, Xid, a DDL query or dml query of B-less group.
2951 if (ends_group() || !rli->curr_group_seen_begin)
2952 {
2953 rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
2954 if (rli->curr_group_isolated)
2955 set_mts_isolate_group();
2956 if (!ptr_group)
2957 ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2958
2959 DBUG_ASSERT(ret_worker != NULL);
2960
2961 /*
2962 The following two blocks are executed if the worker has not been
2963 notified about new relay-log or a new checkpoints.
2964 Relay-log string is freed by Coordinator, Worker deallocates
2965 strings in the checkpoint block.
2966 However if the worker exits earlier reclaiming for both happens anyway at
2967 GAQ delete.
2968 */
2969 if (!ret_worker->relay_log_change_notified)
2970 {
2971 /*
2972 Prior this event, C rotated the relay log to drop each
2973 Worker's notified flag. Now group terminating event initiates
2974 the new relay-log (where the current event is from) name
2975 delivery to Worker that will receive it in commit_positions().
2976 */
2977 DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2978
2979 ptr_group->group_relay_log_name= (char *)
2980 my_malloc(strlen(rli->
2981 get_group_relay_log_name()) + 1, MYF(MY_WME));
2982 strcpy(ptr_group->group_relay_log_name,
2983 rli->get_event_relay_log_name());
2984
2985 DBUG_ASSERT(ptr_group->group_relay_log_name != NULL);
2986
2987 ret_worker->relay_log_change_notified= TRUE;
2988 }
2989
2990 if (!ret_worker->checkpoint_notified)
2991 {
2992 if (!ptr_group)
2993 ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2994 ptr_group->checkpoint_log_name=
2995 my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2996 ptr_group->checkpoint_log_pos= rli->get_group_master_log_pos();
2997 ptr_group->checkpoint_relay_log_name=
2998 my_strdup(rli->get_group_relay_log_name(), MYF(MY_WME));
2999 ptr_group->checkpoint_relay_log_pos= rli->get_group_relay_log_pos();
3000 ptr_group->shifted= ret_worker->bitmap_shifted;
3001 ret_worker->bitmap_shifted= 0;
3002 ret_worker->checkpoint_notified= TRUE;
3003 }
3004 ptr_group->checkpoint_seqno= rli->checkpoint_seqno;
3005 ptr_group->ts= when.tv_sec + (time_t) exec_time; // Seconds_behind_master related
3006 rli->checkpoint_seqno++;
3007 /*
3008 Coordinator should not use the main memroot however its not
3009 reset elsewhere either, so let's do it safe way.
3010 The main mem root is also reset by the SQL thread in at the end
3011 of applying which Coordinator does not do in this case.
3012 That concludes the memroot reset can't harm anything in SQL thread roles
3013 after Coordinator has finished its current scheduling.
3014 */
3015 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3016
3017 #ifndef DBUG_OFF
3018 w_rr++;
3019 #endif
3020
3021 }
3022
3023 return ret_worker;
3024 }
3025
3026 /**
3027 Scheduling event to execute in parallel or execute it directly.
3028 In MTS case the event gets associated with either Coordinator or a
3029 Worker. A special case of the association is NULL when the Worker
3030 can't be decided yet. In the single threaded sequential mode the
3031 event maps to SQL thread rli.
3032
3033 @note in case of MTS failure Coordinator destroys all gathered
3034 deferred events.
3035
3036 @return 0 as success, otherwise a failure.
3037 */
apply_event(Relay_log_info * rli)3038 int Log_event::apply_event(Relay_log_info *rli)
3039 {
3040 DBUG_ENTER("LOG_EVENT:apply_event");
3041 bool parallel= FALSE;
3042 enum enum_mts_event_exec_mode actual_exec_mode= EVENT_EXEC_PARALLEL;
3043 THD *thd= rli->info_thd;
3044
3045 worker= rli;
3046
3047 if (rli->is_mts_recovery())
3048 {
3049 bool skip=
3050 bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index) &&
3051 (get_mts_execution_mode(::server_id,
3052 rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
3053 == EVENT_EXEC_PARALLEL);
3054 if (skip)
3055 {
3056 DBUG_RETURN(0);
3057 }
3058 else
3059 {
3060 DBUG_RETURN(do_apply_event(rli));
3061 }
3062 }
3063
3064 if (!(parallel= rli->is_parallel_exec()) ||
3065 ((actual_exec_mode=
3066 get_mts_execution_mode(::server_id,
3067 rli->mts_group_status == Relay_log_info::MTS_IN_GROUP))
3068 != EVENT_EXEC_PARALLEL))
3069 {
3070 if (parallel)
3071 {
3072 /*
3073 There are two classes of events that Coordinator executes
3074 itself. One e.g the master Rotate requires all Workers to finish up
3075 their assignments. The other async class, e.g the slave Rotate,
3076 can't have this such synchronization because Worker might be waiting
3077 for terminal events to finish.
3078 */
3079
3080 if (actual_exec_mode != EVENT_EXEC_ASYNC)
3081 {
3082 /*
3083 this event does not split the current group but is indeed
3084 a separator beetwen two master's binlog therefore requiring
3085 Workers to sync.
3086 */
3087 if (rli->curr_group_da.elements > 0)
3088 {
3089 char llbuff[22];
3090 /*
3091 Possible reason is a old version binlog sequential event
3092 wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var.
3093 MTS has to stop to suggest restart in the permanent sequential mode.
3094 */
3095 llstr(rli->get_event_relay_log_pos(), llbuff);
3096 my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3097 get_type_str(), rli->get_event_relay_log_name(), llbuff,
3098 "possible malformed group of events from an old master");
3099
3100 /* Coordinator cant continue, it marks MTS group status accordingly */
3101 rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
3102
3103 goto err;
3104 }
3105 /*
3106 Marking sure the event will be executed in sequential mode.
3107 */
3108 if (wait_for_workers_to_finish(rli) == -1)
3109 {
3110 // handle synchronization error
3111 rli->report(WARNING_LEVEL, 0,
3112 "Slave worker thread has failed to apply an event. As a "
3113 "consequence, the coordinator thread is stopping "
3114 "execution.");
3115 DBUG_RETURN(-1);
3116 }
3117 /*
3118 Given not in-group mark the event handler can invoke checkpoint
3119 update routine in the following course.
3120 */
3121 DBUG_ASSERT(rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP);
3122
3123 #ifndef DBUG_OFF
3124 /* all Workers are idle as done through wait_for_workers_to_finish */
3125 for (uint k= 0; k < rli->curr_group_da.elements; k++)
3126 {
3127 DBUG_ASSERT(!(*(Slave_worker **)
3128 dynamic_array_ptr(&rli->workers, k))->usage_partition);
3129 DBUG_ASSERT(!(*(Slave_worker **)
3130 dynamic_array_ptr(&rli->workers, k))->jobs.len);
3131 }
3132 #endif
3133 }
3134 else
3135 {
3136 DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_ASYNC);
3137 }
3138 }
3139 DBUG_RETURN(do_apply_event(rli));
3140 }
3141
3142 DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_PARALLEL);
3143 DBUG_ASSERT(!(rli->curr_group_seen_begin && ends_group()) ||
3144 /*
3145 This is an empty group being processed due to gtids.
3146 */
3147 (rli->curr_group_seen_begin && rli->curr_group_seen_gtid
3148 && ends_group()) ||
3149 rli->last_assigned_worker ||
3150 /*
3151 Begin_load_query can be logged w/o db info and within
3152 Begin/Commit. That's a pattern forcing sequential
3153 applying of LOAD-DATA.
3154 */
3155 (*(Log_event **)
3156 dynamic_array_ptr(&rli->curr_group_da,
3157 rli->curr_group_da.elements - 1))->
3158 get_type_code() == BEGIN_LOAD_QUERY_EVENT);
3159
3160 worker= NULL;
3161 rli->mts_group_status= Relay_log_info::MTS_IN_GROUP;
3162
3163 worker= (Relay_log_info*)
3164 (rli->last_assigned_worker= get_slave_worker(rli));
3165
3166 #ifndef DBUG_OFF
3167 if (rli->last_assigned_worker)
3168 DBUG_PRINT("mts", ("Assigning job to worker %lu",
3169 rli->last_assigned_worker->id));
3170 #endif
3171
3172 err:
3173 if (thd->is_error())
3174 {
3175 DBUG_ASSERT(!worker);
3176
3177 /*
3178 Destroy all deferred buffered events but the current prior to exit.
3179 The current one will be deleted as an event never destined/assigned
3180 to any Worker in Coordinator's regular execution path.
3181 */
3182 for (uint k= 0; k < rli->curr_group_da.elements; k++)
3183 {
3184 Log_event *ev_buf=
3185 *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k);
3186 if (this != ev_buf)
3187 delete ev_buf;
3188 }
3189 rli->curr_group_da.elements= 0;
3190 }
3191 else
3192 {
3193 DBUG_ASSERT(worker || rli->curr_group_assigned_parts.elements == 0);
3194 }
3195
3196 DBUG_RETURN((!thd->is_error() ||
3197 DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ?
3198 0 : -1);
3199 }
3200
3201 #endif
3202
3203 /**************************************************************************
3204 Query_log_event methods
3205 **************************************************************************/
3206
3207 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3208
3209 /**
3210 This (which is used only for SHOW BINLOG EVENTS) could be updated to
3211 print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
3212 only an information, it does not produce suitable queries to replay (for
3213 example it does not print LOAD DATA INFILE).
3214 @todo
3215 show the catalog ??
3216 */
3217
pack_info(Protocol * protocol)3218 int Query_log_event::pack_info(Protocol *protocol)
3219 {
3220 // TODO: show the catalog ??
3221 String temp_buf;
3222 // Add use `DB` to the string if required
3223 if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
3224 && db && db_len)
3225 {
3226 temp_buf.append("use ");
3227 append_identifier(this->thd, &temp_buf, db, db_len);
3228 temp_buf.append("; ");
3229 }
3230 // Add the query to the string
3231 if (query && q_len)
3232 temp_buf.append(query);
3233 // persist the buffer in protocol
3234 protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
3235 return 0;
3236 }
3237 #endif
3238
3239 #ifndef MYSQL_CLIENT
3240
3241 /**
3242 Utility function for the next method (Query_log_event::write()) .
3243 */
write_str_with_code_and_len(uchar ** dst,const char * src,uint len,uint code)3244 static void write_str_with_code_and_len(uchar **dst, const char *src,
3245 uint len, uint code)
3246 {
3247 /*
3248 only 1 byte to store the length of catalog, so it should not
3249 surpass 255
3250 */
3251 DBUG_ASSERT(len <= 255);
3252 DBUG_ASSERT(src);
3253 *((*dst)++)= code;
3254 *((*dst)++)= (uchar) len;
3255 bmove(*dst, src, len);
3256 (*dst)+= len;
3257 }
3258
3259
3260 /**
3261 Query_log_event::write().
3262
3263 @note
3264 In this event we have to modify the header to have the correct
3265 EVENT_LEN_OFFSET as we don't yet know how many status variables we
3266 will print!
3267 */
3268
write(IO_CACHE * file)3269 bool Query_log_event::write(IO_CACHE* file)
3270 {
3271 uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3272 uchar *start, *start_of_status;
3273 ulong event_length;
3274
3275 if (!query)
3276 return 1; // Something wrong with event
3277
3278 /*
3279 We want to store the thread id:
3280 (- as an information for the user when he reads the binlog)
3281 - if the query uses temporary table: for the slave SQL thread to know to
3282 which master connection the temp table belongs.
3283 Now imagine we (write()) are called by the slave SQL thread (we are
3284 logging a query executed by this thread; the slave runs with
3285 --log-slave-updates). Then this query will be logged with
3286 thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
3287 the same name were created simultaneously on the master (in the master
3288 binlog you have
3289 CREATE TEMPORARY TABLE t; (thread 1)
3290 CREATE TEMPORARY TABLE t; (thread 2)
3291 ...)
3292 then in the slave's binlog there will be
3293 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3294 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3295 which is bad (same thread id!).
3296
3297 To avoid this, we log the thread's thread id EXCEPT for the SQL
3298 slave thread for which we log the original (master's) thread id.
3299 Now this moves the bug: what happens if the thread id on the
3300 master was 10 and when the slave replicates the query, a
3301 connection number 10 is opened by a normal client on the slave,
3302 and updates a temp table of the same name? We get a problem
3303 again. To avoid this, in the handling of temp tables (sql_base.cc)
3304 we use thread_id AND server_id. TODO when this is merged into
3305 4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
3306 and is a session variable: that's to make mysqlbinlog work with
3307 temp tables. We probably need to introduce
3308
3309 SET PSEUDO_SERVER_ID
3310 for mysqlbinlog in 4.1. mysqlbinlog would print:
3311 SET PSEUDO_SERVER_ID=
3312 SET PSEUDO_THREAD_ID=
3313 for each query using temp tables.
3314 */
3315 int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
3316 int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
3317 buf[Q_DB_LEN_OFFSET] = (char) db_len;
3318 int2store(buf + Q_ERR_CODE_OFFSET, error_code);
3319
3320 /*
3321 You MUST always write status vars in increasing order of code. This
3322 guarantees that a slightly older slave will be able to parse those he
3323 knows.
3324 */
3325 start_of_status= start= buf+QUERY_HEADER_LEN;
3326 if (flags2_inited)
3327 {
3328 *start++= Q_FLAGS2_CODE;
3329 int4store(start, flags2);
3330 start+= 4;
3331 }
3332 if (sql_mode_inited)
3333 {
3334 *start++= Q_SQL_MODE_CODE;
3335 int8store(start, sql_mode);
3336 start+= 8;
3337 }
3338 if (catalog_len) // i.e. this var is inited (false for 4.0 events)
3339 {
3340 write_str_with_code_and_len(&start,
3341 catalog, catalog_len, Q_CATALOG_NZ_CODE);
3342 /*
3343 In 5.0.x where x<4 masters we used to store the end zero here. This was
3344 a waste of one byte so we don't do it in x>=4 masters. We change code to
3345 Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
3346 of this x>=4 master segfault (expecting a zero when there is
3347 none). Remaining compatibility problems are: the older slave will not
3348 find the catalog; but it is will not crash, and it's not an issue
3349 that it does not find the catalog as catalogs were not used in these
3350 older MySQL versions (we store it in binlog and read it from relay log
3351 but do nothing useful with it). What is an issue is that the older slave
3352 will stop processing the Q_* blocks (and jumps to the db/query) as soon
3353 as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
3354 Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
3355 various ways. Documented that you should not mix alpha/beta versions if
3356 they are not exactly the same version, with example of 5.0.3->5.0.2 and
3357 5.0.4->5.0.3. If replication is from older to new, the new will
3358 recognize Q_CATALOG_CODE and have no problem.
3359 */
3360 }
3361 if (auto_increment_increment != 1 || auto_increment_offset != 1)
3362 {
3363 *start++= Q_AUTO_INCREMENT;
3364 int2store(start, auto_increment_increment);
3365 int2store(start+2, auto_increment_offset);
3366 start+= 4;
3367 }
3368 if (charset_inited)
3369 {
3370 *start++= Q_CHARSET_CODE;
3371 memcpy(start, charset, 6);
3372 start+= 6;
3373 }
3374 if (time_zone_len)
3375 {
3376 /* In the TZ sys table, column Name is of length 64 so this should be ok */
3377 DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
3378 write_str_with_code_and_len(&start,
3379 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
3380 }
3381 if (lc_time_names_number)
3382 {
3383 DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
3384 *start++= Q_LC_TIME_NAMES_CODE;
3385 int2store(start, lc_time_names_number);
3386 start+= 2;
3387 }
3388 if (charset_database_number)
3389 {
3390 DBUG_ASSERT(charset_database_number <= 0xFFFF);
3391 *start++= Q_CHARSET_DATABASE_CODE;
3392 int2store(start, charset_database_number);
3393 start+= 2;
3394 }
3395 if (table_map_for_update)
3396 {
3397 *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
3398 int8store(start, table_map_for_update);
3399 start+= 8;
3400 }
3401 if (master_data_written != 0)
3402 {
3403 /*
3404 Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
3405 has binlog_version<4 and the slave has binlog_version=4. See comment
3406 for master_data_written in log_event.h for details.
3407 */
3408 *start++= Q_MASTER_DATA_WRITTEN_CODE;
3409 int4store(start, master_data_written);
3410 start+= 4;
3411 }
3412
3413 if (thd && thd->need_binlog_invoker())
3414 {
3415 LEX_STRING user;
3416 LEX_STRING host;
3417 memset(&user, 0, sizeof(user));
3418 memset(&host, 0, sizeof(host));
3419
3420 if (thd->slave_thread && thd->has_invoker())
3421 {
3422 /* user will be null, if master is older than this patch */
3423 user= thd->get_invoker_user();
3424 host= thd->get_invoker_host();
3425 }
3426 else
3427 {
3428 Security_context *ctx= thd->security_ctx;
3429
3430 user.length= strlen(ctx->priv_user);
3431 user.str= ctx->priv_user;
3432 if (ctx->priv_host[0] != '\0')
3433 {
3434 host.str= ctx->priv_host;
3435 host.length= strlen(ctx->priv_host);
3436 }
3437 }
3438
3439 *start++= Q_INVOKER;
3440
3441 /*
3442 Store user length and user. The max length of use is 16, so 1 byte is
3443 enough to store the user's length.
3444 */
3445 *start++= (uchar)user.length;
3446 memcpy(start, user.str, user.length);
3447 start+= user.length;
3448
3449 /*
3450 Store host length and host. The max length of host is 60, so 1 byte is
3451 enough to store the host's length.
3452 */
3453 *start++= (uchar)host.length;
3454 memcpy(start, host.str, host.length);
3455 start+= host.length;
3456 }
3457
3458 if (thd && thd->get_binlog_accessed_db_names() != NULL)
3459 {
3460 uchar dbs;
3461 *start++= Q_UPDATED_DB_NAMES;
3462
3463 compile_time_assert(MAX_DBS_IN_EVENT_MTS <= OVER_MAX_DBS_IN_EVENT_MTS);
3464
3465 /*
3466 In case of the number of db:s exceeds MAX_DBS_IN_EVENT_MTS
3467 no db:s is written and event will require the sequential applying on slave.
3468 */
3469 dbs=
3470 (thd->get_binlog_accessed_db_names()->elements <= MAX_DBS_IN_EVENT_MTS) ?
3471 thd->get_binlog_accessed_db_names()->elements : OVER_MAX_DBS_IN_EVENT_MTS;
3472
3473 DBUG_ASSERT(dbs != 0);
3474
3475 if (dbs <= MAX_DBS_IN_EVENT_MTS)
3476 {
3477 List_iterator_fast<char> it(*thd->get_binlog_accessed_db_names());
3478 char *db_name= it++;
3479 /*
3480 the single "" db in the acccessed db list corresponds to the same as
3481 exceeds MAX_DBS_IN_EVENT_MTS case, so dbs is set to the over-max.
3482 */
3483 if (dbs == 1 && !strcmp(db_name, ""))
3484 dbs= OVER_MAX_DBS_IN_EVENT_MTS;
3485 *start++= dbs;
3486 if (dbs != OVER_MAX_DBS_IN_EVENT_MTS)
3487 do
3488 {
3489 strcpy((char*) start, db_name);
3490 start += strlen(db_name) + 1;
3491 } while ((db_name= it++));
3492 }
3493 else
3494 {
3495 *start++= dbs;
3496 }
3497 }
3498
3499 if (thd && thd->query_start_usec_used)
3500 {
3501 *start++= Q_MICROSECONDS;
3502 get_time();
3503 int3store(start, when.tv_usec);
3504 start+= 3;
3505 }
3506
3507 /*
3508 NOTE: When adding new status vars, please don't forget to update
3509 the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
3510 code_name() in this file.
3511
3512 Here there could be code like
3513 if (command-line-option-which-says-"log_this_variable" && inited)
3514 {
3515 *start++= Q_THIS_VARIABLE_CODE;
3516 int4store(start, this_variable);
3517 start+= 4;
3518 }
3519 */
3520
3521 /* Store length of status variables */
3522 status_vars_len= (uint) (start-start_of_status);
3523 DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
3524 int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
3525
3526 /*
3527 Calculate length of whole event
3528 The "1" below is the \0 in the db's length
3529 */
3530 event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
3531
3532 return (write_header(file, event_length) ||
3533 wrapper_my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
3534 write_post_header_for_derived(file) ||
3535 wrapper_my_b_safe_write(file, (uchar*) start_of_status,
3536 (uint) (start-start_of_status)) ||
3537 wrapper_my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
3538 wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
3539 write_footer(file)) ? 1 : 0;
3540 }
3541
3542 /**
3543 The simplest constructor that could possibly work. This is used for
3544 creating static objects that have a special meaning and are invisible
3545 to the log.
3546 */
Query_log_event()3547 Query_log_event::Query_log_event()
3548 :Log_event(), data_buf(0)
3549 {
3550 memset(&user, 0, sizeof(user));
3551 memset(&host, 0, sizeof(host));
3552 }
3553
3554
3555 /**
3556 Creates a Query Log Event.
3557
3558 @param thd_arg Thread handle
3559 @param query_arg Array of char representing the query
3560 @param query_length Size of the 'query_arg' array
3561 @param using_trans Indicates that there are transactional changes.
3562 @param immediate After being written to the binary log, the event
3563 must be flushed immediately. This indirectly implies
3564 the stmt-cache.
3565 @param suppress_use Suppress the generation of 'USE' statements
3566 @param errcode The error code of the query
3567 @param ignore Ignore user's statement, i.e. lex information, while
3568 deciding which cache must be used.
3569 */
Query_log_event(THD * thd_arg,const char * query_arg,ulong query_length,bool using_trans,bool immediate,bool suppress_use,int errcode,bool ignore_cmd_internals)3570 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
3571 ulong query_length, bool using_trans,
3572 bool immediate, bool suppress_use,
3573 int errcode, bool ignore_cmd_internals)
3574
3575 :Log_event(thd_arg,
3576 (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
3577 0) |
3578 (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
3579 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
3580 Log_event::EVENT_STMT_CACHE,
3581 Log_event::EVENT_NORMAL_LOGGING),
3582 data_buf(0), query(query_arg), catalog(thd_arg->catalog),
3583 db(thd_arg->db), q_len((uint32) query_length),
3584 thread_id(thd_arg->thread_id),
3585 /* save the original thread id; we already know the server id */
3586 slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3587 flags2_inited(1), sql_mode_inited(1), charset_inited(1),
3588 sql_mode(thd_arg->variables.sql_mode),
3589 auto_increment_increment(thd_arg->variables.auto_increment_increment),
3590 auto_increment_offset(thd_arg->variables.auto_increment_offset),
3591 lc_time_names_number(thd_arg->variables.lc_time_names->number),
3592 charset_database_number(0),
3593 table_map_for_update((ulonglong)thd_arg->table_map_for_update),
3594 master_data_written(0), mts_accessed_dbs(0)
3595 {
3596
3597 #ifdef WITH_WSREP
3598 /*
3599 If Query_log_event will contain non trans keyword (not BEGIN, COMMIT,
3600 SAVEPOINT or ROLLBACK) we disable PA for this transaction.
3601 */
3602 if (!is_trans_keyword())
3603 thd->wsrep_PA_safe= false;
3604 #endif /* WITH_WSREP */
3605 memset(&user, 0, sizeof(user));
3606 memset(&host, 0, sizeof(host));
3607
3608 error_code= errcode;
3609
3610 /*
3611 exec_time calculation has changed to use the same method that is used
3612 to fill out "thd_arg->start_time"
3613 */
3614
3615 struct timeval end_time;
3616 ulonglong micro_end_time= my_micro_time();
3617 my_micro_time_to_timeval(micro_end_time, &end_time);
3618
3619 exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
3620
3621 /**
3622 @todo this means that if we have no catalog, then it is replicated
3623 as an existing catalog of length zero. is that safe? /sven
3624 */
3625 catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
3626 /* status_vars_len is set just before writing the event */
3627 db_len = (db) ? (uint32) strlen(db) : 0;
3628 if (thd_arg->variables.collation_database != thd_arg->db_charset)
3629 charset_database_number= thd_arg->variables.collation_database->number;
3630
3631 /*
3632 We only replicate over the bits of flags2 that we need: the rest
3633 are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
3634
3635 We also force AUTOCOMMIT=1. Rationale (cf. BUG#29288): After
3636 fixing BUG#26395, we always write BEGIN and COMMIT around all
3637 transactions (even single statements in autocommit mode). This is
3638 so that replication from non-transactional to transactional table
3639 and error recovery from XA to non-XA table should work as
3640 expected. The BEGIN/COMMIT are added in log.cc. However, there is
3641 one exception: MyISAM bypasses log.cc and writes directly to the
3642 binlog. So if autocommit is off, master has MyISAM, and slave has
3643 a transactional engine, then the slave will just see one long
3644 never-ending transaction. The only way to bypass explicit
3645 BEGIN/COMMIT in the binlog is by using a non-transactional table.
3646 So setting AUTOCOMMIT=1 will make this work as expected.
3647
3648 Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
3649 assume AUTOCOMMIT=1 on slave; the slave still reads the state of
3650 the autocommit flag as written by the master to the binlog. This
3651 behavior may change after WL#4162 has been implemented.
3652 */
3653 flags2= (uint32) (thd_arg->variables.option_bits &
3654 (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
3655 DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
3656 DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
3657 DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
3658 DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
3659 int2store(charset, thd_arg->variables.character_set_client->number);
3660 int2store(charset+2, thd_arg->variables.collation_connection->number);
3661 int2store(charset+4, thd_arg->variables.collation_server->number);
3662 if (thd_arg->time_zone_used)
3663 {
3664 /*
3665 Note that our event becomes dependent on the Time_zone object
3666 representing the time zone. Fortunately such objects are never deleted
3667 or changed during mysqld's lifetime.
3668 */
3669 time_zone_len= thd_arg->variables.time_zone->get_name()->length();
3670 time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
3671 }
3672 else
3673 time_zone_len= 0;
3674
3675 /*
3676 In what follows, we define in which cache, trx-cache or stmt-cache,
3677 this Query Log Event will be written to.
3678
3679 If ignore_cmd_internals is defined, we rely on the is_trans flag to
3680 choose the cache and this is done in the base class Log_event. False
3681 means that the stmt-cache will be used and upon statement commit/rollback
3682 the cache will be flushed to disk. True means that the trx-cache will
3683 be used and upon transaction commit/rollback the cache will be flushed
3684 to disk.
3685
3686 If set immediate cache is defined, for convenience, we automatically
3687 use the stmt-cache. This mean that the statement will be written
3688 to the stmt-cache and immediately flushed to disk without waiting
3689 for a commit/rollback notification.
3690
3691 For example, the cluster/ndb captures a request to execute a DDL
3692 statement and synchronously propagate it to all available MySQL
3693 servers. Unfortunately, the current protocol assumes that the
3694 generated events are immediately written to diks and does not check
3695 for commit/rollback.
3696
3697 Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are
3698 generated and in this case the statements have the immediate flag
3699 set because there is no commit/rollback.
3700
3701 If the immediate flag is not set, the decision on the cache is based
3702 on the current statement and the flag is_trans, which indicates if
3703 a transactional engine was updated.
3704
3705 Statements are classifed as row producers (i.e. can_generate_row_events())
3706 or non-row producers. Non-row producers, DDL in general, are treated
3707 as the immediate flag was set and for convenience are written to the
3708 stmt-cache and immediately flushed to disk.
3709
3710 Row producers are handled in general according to the is_trans flag.
3711 False means that the stmt-cache will be used and upon statement
3712 commit/rollback the cache will be flushed to disk. True means that the
3713 trx-cache will be used and upon transaction commit/rollback the cache
3714 will be flushed to disk.
3715
3716 Unfortunately, there are exceptions to this non-row and row producer
3717 rules:
3718
3719 . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not
3720 have the flag is_trans set because there is no updated engine but
3721 must be written to the trx-cache.
3722
3723 . SET If auto-commit is on, it must not go through a cache.
3724
3725 . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY
3726 must be handled as row producer.
3727
3728 . DROP TABLE is classfied as non-row producer but DROP TEMPORARY
3729 must be handled as row producer.
3730
3731 Finally, some statements that does not have the flag is_trans set may
3732 be written to the trx-cache based on the following criteria:
3733
3734 . updated both a transactional and a non-transactional engine (i.e.
3735 stmt_has_updated_trans_table()).
3736
3737 . accessed both a transactional and a non-transactional engine and
3738 is classified as unsafe (i.e. is_mixed_stmt_unsafe()).
3739
3740 . is executed within a transaction and previously a transactional
3741 engine was updated and the flag binlog_direct_non_trans_update
3742 is set.
3743 */
3744 if (ignore_cmd_internals)
3745 return;
3746
3747 /*
3748 TRUE defines that the trx-cache must be used.
3749 */
3750 bool cmd_can_generate_row_events= FALSE;
3751 /*
3752 TRUE defines that the trx-cache must be used.
3753 */
3754 bool cmd_must_go_to_trx_cache= FALSE;
3755
3756 LEX *lex= thd->lex;
3757 if (!immediate)
3758 {
3759 switch (lex->sql_command)
3760 {
3761 case SQLCOM_DROP_TABLE:
3762 cmd_can_generate_row_events= lex->drop_temporary &&
3763 thd->in_multi_stmt_transaction_mode();
3764 break;
3765 case SQLCOM_CREATE_TABLE:
3766 cmd_must_go_to_trx_cache= lex->select_lex.item_list.elements &&
3767 thd->is_current_stmt_binlog_format_row();
3768 cmd_can_generate_row_events=
3769 ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
3770 thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache;
3771 break;
3772 case SQLCOM_SET_OPTION:
3773 if (lex->autocommit)
3774 cmd_can_generate_row_events= cmd_must_go_to_trx_cache= FALSE;
3775 else
3776 cmd_can_generate_row_events= TRUE;
3777 break;
3778 case SQLCOM_RELEASE_SAVEPOINT:
3779 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
3780 case SQLCOM_SAVEPOINT:
3781 cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE;
3782 break;
3783 default:
3784 cmd_can_generate_row_events=
3785 sqlcom_can_generate_row_events(thd->lex->sql_command);
3786 break;
3787 }
3788 }
3789
3790 if (cmd_can_generate_row_events)
3791 {
3792 cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
3793 if (cmd_must_go_to_trx_cache ||
3794 stmt_has_updated_trans_table(thd->transaction.stmt.ha_list) ||
3795 thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
3796 thd->variables.binlog_direct_non_trans_update,
3797 trans_has_updated_trans_table(thd),
3798 thd->tx_isolation) ||
3799 (!thd->variables.binlog_direct_non_trans_update && trans_has_updated_trans_table(thd)))
3800 {
3801 event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3802 event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
3803 }
3804 else
3805 {
3806 event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3807 event_cache_type= Log_event::EVENT_STMT_CACHE;
3808 }
3809 }
3810 else
3811 {
3812 event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
3813 event_cache_type= Log_event::EVENT_STMT_CACHE;
3814 }
3815
3816 DBUG_ASSERT(event_cache_type != Log_event::EVENT_INVALID_CACHE);
3817 DBUG_ASSERT(event_logging_type != Log_event::EVENT_INVALID_LOGGING);
3818 DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu",
3819 (ulong) flags2, sql_mode));
3820 }
3821 #endif /* MYSQL_CLIENT */
3822
3823
3824 /* 2 utility functions for the next method */
3825
3826 /**
3827 Read a string with length from memory.
3828
3829 This function reads the string-with-length stored at
3830 <code>src</code> and extract the length into <code>*len</code> and
3831 a pointer to the start of the string into <code>*dst</code>. The
3832 string can then be copied using <code>memcpy()</code> with the
3833 number of bytes given in <code>*len</code>.
3834
3835 @param src Pointer to variable holding a pointer to the memory to
3836 read the string from.
3837 @param dst Pointer to variable holding a pointer where the actual
3838 string starts. Starting from this position, the string
3839 can be copied using @c memcpy().
3840 @param len Pointer to variable where the length will be stored.
3841 @param end One-past-the-end of the memory where the string is
3842 stored.
3843
3844 @return Zero if the entire string can be copied successfully,
3845 @c UINT_MAX if the length could not be read from memory
3846 (that is, if <code>*src >= end</code>), otherwise the
3847 number of bytes that are missing to read the full
3848 string, which happends <code>*dst + *len >= end</code>.
3849 */
3850 static int
get_str_len_and_pointer(const Log_event::Byte ** src,const char ** dst,uint * len,const Log_event::Byte * end)3851 get_str_len_and_pointer(const Log_event::Byte **src,
3852 const char **dst,
3853 uint *len,
3854 const Log_event::Byte *end)
3855 {
3856 if (*src >= end)
3857 return -1; // Will be UINT_MAX in two-complement arithmetics
3858 uint length= **src;
3859 if (length > 0)
3860 {
3861 if (*src + length >= end)
3862 return *src + length - end + 1; // Number of bytes missing
3863 *dst= (char *)*src + 1; // Will be copied later
3864 }
3865 *len= length;
3866 *src+= length + 1;
3867 return 0;
3868 }
3869
copy_str_and_move(const char ** src,Log_event::Byte ** dst,uint len)3870 static void copy_str_and_move(const char **src,
3871 Log_event::Byte **dst,
3872 uint len)
3873 {
3874 memcpy(*dst, *src, len);
3875 *src= (const char *)*dst;
3876 (*dst)+= len;
3877 *(*dst)++= 0;
3878 }
3879
3880
3881 #ifndef DBUG_OFF
3882 static char const *
code_name(int code)3883 code_name(int code)
3884 {
3885 static char buf[255];
3886 switch (code) {
3887 case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
3888 case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
3889 case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
3890 case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
3891 case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
3892 case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
3893 case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
3894 case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
3895 case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
3896 case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
3897 case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
3898 case Q_UPDATED_DB_NAMES: return "Q_UPDATED_DB_NAMES";
3899 case Q_MICROSECONDS: return "Q_MICROSECONDS";
3900 }
3901 sprintf(buf, "CODE#%d", code);
3902 return buf;
3903 }
3904 #endif
3905
3906 /**
3907 Macro to check that there is enough space to read from memory.
3908
3909 @param PTR Pointer to memory
3910 @param END End of memory
3911 @param CNT Number of bytes that should be read.
3912 */
3913 #define CHECK_SPACE(PTR,END,CNT) \
3914 do { \
3915 DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
3916 DBUG_ASSERT((PTR) + (CNT) <= (END)); \
3917 if ((PTR) + (CNT) > (END)) { \
3918 DBUG_PRINT("info", ("query= 0")); \
3919 query= 0; \
3920 DBUG_VOID_RETURN; \
3921 } \
3922 } while (0)
3923
3924
3925 /**
3926 This is used by the SQL slave thread to prepare the event before execution.
3927 */
Query_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event,Log_event_type event_type)3928 Query_log_event::Query_log_event(const char* buf, uint event_len,
3929 const Format_description_log_event
3930 *description_event,
3931 Log_event_type event_type)
3932 :Log_event(buf, description_event), data_buf(0), query(NullS),
3933 db(NullS), catalog_len(0), status_vars_len(0),
3934 flags2_inited(0), sql_mode_inited(0), charset_inited(0),
3935 auto_increment_increment(1), auto_increment_offset(1),
3936 time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
3937 table_map_for_update(0), master_data_written(0),
3938 mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS)
3939 {
3940 ulong data_len;
3941 uint32 tmp;
3942 uint8 common_header_len, post_header_len;
3943 Log_event::Byte *start;
3944 const Log_event::Byte *end;
3945 bool catalog_nz= 1;
3946 DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
3947
3948 memset(&user, 0, sizeof(user));
3949 memset(&host, 0, sizeof(host));
3950 common_header_len= description_event->common_header_len;
3951 post_header_len= description_event->post_header_len[event_type-1];
3952 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
3953 event_len, common_header_len, post_header_len));
3954
3955 /*
3956 We test if the event's length is sensible, and if so we compute data_len.
3957 We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
3958 We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
3959 */
3960 if (event_len < (uint)(common_header_len + post_header_len))
3961 DBUG_VOID_RETURN;
3962 data_len = event_len - (common_header_len + post_header_len);
3963 buf+= common_header_len;
3964
3965 slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
3966 exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
3967 db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
3968 error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
3969
3970 /*
3971 5.0 format starts here.
3972 Depending on the format, we may or not have affected/warnings etc
3973 The remnent post-header to be parsed has length:
3974 */
3975 tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
3976 if (tmp)
3977 {
3978 status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
3979 /*
3980 Check if status variable length is corrupt and will lead to very
3981 wrong data. We could be even more strict and require data_len to
3982 be even bigger, but this will suffice to catch most corruption
3983 errors that can lead to a crash.
3984 */
3985 if (status_vars_len > min<ulong>(data_len, MAX_SIZE_LOG_EVENT_STATUS))
3986 {
3987 DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
3988 status_vars_len, data_len));
3989 query= 0;
3990 DBUG_VOID_RETURN;
3991 }
3992 data_len-= status_vars_len;
3993 DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
3994 (uint) status_vars_len));
3995 tmp-= 2;
3996 }
3997 else
3998 {
3999 /*
4000 server version < 5.0 / binlog_version < 4 master's event is
4001 relay-logged with storing the original size of the event in
4002 Q_MASTER_DATA_WRITTEN_CODE status variable.
4003 The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
4004 event from the relay log.
4005 */
4006 DBUG_ASSERT(description_event->binlog_version < 4);
4007 master_data_written= data_written;
4008 }
4009 /*
4010 We have parsed everything we know in the post header for QUERY_EVENT,
4011 the rest of post header is either comes from older version MySQL or
4012 dedicated to derived events (e.g. Execute_load_query...)
4013 */
4014
4015 /* variable-part: the status vars; only in MySQL 5.0 */
4016
4017 start= (Log_event::Byte*) (buf+post_header_len);
4018 end= (const Log_event::Byte*) (start+status_vars_len);
4019 for (const Log_event::Byte* pos= start; pos < end;)
4020 {
4021 switch (*pos++) {
4022 case Q_FLAGS2_CODE:
4023 CHECK_SPACE(pos, end, 4);
4024 flags2_inited= 1;
4025 flags2= uint4korr(pos);
4026 DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
4027 pos+= 4;
4028 break;
4029 case Q_SQL_MODE_CODE:
4030 {
4031 #ifndef DBUG_OFF
4032 char buff[22];
4033 #endif
4034 CHECK_SPACE(pos, end, 8);
4035 sql_mode_inited= 1;
4036 sql_mode= uint8korr(pos);
4037 DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
4038 llstr(sql_mode, buff)));
4039 pos+= 8;
4040 break;
4041 }
4042 case Q_CATALOG_NZ_CODE:
4043 DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
4044 (ulong) pos, (ulong) end));
4045 if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
4046 {
4047 DBUG_PRINT("info", ("query= 0"));
4048 query= 0;
4049 DBUG_VOID_RETURN;
4050 }
4051 break;
4052 case Q_AUTO_INCREMENT:
4053 CHECK_SPACE(pos, end, 4);
4054 auto_increment_increment= uint2korr(pos);
4055 auto_increment_offset= uint2korr(pos+2);
4056 pos+= 4;
4057 break;
4058 case Q_CHARSET_CODE:
4059 {
4060 CHECK_SPACE(pos, end, 6);
4061 charset_inited= 1;
4062 memcpy(charset, pos, 6);
4063 pos+= 6;
4064 break;
4065 }
4066 case Q_TIME_ZONE_CODE:
4067 {
4068 if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
4069 {
4070 DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
4071 query= 0;
4072 DBUG_VOID_RETURN;
4073 }
4074 break;
4075 }
4076 case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
4077 CHECK_SPACE(pos, end, 1);
4078 if ((catalog_len= *pos))
4079 catalog= (char*) pos+1; // Will be copied later
4080 CHECK_SPACE(pos, end, catalog_len + 2);
4081 pos+= catalog_len+2; // leap over end 0
4082 catalog_nz= 0; // catalog has end 0 in event
4083 break;
4084 case Q_LC_TIME_NAMES_CODE:
4085 CHECK_SPACE(pos, end, 2);
4086 lc_time_names_number= uint2korr(pos);
4087 pos+= 2;
4088 break;
4089 case Q_CHARSET_DATABASE_CODE:
4090 CHECK_SPACE(pos, end, 2);
4091 charset_database_number= uint2korr(pos);
4092 pos+= 2;
4093 break;
4094 case Q_TABLE_MAP_FOR_UPDATE_CODE:
4095 CHECK_SPACE(pos, end, 8);
4096 table_map_for_update= uint8korr(pos);
4097 pos+= 8;
4098 break;
4099 case Q_MASTER_DATA_WRITTEN_CODE:
4100 CHECK_SPACE(pos, end, 4);
4101 data_written= master_data_written= uint4korr(pos);
4102 pos+= 4;
4103 break;
4104 case Q_MICROSECONDS:
4105 {
4106 CHECK_SPACE(pos, end, 3);
4107 when.tv_usec= uint3korr(pos);
4108 pos+= 3;
4109 break;
4110 }
4111 case Q_INVOKER:
4112 {
4113 CHECK_SPACE(pos, end, 1);
4114 user.length= *pos++;
4115 CHECK_SPACE(pos, end, user.length);
4116 user.str= (char *)pos;
4117 if (user.length == 0)
4118 user.str= (char *)"";
4119 pos+= user.length;
4120
4121 CHECK_SPACE(pos, end, 1);
4122 host.length= *pos++;
4123 CHECK_SPACE(pos, end, host.length);
4124 host.str= (char *)pos;
4125 if (host.length == 0)
4126 host.str= (char *)"";
4127 pos+= host.length;
4128 break;
4129 }
4130 case Q_UPDATED_DB_NAMES:
4131 {
4132 uchar i= 0;
4133 CHECK_SPACE(pos, end, 1);
4134 mts_accessed_dbs= *pos++;
4135 /*
4136 Notice, the following check is positive also in case of
4137 the master's MAX_DBS_IN_EVENT_MTS > the slave's one and the event
4138 contains e.g the master's MAX_DBS_IN_EVENT_MTS db:s.
4139 */
4140 if (mts_accessed_dbs > MAX_DBS_IN_EVENT_MTS)
4141 {
4142 mts_accessed_dbs= OVER_MAX_DBS_IN_EVENT_MTS;
4143 break;
4144 }
4145
4146 DBUG_ASSERT(mts_accessed_dbs != 0);
4147
4148 for (i= 0; i < mts_accessed_dbs && pos < start + status_vars_len; i++)
4149 {
4150 DBUG_EXECUTE_IF("query_log_event_mts_corrupt_db_names",
4151 {
4152 if (mts_accessed_dbs == 2)
4153 {
4154 DBUG_ASSERT(pos[sizeof("d?") - 1] == 0);
4155 ((char*) pos)[sizeof("d?") - 1]= 'a';
4156 }});
4157 strncpy(mts_accessed_db_names[i], (char*) pos,
4158 min<ulong>(NAME_LEN, start + status_vars_len - pos));
4159 mts_accessed_db_names[i][NAME_LEN - 1]= 0;
4160 pos+= 1 + strlen((const char*) pos);
4161 }
4162 if (i != mts_accessed_dbs || pos > start + status_vars_len)
4163 DBUG_VOID_RETURN;
4164 break;
4165 }
4166 default:
4167 /* That's why you must write status vars in growing order of code */
4168 DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
4169 code: %u), skipping the rest of them", (uint) *(pos-1)));
4170 pos= (const uchar*) end; // Break loop
4171 }
4172 }
4173
4174 /**
4175 Layout for the data buffer is as follows
4176 +--------+-----------+------+------+---------+----+-------+
4177 | catlog | time_zone | user | host | db name | \0 | Query |
4178 +--------+-----------+------+------+---------+----+-------+
4179
4180 To support the query cache we append the following buffer to the above
4181 +-------+----------------------------------------+-------+
4182 |db len | uninitiatlized space of size of db len | FLAGS |
4183 +-------+----------------------------------------+-------+
4184
4185 The area of buffer starting from Query field all the way to the end belongs
4186 to the Query buffer and its structure is described in alloc_query() in
4187 sql_parse.cc
4188 */
4189
4190 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4191 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4192 + time_zone_len + 1
4193 + user.length + 1
4194 + host.length + 1
4195 + data_len + 1
4196 + sizeof(size_t)//for db_len
4197 + db_len + 1
4198 + QUERY_CACHE_FLAGS_SIZE,
4199 MYF(MY_WME))))
4200 #else
4201 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4202 + time_zone_len + 1
4203 + user.length + 1
4204 + host.length + 1
4205 + data_len + 1,
4206 MYF(MY_WME))))
4207 #endif
4208 DBUG_VOID_RETURN;
4209 if (catalog_len) // If catalog is given
4210 {
4211 /**
4212 @todo we should clean up and do only copy_str_and_move; it
4213 works for both cases. Then we can remove the catalog_nz
4214 flag. /sven
4215 */
4216 if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
4217 copy_str_and_move(&catalog, &start, catalog_len);
4218 else
4219 {
4220 memcpy(start, catalog, catalog_len+1); // copy end 0
4221 catalog= (const char *)start;
4222 start+= catalog_len+1;
4223 }
4224 }
4225 if (time_zone_len)
4226 copy_str_and_move(&time_zone_str, &start, time_zone_len);
4227
4228 if (user.length > 0)
4229 copy_str_and_move((const char **)&(user.str), &start, user.length);
4230 if (host.length > 0)
4231 copy_str_and_move((const char **)&(host.str), &start, host.length);
4232
4233 /**
4234 if time_zone_len or catalog_len are 0, then time_zone and catalog
4235 are uninitialized at this point. shouldn't they point to the
4236 zero-length null-terminated strings we allocated space for in the
4237 my_alloc call above? /sven
4238 */
4239
4240 /* A 2nd variable part; this is common to all versions */
4241 memcpy((char*) start, end, data_len); // Copy db and query
4242 start[data_len]= '\0'; // End query with \0 (For safetly)
4243 db= (char *)start;
4244 query= (char *)(start + db_len + 1);
4245 q_len= data_len - db_len -1;
4246
4247 if (data_len && (data_len < db_len ||
4248 data_len < q_len ||
4249 data_len != (db_len + q_len + 1)))
4250 {
4251 q_len= 0;
4252 query= NULL;
4253 DBUG_VOID_RETURN;
4254 }
4255
4256 unsigned int max_length;
4257 max_length= (event_len - ((const char*)(end + db_len + 1) -
4258 (buf - common_header_len)));
4259 if (q_len != max_length)
4260 {
4261 q_len= 0;
4262 query= NULL;
4263 DBUG_VOID_RETURN;
4264 }
4265 /**
4266 Append the db length at the end of the buffer. This will be used by
4267 Query_cache::send_result_to_client() in case the query cache is On.
4268 */
4269 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4270 size_t db_length= (size_t)db_len;
4271 memcpy(start + data_len + 1, &db_length, sizeof(size_t));
4272 #endif
4273 DBUG_VOID_RETURN;
4274 }
4275
4276
4277 #ifdef MYSQL_CLIENT
4278 /**
4279 Query_log_event::print().
4280
4281 @todo
4282 print the catalog ??
4283 */
print_query_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)4284 void Query_log_event::print_query_header(IO_CACHE* file,
4285 PRINT_EVENT_INFO* print_event_info)
4286 {
4287 // TODO: print the catalog ??
4288 char buff[48], *end; // Enough for "SET TIMESTAMP=1305535348.123456"
4289 char quoted_id[1+ 2*FN_REFLEN+ 2];
4290 int quoted_len= 0;
4291 bool different_db= 1;
4292 uint32 tmp;
4293
4294 if (!print_event_info->short_form)
4295 {
4296 print_header(file, print_event_info, FALSE);
4297 my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
4298 get_type_str(), (ulong) thread_id, (ulong) exec_time,
4299 error_code);
4300 }
4301
4302 if ((flags & LOG_EVENT_SUPPRESS_USE_F))
4303 {
4304 if (!is_trans_keyword())
4305 print_event_info->db[0]= '\0';
4306 }
4307 else if (db)
4308 {
4309 #ifdef MYSQL_SERVER
4310 quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
4311 #else
4312 quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
4313 #endif
4314 quoted_id[quoted_len]= '\0';
4315 different_db= memcmp(print_event_info->db, db, db_len + 1);
4316 if (different_db)
4317 memcpy(print_event_info->db, db, db_len + 1);
4318 if (db[0] && different_db)
4319 my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
4320 }
4321
4322 end=int10_to_str((long) when.tv_sec, strmov(buff,"SET TIMESTAMP="),10);
4323 if (when.tv_usec)
4324 end+= sprintf(end, ".%06d", (int) when.tv_usec);
4325 end= strmov(end, print_event_info->delimiter);
4326 *end++='\n';
4327 DBUG_ASSERT(end < buff + sizeof(buff));
4328 my_b_write(file, (uchar*) buff, (uint) (end-buff));
4329 if ((!print_event_info->thread_id_printed ||
4330 ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
4331 thread_id != print_event_info->thread_id)))
4332 {
4333 // If --short-form, print deterministic value instead of pseudo_thread_id.
4334 my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
4335 short_form ? 999999999 : (ulong)thread_id,
4336 print_event_info->delimiter);
4337 print_event_info->thread_id= thread_id;
4338 print_event_info->thread_id_printed= 1;
4339 }
4340
4341 /*
4342 If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
4343 print (remember we don't produce mixed relay logs so there cannot be
4344 5.0 events before that one so there is nothing to reset).
4345 */
4346 if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
4347 {
4348 /* tmp is a bitmask of bits which have changed. */
4349 if (likely(print_event_info->flags2_inited))
4350 /* All bits which have changed */
4351 tmp= (print_event_info->flags2) ^ flags2;
4352 else /* that's the first Query event we read */
4353 {
4354 print_event_info->flags2_inited= 1;
4355 tmp= ~((uint32)0); /* all bits have changed */
4356 }
4357
4358 if (unlikely(tmp)) /* some bits have changed */
4359 {
4360 bool need_comma= 0;
4361 my_b_printf(file, "SET ");
4362 print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
4363 "@@session.foreign_key_checks", &need_comma);
4364 print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
4365 "@@session.sql_auto_is_null", &need_comma);
4366 print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
4367 "@@session.unique_checks", &need_comma);
4368 print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
4369 "@@session.autocommit", &need_comma);
4370 my_b_printf(file,"%s\n", print_event_info->delimiter);
4371 print_event_info->flags2= flags2;
4372 }
4373 }
4374
4375 /*
4376 Now the session variables;
4377 it's more efficient to pass SQL_MODE as a number instead of a
4378 comma-separated list.
4379 FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
4380 variables (they have no global version; they're not listed in
4381 sql_class.h), The tests below work for pure binlogs or pure relay
4382 logs. Won't work for mixed relay logs but we don't create mixed
4383 relay logs (that is, there is no relay log with a format change
4384 except within the 3 first events, which mysqlbinlog handles
4385 gracefully). So this code should always be good.
4386 */
4387
4388 if (likely(sql_mode_inited) &&
4389 (unlikely(print_event_info->sql_mode != sql_mode ||
4390 !print_event_info->sql_mode_inited)))
4391 {
4392 my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
4393 (ulong)sql_mode, print_event_info->delimiter);
4394 print_event_info->sql_mode= sql_mode;
4395 print_event_info->sql_mode_inited= 1;
4396 }
4397 if (print_event_info->auto_increment_increment != auto_increment_increment ||
4398 print_event_info->auto_increment_offset != auto_increment_offset)
4399 {
4400 my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
4401 auto_increment_increment,auto_increment_offset,
4402 print_event_info->delimiter);
4403 print_event_info->auto_increment_increment= auto_increment_increment;
4404 print_event_info->auto_increment_offset= auto_increment_offset;
4405 }
4406
4407 /* TODO: print the catalog when we feature SET CATALOG */
4408
4409 if (likely(charset_inited) &&
4410 (unlikely(!print_event_info->charset_inited ||
4411 memcmp(print_event_info->charset, charset, 6))))
4412 {
4413 char *charset_p= charset; // Avoid type-punning warning.
4414 CHARSET_INFO *cs_info= get_charset(uint2korr(charset_p), MYF(MY_WME));
4415 if (cs_info)
4416 {
4417 /* for mysql client */
4418 my_b_printf(file, "/*!\\C %s */%s\n",
4419 cs_info->csname, print_event_info->delimiter);
4420 }
4421 my_b_printf(file,"SET "
4422 "@@session.character_set_client=%d,"
4423 "@@session.collation_connection=%d,"
4424 "@@session.collation_server=%d"
4425 "%s\n",
4426 uint2korr(charset_p),
4427 uint2korr(charset+2),
4428 uint2korr(charset+4),
4429 print_event_info->delimiter);
4430 memcpy(print_event_info->charset, charset, 6);
4431 print_event_info->charset_inited= 1;
4432 }
4433 if (time_zone_len)
4434 {
4435 if (memcmp(print_event_info->time_zone_str,
4436 time_zone_str, time_zone_len+1))
4437 {
4438 my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
4439 time_zone_str, print_event_info->delimiter);
4440 memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
4441 }
4442 }
4443 if (lc_time_names_number != print_event_info->lc_time_names_number)
4444 {
4445 my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
4446 lc_time_names_number, print_event_info->delimiter);
4447 print_event_info->lc_time_names_number= lc_time_names_number;
4448 }
4449 if (charset_database_number != print_event_info->charset_database_number)
4450 {
4451 if (charset_database_number)
4452 my_b_printf(file, "SET @@session.collation_database=%d%s\n",
4453 charset_database_number, print_event_info->delimiter);
4454 else
4455 my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
4456 print_event_info->delimiter);
4457 print_event_info->charset_database_number= charset_database_number;
4458 }
4459 }
4460
4461
print(FILE * file,PRINT_EVENT_INFO * print_event_info)4462 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4463 {
4464 IO_CACHE *const head= &print_event_info->head_cache;
4465
4466 /**
4467 reduce the size of io cache so that the write function is called
4468 for every call to my_b_write().
4469 */
4470 DBUG_EXECUTE_IF ("simulate_file_write_error",
4471 {head->write_pos= head->write_end- 500;});
4472 print_query_header(head, print_event_info);
4473 my_b_write(head, (uchar*) query, q_len);
4474 my_b_printf(head, "\n%s\n", print_event_info->delimiter);
4475 }
4476 #endif /* MYSQL_CLIENT */
4477
4478 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4479
4480 /**
4481 Associating slave Worker thread to a subset of temporary tables
4482 belonging to db-partitions the event accesses.
4483 The pointer if all entries is cleaned.
4484
4485 @param thd THD instance pointer
4486 */
attach_temp_tables_worker(THD * thd)4487 void Query_log_event::attach_temp_tables_worker(THD *thd)
4488 {
4489 if (!is_mts_worker(thd) || (ends_group() || starts_group()))
4490 return;
4491
4492 // in over max-db:s case just one special partition is locked
4493 int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4494 1 : mts_accessed_dbs);
4495
4496 DBUG_ASSERT(!thd->temporary_tables);
4497
4498 for (int i= 0; i < parts; i++)
4499 {
4500 mts_move_temp_tables_to_thd(thd,
4501 mts_assigned_partitions[i]->temporary_tables);
4502 mts_assigned_partitions[i]->temporary_tables= NULL;
4503 }
4504 }
4505
4506 /**
4507 Dissociating slave Worker thread from its thd->temporary_tables
4508 to possibly update the involved entries of db-to-worker hash
4509 with new values of temporary_tables.
4510
4511 @param thd THD instance pointer
4512 */
detach_temp_tables_worker(THD * thd)4513 void Query_log_event::detach_temp_tables_worker(THD *thd)
4514 {
4515 if (!is_mts_worker(thd))
4516 return;
4517
4518 int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4519 1 : mts_accessed_dbs);
4520 /*
4521 todo: optimize for a case of
4522
4523 a. one db
4524 Only detaching temporary_tables from thd to entry would require
4525 instead of the double-loop below.
4526
4527 b. unchanged thd->temporary_tables.
4528 In such case the involved entries would continue to hold the
4529 unmodified lists provided that the attach_ method does not
4530 destroy references to them.
4531 */
4532 for (int i= 0; i < parts; i++)
4533 {
4534 mts_assigned_partitions[i]->temporary_tables= NULL;
4535 }
4536
4537 for (TABLE *table= thd->temporary_tables; table;)
4538 {
4539 int i;
4540 char *db_name= NULL;
4541
4542 // find which entry to go
4543 for (i= 0; i < parts; i++)
4544 {
4545 db_name= mts_accessed_db_names[i];
4546
4547 if (!strlen(db_name))
4548 break;
4549
4550 // Only default database is rewritten.
4551 if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
4552 {
4553 size_t dummy_len;
4554 const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
4555 // db_name != db_filtered means that db_name is rewritten.
4556 if (strcmp(db_name, db_filtered))
4557 db_name= (char*)db_filtered;
4558 }
4559
4560 if (strcmp(table->s->db.str, db_name) < 0)
4561 continue;
4562 else
4563 {
4564 // When rewrite db rules are used we can not rely on
4565 // mts_accessed_db_names elements order.
4566 if (!rpl_filter->is_rewrite_empty() &&
4567 strcmp(table->s->db.str, db_name))
4568 continue;
4569 else
4570 break;
4571 }
4572 }
4573
4574 DBUG_ASSERT(db_name && (
4575 !strcmp(table->s->db.str, db_name) ||
4576 !strlen(db_name))
4577 );
4578 DBUG_ASSERT(i < mts_accessed_dbs);
4579
4580 // table pointer is shifted inside the function
4581 table= mts_move_temp_table_to_entry(table, thd, mts_assigned_partitions[i]);
4582 }
4583
4584 DBUG_ASSERT(!thd->temporary_tables);
4585 #ifndef DBUG_OFF
4586 for (int i= 0; i < parts; i++)
4587 {
4588 DBUG_ASSERT(!mts_assigned_partitions[i]->temporary_tables ||
4589 !mts_assigned_partitions[i]->temporary_tables->prev);
4590 }
4591 #endif
4592 }
4593
4594 /*
4595 Query_log_event::do_apply_event()
4596 */
do_apply_event(Relay_log_info const * rli)4597 int Query_log_event::do_apply_event(Relay_log_info const *rli)
4598 {
4599 return do_apply_event(rli, query, q_len);
4600 }
4601
4602 /*
4603 is_silent_error
4604
4605 Return true if the thread has an error which should be
4606 handled silently
4607 */
4608
is_silent_error(THD * thd)4609 static bool is_silent_error(THD* thd)
4610 {
4611 DBUG_ENTER("is_silent_error");
4612 Diagnostics_area::Sql_condition_iterator it=
4613 thd->get_stmt_da()->sql_conditions();
4614 const Sql_condition *err;
4615 while ((err= it++))
4616 {
4617 DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
4618 err->get_message_text()));
4619 switch (err->get_sql_errno())
4620 {
4621 case ER_SLAVE_SILENT_RETRY_TRANSACTION:
4622 {
4623 DBUG_RETURN(true);
4624 }
4625 default:
4626 break;
4627 }
4628 }
4629 DBUG_RETURN(false);
4630 }
4631
4632 /**
4633 @todo
4634 Compare the values of "affected rows" around here. Something
4635 like:
4636 @code
4637 if ((uint32) affected_in_event != (uint32) affected_on_slave)
4638 {
4639 sql_print_error("Slave: did not get the expected number of affected \
4640 rows running query from master - expected %d, got %d (this numbers \
4641 should have matched modulo 4294967296).", 0, ...);
4642 thd->query_error = 1;
4643 }
4644 @endcode
4645 We may also want an option to tell the slave to ignore "affected"
4646 mismatch. This mismatch could be implemented with a new ER_ code, and
4647 to ignore it you would use --slave-skip-errors...
4648 */
do_apply_event(Relay_log_info const * rli,const char * query_arg,uint32 q_len_arg)4649 int Query_log_event::do_apply_event(Relay_log_info const *rli,
4650 const char *query_arg, uint32 q_len_arg)
4651 {
4652 DBUG_ENTER("Query_log_event::do_apply_event");
4653 int expected_error,actual_error= 0;
4654 HA_CREATE_INFO db_options;
4655
4656 /*
4657 Colleagues: please never free(thd->catalog) in MySQL. This would
4658 lead to bugs as here thd->catalog is a part of an alloced block,
4659 not an entire alloced block (see
4660 Query_log_event::do_apply_event()). Same for thd->db. Thank
4661 you.
4662 */
4663 thd->catalog= catalog_len ? (char *) catalog : (char *)"";
4664
4665 size_t valid_len;
4666 bool len_error;
4667 bool is_invalid_db_name= validate_string(system_charset_info, db, db_len,
4668 &valid_len, &len_error);
4669
4670 DBUG_PRINT("debug",("is_invalid_db_name= %s, valid_len=%zu, len_error=%s",
4671 is_invalid_db_name ? "true" : "false",
4672 valid_len,
4673 len_error ? "true" : "false"));
4674
4675 if (is_invalid_db_name || len_error)
4676 {
4677 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4678 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4679 "Invalid database name in Query event.");
4680 thd->is_slave_error= true;
4681 goto end;
4682 }
4683
4684 set_thd_db(thd, db, db_len);
4685
4686 /*
4687 Setting the character set and collation of the current database thd->db.
4688 */
4689 load_db_opt_by_name(thd, thd->db, &db_options);
4690 if (db_options.default_table_charset)
4691 thd->db_charset= db_options.default_table_charset;
4692 thd->variables.auto_increment_increment= auto_increment_increment;
4693 thd->variables.auto_increment_offset= auto_increment_offset;
4694
4695 /*
4696 InnoDB internally stores the master log position it has executed so far,
4697 i.e. the position just after the COMMIT event.
4698 When InnoDB will want to store, the positions in rli won't have
4699 been updated yet, so group_master_log_* will point to old BEGIN
4700 and event_master_log* will point to the beginning of current COMMIT.
4701 But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
4702 END of the current log event (COMMIT). We save it in rli so that InnoDB can
4703 access it.
4704 */
4705 const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
4706 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
4707
4708 /*
4709 todo: such cleanup should not be specific to Query event and therefore
4710 is preferable at a common with other event pre-execution point
4711 */
4712 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4713 if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock != NULL)
4714 {
4715 /*
4716 Cleaning-up the last statement context:
4717 the terminal event of the current statement flagged with
4718 STMT_END_F got filtered out in ndb circular replication.
4719 */
4720 int error;
4721 char llbuff[22];
4722 if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
4723 {
4724 const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
4725 "Error in cleaning up after an event preceeding the commit; "
4726 "the group log file/position: %s %s",
4727 const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
4728 llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
4729 llbuff));
4730 }
4731 /*
4732 Executing a part of rli->stmt_done() logics that does not deal
4733 with group position change. The part is redundant now but is
4734 future-change-proof addon, e.g if COMMIT handling will start checking
4735 invariants like IN_STMT flag must be off at committing the transaction.
4736 */
4737 const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
4738 const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
4739 }
4740 else
4741 {
4742 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
4743 }
4744
4745 /*
4746 Note: We do not need to execute reset_one_shot_variables() if this
4747 db_ok() test fails.
4748 Reason: The db stored in binlog events is the same for SET and for
4749 its companion query. If the SET is ignored because of
4750 db_ok(), the companion query will also be ignored, and if
4751 the companion query is ignored in the db_ok() test of
4752 ::do_apply_event(), then the companion SET also have so
4753 we don't need to reset_one_shot_variables().
4754 */
4755 {
4756 thd->set_time(&when);
4757 thd->set_query_and_id((char*)query_arg, q_len_arg,
4758 thd->charset(), next_query_id());
4759 thd->set_query_for_display(query_arg, q_len_arg);
4760 thd->variables.pseudo_thread_id= thread_id; // for temp tables
4761 attach_temp_tables_worker(thd);
4762 DBUG_PRINT("query",("%s", thd->query()));
4763
4764 if (ignored_error_code((expected_error= error_code)) ||
4765 !unexpected_error_code(expected_error))
4766 {
4767 if (flags2_inited)
4768 /*
4769 all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
4770 must take their value from flags2.
4771 */
4772 thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
4773 /*
4774 else, we are in a 3.23/4.0 binlog; we previously received a
4775 Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
4776 nothing to do.
4777 */
4778 /*
4779 We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
4780 slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
4781 force us to ignore the dir too. Imagine you are a ring of machines, and
4782 one has a disk problem so that you temporarily need
4783 MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
4784 elsewhere (you don't want all slaves to start ignoring the dirs).
4785 */
4786 if (sql_mode_inited)
4787 thd->variables.sql_mode=
4788 (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
4789 (sql_mode & ~(ulonglong) MODE_NO_DIR_IN_CREATE));
4790 if (charset_inited)
4791 {
4792 if (rli->cached_charset_compare(charset))
4793 {
4794 char *charset_p= charset; // Avoid type-punning warning.
4795 /* Verify that we support the charsets found in the event. */
4796 if (!(thd->variables.character_set_client=
4797 get_charset(uint2korr(charset_p), MYF(MY_WME))) ||
4798 !(thd->variables.collation_connection=
4799 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
4800 !(thd->variables.collation_server=
4801 get_charset(uint2korr(charset+4), MYF(MY_WME))))
4802 {
4803 /*
4804 We updated the thd->variables with nonsensical values (0). Let's
4805 set them to something safe (i.e. which avoids crash), and we'll
4806 stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
4807 ignore this error).
4808 */
4809 set_slave_thread_default_charset(thd, rli);
4810 goto compare_errors;
4811 }
4812 thd->update_charset(); // for the charset change to take effect
4813 /*
4814 Reset thd->query_string.cs to the newly set value.
4815 Note, there is a small flaw here. For a very short time frame
4816 if the new charset is different from the old charset and
4817 if another thread executes "SHOW PROCESSLIST" after
4818 the above thd->set_query_and_id() and before this thd->set_query(),
4819 and if the current query has some non-ASCII characters,
4820 the another thread may see some '?' marks in the PROCESSLIST
4821 result. This should be acceptable now. This is a reminder
4822 to fix this if any refactoring happens here sometime.
4823 */
4824 thd->set_query((char*) query_arg, q_len_arg, thd->charset());
4825 thd->reset_query_for_display();
4826 }
4827 }
4828 if (time_zone_len)
4829 {
4830 String tmp(time_zone_str, time_zone_len, &my_charset_bin);
4831 if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
4832 {
4833 my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
4834 thd->variables.time_zone= global_system_variables.time_zone;
4835 goto compare_errors;
4836 }
4837 }
4838 if (lc_time_names_number)
4839 {
4840 if (!(thd->variables.lc_time_names=
4841 my_locale_by_number(lc_time_names_number)))
4842 {
4843 my_printf_error(ER_UNKNOWN_ERROR,
4844 "Unknown locale: '%d'", MYF(0), lc_time_names_number);
4845 thd->variables.lc_time_names= &my_locale_en_US;
4846 goto compare_errors;
4847 }
4848 }
4849 else
4850 thd->variables.lc_time_names= &my_locale_en_US;
4851 if (charset_database_number)
4852 {
4853 CHARSET_INFO *cs;
4854 if (!(cs= get_charset(charset_database_number, MYF(0))))
4855 {
4856 char buf[20];
4857 int10_to_str((int) charset_database_number, buf, -10);
4858 my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
4859 goto compare_errors;
4860 }
4861 thd->variables.collation_database= cs;
4862 }
4863 else
4864 thd->variables.collation_database= thd->db_charset;
4865
4866 {
4867 const CHARSET_INFO *cs= thd->charset();
4868 /*
4869 We cannot ask for parsing a statement using a character set
4870 without state_maps (parser internal data).
4871 */
4872 if (!cs->state_map)
4873 {
4874 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4875 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4876 "character_set cannot be parsed");
4877 thd->is_slave_error= true;
4878 goto end;
4879 }
4880 }
4881
4882 thd->table_map_for_update= (table_map)table_map_for_update;
4883 thd->set_invoker(&user, &host);
4884 /*
4885 Flag if we need to rollback the statement transaction on
4886 slave if it by chance succeeds.
4887 If we expected a non-zero error code and get nothing and,
4888 it is a concurrency issue or ignorable issue, effects
4889 of the statement should be rolled back.
4890 */
4891 if (expected_error &&
4892 (ignored_error_code(expected_error) ||
4893 concurrency_error_code(expected_error)))
4894 {
4895 thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
4896 }
4897 /* Execute the query (note that we bypass dispatch_command()) */
4898 Parser_state parser_state;
4899 if (!parser_state.init(thd, thd->query(), thd->query_length()))
4900 {
4901 DBUG_ASSERT(thd->m_digest == NULL);
4902 thd->m_digest= & thd->m_digest_state;
4903 DBUG_ASSERT(thd->m_statement_psi == NULL);
4904 thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
4905 stmt_info_rpl.m_key,
4906 thd->db, thd->db_length,
4907 thd->charset());
4908 THD_STAGE_INFO(thd, stage_init);
4909 if (thd->m_digest != NULL)
4910 thd->m_digest->reset(thd->m_token_array, max_digest_length);
4911
4912 mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
4913 /* Finalize server status flags after executing a statement. */
4914 thd->update_server_status();
4915 log_slow_statement(thd);
4916 }
4917
4918 thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
4919
4920 /*
4921 Resetting the enable_slow_log thd variable.
4922
4923 We need to reset it back to the opt_log_slow_slave_statements
4924 value after the statement execution (and slow logging
4925 is done). It might have changed if the statement was an
4926 admin statement (in which case, down in mysql_parse execution
4927 thd->enable_slow_log is set to the value of
4928 opt_log_slow_admin_statements).
4929 */
4930 thd->enable_slow_log= opt_log_slow_slave_statements;
4931 }
4932 else
4933 {
4934 /*
4935 The query got a really bad error on the master (thread killed etc),
4936 which could be inconsistent. Parse it to test the table names: if the
4937 replicate-*-do|ignore-table rules say "this query must be ignored" then
4938 we exit gracefully; otherwise we warn about the bad error and tell DBA
4939 to check/fix it.
4940 */
4941 if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
4942 clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
4943 else
4944 {
4945 rli->report(ERROR_LEVEL, expected_error,
4946 #ifdef WITH_WSREP
4947 "\
4948 Query partially completed on the master (error on master: %d) \
4949 and was aborted. There is a chance that your master is inconsistent at this \
4950 point. If you are sure that your master is ok, run this query manually on the \
4951 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4952 START SLAVE; . Query: '%s'", expected_error,
4953 (!opt_log_raw) && thd->rewritten_query.length()
4954 ? thd->rewritten_query.c_ptr_safe() : thd->query());
4955 #else
4956 "\
4957 Query partially completed on the master (error on master: %d) \
4958 and was aborted. There is a chance that your master is inconsistent at this \
4959 point. If you are sure that your master is ok, run this query manually on the \
4960 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4961 START SLAVE; . Query: '%s'", expected_error, thd->query());
4962 #endif /* WITH_WSREP */
4963 thd->is_slave_error= 1;
4964 }
4965 goto end;
4966 }
4967
4968 /* If the query was not ignored, it is printed to the general log */
4969 if (!thd->is_error() || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
4970 {
4971 /* log the rewritten query if the query was rewritten
4972 and the option to log raw was not set.
4973
4974 There is an assumption here. We assume that query log
4975 events can never have multi-statement queries, thus the
4976 parsed statement is the same as the raw one.
4977 */
4978 if (opt_log_raw || thd->rewritten_query.length() == 0)
4979 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
4980 else
4981 general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
4982 thd->rewritten_query.length());
4983 }
4984
4985 compare_errors:
4986 /*
4987 In the slave thread, we may sometimes execute some DROP / * 40005
4988 TEMPORARY * / TABLE that come from parts of binlogs (likely if we
4989 use RESET SLAVE or CHANGE MASTER TO), while the temporary table
4990 has already been dropped. To ignore such irrelevant "table does
4991 not exist errors", we silently clear the error if TEMPORARY was used.
4992 */
4993 if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
4994 thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
4995 !expected_error)
4996 thd->get_stmt_da()->reset_diagnostics_area();
4997 /*
4998 If we expected a non-zero error code, and we don't get the same error
4999 code, and it should be ignored or is related to a concurrency issue.
5000 */
5001 actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
5002 DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
5003 expected_error, actual_error));
5004
5005 /*
5006 If a statement with expected error is received on slave and if the
5007 statement is not filtered on the slave, only then compare the expected
5008 error with the actual error that happened on slave.
5009 */
5010 if ((expected_error && rpl_filter->db_ok(thd->db) &&
5011 expected_error != actual_error &&
5012 !concurrency_error_code(expected_error)) &&
5013 !ignored_error_code(actual_error) &&
5014 !ignored_error_code(expected_error))
5015 {
5016 rli->report(ERROR_LEVEL, 0,
5017 "\
5018 Query caused different errors on master and slave. \
5019 Error on master: message (format)='%s' error code=%d ; \
5020 Error on slave: actual message='%s', error code=%d. \
5021 Default database: '%s'. Query: '%s'",
5022 ER_SAFE(expected_error),
5023 expected_error,
5024 actual_error ? thd->get_stmt_da()->message() : "no error",
5025 actual_error,
5026 #ifdef WITH_WSREP
5027 print_slave_db_safe(db),
5028 (!opt_log_raw) && thd->rewritten_query.length()
5029 ? thd->rewritten_query.c_ptr_safe() : query_arg);
5030 #else
5031 print_slave_db_safe(db), query_arg);
5032 #endif /* WITH_WSREP */
5033 thd->is_slave_error= 1;
5034 }
5035 /*
5036 If we get the same error code as expected and it is not a concurrency
5037 issue, or should be ignored.
5038 */
5039 else if ((expected_error == actual_error &&
5040 !concurrency_error_code(expected_error)) ||
5041 ignored_error_code(actual_error))
5042 {
5043 DBUG_PRINT("info",("error ignored"));
5044 if (actual_error && log_warnings > 1 && ignored_error_code(actual_error))
5045 {
5046 if (actual_error == ER_SLAVE_IGNORED_TABLE)
5047 {
5048 if (!slave_ignored_err_throttle.log(thd))
5049 rli->report(WARNING_LEVEL, actual_error,
5050 "Could not execute %s event. Detailed error: %s;"
5051 " Error log throttle is enabled. This error will not be"
5052 " displayed for next %lu secs. It will be suppressed",
5053 get_type_str(), thd->get_stmt_da()->message(),
5054 (window_size / 1000000));
5055 }
5056 else
5057 rli->report(WARNING_LEVEL, actual_error,
5058 "Could not execute %s event. Detailed error: %s;",
5059 get_type_str(), thd->get_stmt_da()->message());
5060 }
5061 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
5062 thd->killed= THD::NOT_KILLED;
5063 }
5064 /*
5065 Other cases: mostly we expected no error and get one.
5066 */
5067 else if (thd->is_slave_error || thd->is_fatal_error)
5068 {
5069 if (!is_silent_error(thd))
5070 {
5071 rli->report(ERROR_LEVEL, actual_error,
5072 "Error '%s' on query. Default database: '%s'. Query: '%s'",
5073 (actual_error ? thd->get_stmt_da()->message() :
5074 "unexpected success or fatal error"),
5075 #ifdef WITH_WSREP
5076 print_slave_db_safe(thd->db),
5077 (!opt_log_raw) && thd->rewritten_query.length()
5078 ? thd->rewritten_query.c_ptr_safe() : query_arg);
5079 #else
5080 print_slave_db_safe(thd->db), query_arg);
5081 #endif /* WITH_WSREP */
5082 }
5083 thd->is_slave_error= 1;
5084 }
5085
5086 /*
5087 TODO: compare the values of "affected rows" around here. Something
5088 like:
5089 if ((uint32) affected_in_event != (uint32) affected_on_slave)
5090 {
5091 sql_print_error("Slave: did not get the expected number of affected \
5092 rows running query from master - expected %d, got %d (this numbers \
5093 should have matched modulo 4294967296).", 0, ...);
5094 thd->is_slave_error = 1;
5095 }
5096 We may also want an option to tell the slave to ignore "affected"
5097 mismatch. This mismatch could be implemented with a new ER_ code, and
5098 to ignore it you would use --slave-skip-errors...
5099
5100 To do the comparison we need to know the value of "affected" which the
5101 above mysql_parse() computed. And we need to know the value of
5102 "affected" in the master's binlog. Both will be implemented later. The
5103 important thing is that we now have the format ready to log the values
5104 of "affected" in the binlog. So we can release 5.0.0 before effectively
5105 logging "affected" and effectively comparing it.
5106 */
5107 } /* End of if (db_ok(... */
5108
5109 {
5110 /**
5111 The following failure injecion works in cooperation with tests
5112 setting @@global.debug= 'd,stop_slave_middle_group'.
5113 The sql thread receives the killed status and will proceed
5114 to shutdown trying to finish incomplete events group.
5115 */
5116
5117 // TODO: address the middle-group killing in MTS case
5118
5119 DBUG_EXECUTE_IF("stop_slave_middle_group",
5120 if (strcmp("COMMIT", query) != 0 &&
5121 strcmp("BEGIN", query) != 0)
5122 {
5123 if (thd->transaction.all.cannot_safely_rollback())
5124 const_cast<Relay_log_info*>(rli)->abort_slave= 1;
5125 };);
5126 }
5127
5128 end:
5129
5130 if (thd->temporary_tables)
5131 detach_temp_tables_worker(thd);
5132 /*
5133 Probably we have set thd->query, thd->db, thd->catalog to point to places
5134 in the data_buf of this event. Now the event is going to be deleted
5135 probably, so data_buf will be freed, so the thd->... listed above will be
5136 pointers to freed memory.
5137 So we must set them to 0, so that those bad pointers values are not later
5138 used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
5139 don't suffer from these assignments to 0 as DROP TEMPORARY
5140 TABLE uses the db.table syntax.
5141 */
5142 thd->catalog= 0;
5143 thd->set_db(NULL, 0); /* will free the current database */
5144 thd->reset_query();
5145 thd->lex->sql_command= SQLCOM_END;
5146 DBUG_PRINT("info", ("end: query= 0"));
5147
5148 /* Mark the statement completed. */
5149 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
5150 thd->m_statement_psi= NULL;
5151 thd->m_digest= NULL;
5152
5153 /*
5154 As a disk space optimization, future masters will not log an event for
5155 LAST_INSERT_ID() if that function returned 0 (and thus they will be able
5156 to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
5157 variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
5158 resetting below we are ready to support that.
5159 */
5160 thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
5161 thd->first_successful_insert_id_in_prev_stmt= 0;
5162 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5163 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5164 DBUG_RETURN(thd->is_slave_error);
5165 }
5166
do_update_pos(Relay_log_info * rli)5167 int Query_log_event::do_update_pos(Relay_log_info *rli)
5168 {
5169 /*
5170 Note that we will not increment group* positions if we are just
5171 after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
5172 from its following updating query.
5173 */
5174 int ret= 0;
5175 if (thd->one_shot_set)
5176 {
5177 rli->inc_event_relay_log_pos();
5178 }
5179 else
5180 ret= Log_event::do_update_pos(rli);
5181
5182 DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
5183 if (!strcmp("COMMIT", query))
5184 {
5185 sql_print_information("Crashing crash_after_commit_and_update_pos.");
5186 rli->flush_info(true);
5187 ha_flush_logs(0);
5188 DBUG_SUICIDE();
5189 }
5190 );
5191
5192 return ret;
5193 }
5194
5195
5196 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5197 Query_log_event::do_shall_skip(Relay_log_info *rli)
5198 {
5199 DBUG_ENTER("Query_log_event::do_shall_skip");
5200 DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
5201 DBUG_ASSERT(query && q_len > 0);
5202
5203 if (rli->slave_skip_counter > 0)
5204 {
5205 if (strcmp("BEGIN", query) == 0)
5206 {
5207 thd->variables.option_bits|= OPTION_BEGIN;
5208 DBUG_RETURN(Log_event::continue_group(rli));
5209 }
5210
5211 if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
5212 {
5213 thd->variables.option_bits&= ~OPTION_BEGIN;
5214 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5215 }
5216 }
5217 DBUG_RETURN(Log_event::do_shall_skip(rli));
5218 }
5219
5220 #endif
5221
5222
5223 /**************************************************************************
5224 Start_log_event_v3 methods
5225 **************************************************************************/
5226
5227 #ifndef MYSQL_CLIENT
Start_log_event_v3()5228 Start_log_event_v3::Start_log_event_v3()
5229 :Log_event(), created(0), binlog_version(BINLOG_VERSION),
5230 dont_set_created(0)
5231 {
5232 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5233 }
5234 #endif
5235
5236 /*
5237 Start_log_event_v3::pack_info()
5238 */
5239
5240 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5241 int Start_log_event_v3::pack_info(Protocol *protocol)
5242 {
5243 char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5244 pos= strmov(buf, "Server ver: ");
5245 pos= strmov(pos, server_version);
5246 pos= strmov(pos, ", Binlog ver: ");
5247 pos= int10_to_str(binlog_version, pos, 10);
5248 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5249 return 0;
5250 }
5251 #endif
5252
5253
5254 /*
5255 Start_log_event_v3::print()
5256 */
5257
5258 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5259 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5260 {
5261 DBUG_ENTER("Start_log_event_v3::print");
5262
5263 IO_CACHE *const head= &print_event_info->head_cache;
5264
5265 if (!print_event_info->short_form)
5266 {
5267 print_header(head, print_event_info, FALSE);
5268 my_b_printf(head, "\tStart: binlog v %d, server v %s created ",
5269 binlog_version, server_version);
5270 print_timestamp(head, NULL);
5271 if (created)
5272 my_b_printf(head," at startup");
5273 my_b_printf(head, "\n");
5274 if (flags & LOG_EVENT_BINLOG_IN_USE_F)
5275 my_b_printf(head, "# Warning: this binlog is either in use or was not "
5276 "closed properly.\n");
5277 }
5278 if (!is_artificial_event() && created)
5279 {
5280 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5281 /*
5282 This is for mysqlbinlog: like in replication, we want to delete the stale
5283 tmp files left by an unclean shutdown of mysqld (temporary tables)
5284 and rollback unfinished transaction.
5285 Probably this can be done with RESET CONNECTION (syntax to be defined).
5286 */
5287 my_b_printf(head,"RESET CONNECTION%s\n", print_event_info->delimiter);
5288 #else
5289 my_b_printf(head,"ROLLBACK%s\n", print_event_info->delimiter);
5290 if (print_event_info->is_gtid_next_set)
5291 print_event_info->is_gtid_next_valid= false;
5292 #endif
5293 }
5294 // set gtid_next=automatic if we have previously set it to uuid:number
5295 if (!print_event_info->is_gtid_next_valid)
5296 {
5297 my_b_printf(head, "%sAUTOMATIC'%s\n",
5298 Gtid_log_event::SET_STRING_PREFIX,
5299 print_event_info->delimiter);
5300 print_event_info->is_gtid_next_set= false;
5301 print_event_info->is_gtid_next_valid= true;
5302 }
5303 if (temp_buf &&
5304 print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5305 !print_event_info->short_form)
5306 {
5307 if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
5308 my_b_printf(head, "BINLOG '\n");
5309 print_base64(head, print_event_info, FALSE);
5310 print_event_info->printed_fd_event= TRUE;
5311 }
5312 DBUG_VOID_RETURN;
5313 }
5314 #endif /* MYSQL_CLIENT */
5315
5316 /*
5317 Start_log_event_v3::Start_log_event_v3()
5318 */
5319
Start_log_event_v3(const char * buf,uint event_len,const Format_description_log_event * description_event)5320 Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
5321 const Format_description_log_event
5322 *description_event)
5323 :Log_event(buf, description_event), binlog_version(BINLOG_VERSION)
5324 {
5325 if (event_len < (uint)description_event->common_header_len +
5326 ST_COMMON_HEADER_LEN_OFFSET)
5327 {
5328 server_version[0]= 0;
5329 return;
5330 }
5331 buf+= description_event->common_header_len;
5332 binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
5333 memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
5334 ST_SERVER_VER_LEN);
5335 // prevent overrun if log is corrupted on disk
5336 server_version[ST_SERVER_VER_LEN-1]= 0;
5337 created= uint4korr(buf+ST_CREATED_OFFSET);
5338 dont_set_created= 1;
5339 }
5340
5341
5342 /*
5343 Start_log_event_v3::write()
5344 */
5345
5346 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5347 bool Start_log_event_v3::write(IO_CACHE* file)
5348 {
5349 char buff[START_V3_HEADER_LEN];
5350 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5351 memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5352 if (!dont_set_created)
5353 created= get_time();
5354 int4store(buff + ST_CREATED_OFFSET,created);
5355 return (write_header(file, sizeof(buff)) ||
5356 wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
5357 write_footer(file));
5358 }
5359 #endif
5360
5361
5362 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5363
5364 /**
5365 Start_log_event_v3::do_apply_event() .
5366 The master started
5367
5368 IMPLEMENTATION
5369 - To handle the case where the master died without having time to write
5370 DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
5371 TODO), we clean up all temporary tables that we got, if we are sure we
5372 can (see below).
5373
5374 @todo
5375 - Remove all active user locks.
5376 Guilhem 2003-06: this is true but not urgent: the worst it can cause is
5377 the use of a bit of memory for a user lock which will not be used
5378 anymore. If the user lock is later used, the old one will be released. In
5379 other words, no deadlock problem.
5380 */
5381
do_apply_event(Relay_log_info const * rli)5382 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
5383 {
5384 DBUG_ENTER("Start_log_event_v3::do_apply_event");
5385 int error= 0;
5386 switch (binlog_version)
5387 {
5388 case 3:
5389 case 4:
5390 /*
5391 This can either be 4.x (then a Start_log_event_v3 is only at master
5392 startup so we are sure the master has restarted and cleared his temp
5393 tables; the event always has 'created'>0) or 5.0 (then we have to test
5394 'created').
5395 */
5396 if (created)
5397 {
5398 error= close_temporary_tables(thd);
5399 cleanup_load_tmpdir();
5400 }
5401 else
5402 {
5403 /*
5404 Set all temporary tables thread references to the current thread
5405 as they may point to the "old" SQL slave thread in case of its
5406 restart.
5407 */
5408 TABLE *table;
5409 for (table= thd->temporary_tables; table; table= table->next)
5410 table->in_use= thd;
5411 }
5412 break;
5413
5414 /*
5415 Now the older formats; in that case load_tmpdir is cleaned up by the I/O
5416 thread.
5417 */
5418 case 1:
5419 if (strncmp(rli->get_rli_description_event()->server_version,
5420 "3.23.57",7) >= 0 && created)
5421 {
5422 /*
5423 Can distinguish, based on the value of 'created': this event was
5424 generated at master startup.
5425 */
5426 error= close_temporary_tables(thd);
5427 }
5428 /*
5429 Otherwise, can't distinguish a Start_log_event generated at
5430 master startup and one generated by master FLUSH LOGS, so cannot
5431 be sure temp tables have to be dropped. So do nothing.
5432 */
5433 break;
5434 default:
5435 /*
5436 This case is not expected. It can be either an event corruption or an
5437 unsupported binary log version.
5438 */
5439 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5440 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5441 "Binlog version not supported");
5442 DBUG_RETURN(1);
5443 }
5444 DBUG_RETURN(error);
5445 }
5446 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5447
5448 /***************************************************************************
5449 Format_description_log_event methods
5450 ****************************************************************************/
5451
5452 /**
5453 Format_description_log_event 1st ctor.
5454
5455 Ctor. Can be used to create the event to write to the binary log (when the
5456 server starts or when FLUSH LOGS), or to create artificial events to parse
5457 binlogs from MySQL 3.23 or 4.x.
5458 When in a client, only the 2nd use is possible.
5459
5460 @param binlog_version the binlog version for which we want to build
5461 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
5462 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
5463 old 4.0 (binlog version 2) is not supported;
5464 it should not be used for replication with
5465 5.0.
5466 @param server_ver a string containing the server version.
5467 */
5468
5469 Format_description_log_event::
Format_description_log_event(uint8 binlog_ver,const char * server_ver)5470 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
5471 :Start_log_event_v3(), event_type_permutation(0)
5472 {
5473 binlog_version= binlog_ver;
5474 switch (binlog_ver) {
5475 case 4: /* MySQL 5.0 */
5476 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5477 DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
5478 strmov(server_version, "5.0.34"););
5479 common_header_len= LOG_EVENT_HEADER_LEN;
5480 number_of_event_types= LOG_EVENT_TYPES;
5481 /* we'll catch my_malloc() error in is_valid() */
5482 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
5483 + BINLOG_CHECKSUM_ALG_DESC_LEN,
5484 MYF(0));
5485 /*
5486 This long list of assignments is not beautiful, but I see no way to
5487 make it nicer, as the right members are #defines, not array members, so
5488 it's impossible to write a loop.
5489 */
5490 if (post_header_len)
5491 {
5492 #ifndef DBUG_OFF
5493 // Allows us to sanity-check that all events initialized their
5494 // events (see the end of this 'if' block).
5495 memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
5496 #endif
5497
5498 /* Note: all event types must explicitly fill in their lengths here. */
5499 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5500 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
5501 post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
5502 post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
5503 post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
5504 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5505 post_header_len[SLAVE_EVENT-1]= 0; /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5506 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5507 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5508 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5509 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5510 post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
5511 post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
5512 post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
5513 post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
5514 post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
5515 post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
5516 post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
5517 /*
5518 The PRE_GA events are never be written to any binlog, but
5519 their lengths are included in Format_description_log_event.
5520 Hence, we need to be assign some value here, to avoid reading
5521 uninitialized memory when the array is written to disk.
5522 */
5523 post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
5524 post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
5525 post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
5526
5527 post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
5528 post_header_len[WRITE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5529 post_header_len[UPDATE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5530 post_header_len[DELETE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5531 /*
5532 We here have the possibility to simulate a master of before we changed
5533 the table map id to be stored in 6 bytes: when it was stored in 4
5534 bytes (=> post_header_len was 6). This is used to test backward
5535 compatibility.
5536 This code can be removed after a few months (today is Dec 21st 2005),
5537 when we know that the 4-byte masters are not deployed anymore (check
5538 with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
5539 too.
5540 */
5541 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5542 post_header_len[TABLE_MAP_EVENT-1]=
5543 post_header_len[WRITE_ROWS_EVENT_V1-1]=
5544 post_header_len[UPDATE_ROWS_EVENT_V1-1]=
5545 post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
5546 post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
5547 post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
5548 post_header_len[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5549 post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5550 post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5551 post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5552 post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5553 post_header_len[GTID_LOG_EVENT-1]=
5554 post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]=
5555 Gtid_log_event::POST_HEADER_LENGTH;
5556 post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5557
5558 // Sanity-check that all post header lengths are initialized.
5559 int i;
5560 for (i=0; i<number_of_event_types; i++)
5561 DBUG_ASSERT(post_header_len[i] != 255);
5562 }
5563 break;
5564
5565 case 1: /* 3.23 */
5566 case 3: /* 4.0.x x>=2 */
5567 /*
5568 We build an artificial (i.e. not sent by the master) event, which
5569 describes what those old master versions send.
5570 */
5571 if (binlog_ver==1)
5572 strmov(server_version, server_ver ? server_ver : "3.23");
5573 else
5574 strmov(server_version, server_ver ? server_ver : "4.0");
5575 common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
5576 LOG_EVENT_MINIMAL_HEADER_LEN;
5577 /*
5578 The first new event in binlog version 4 is Format_desc. So any event type
5579 after that does not exist in older versions. We use the events known by
5580 version 3, even if version 1 had only a subset of them (this is not a
5581 problem: it uses a few bytes for nothing but unifies code; it does not
5582 make the slave detect less corruptions).
5583 */
5584 number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
5585 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
5586 MYF(0));
5587 if (post_header_len)
5588 {
5589 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5590 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
5591 post_header_len[STOP_EVENT-1]= 0;
5592 post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
5593 post_header_len[INTVAR_EVENT-1]= 0;
5594 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5595 post_header_len[SLAVE_EVENT-1]= 0; /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5596 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5597 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5598 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5599 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5600 post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
5601 post_header_len[RAND_EVENT-1]= 0;
5602 post_header_len[USER_VAR_EVENT-1]= 0;
5603 }
5604 break;
5605 default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
5606 post_header_len= 0; /* will make is_valid() fail */
5607 break;
5608 }
5609 calc_server_version_split();
5610 checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5611 }
5612
5613
5614 /**
5615 The problem with this constructor is that the fixed header may have a
5616 length different from this version, but we don't know this length as we
5617 have not read the Format_description_log_event which says it, yet. This
5618 length is in the post-header of the event, but we don't know where the
5619 post-header starts.
5620
5621 So this type of event HAS to:
5622 - either have the header's length at the beginning (in the header, at a
5623 fixed position which will never be changed), not in the post-header. That
5624 would make the header be "shifted" compared to other events.
5625 - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
5626 versions, so that we know for sure.
5627
5628 I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
5629 it is sent before Format_description_log_event).
5630 */
5631
5632 Format_description_log_event::
Format_description_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5633 Format_description_log_event(const char* buf,
5634 uint event_len,
5635 const
5636 Format_description_log_event*
5637 description_event)
5638 :Start_log_event_v3(buf, event_len, description_event),
5639 common_header_len(0), post_header_len(NULL), event_type_permutation(0)
5640 {
5641 ulong ver_calc;
5642 DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
5643 if (!Start_log_event_v3::is_valid())
5644 DBUG_VOID_RETURN; /* sanity check */
5645 buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
5646 if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
5647 DBUG_VOID_RETURN; /* sanity check */
5648 number_of_event_types=
5649 event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
5650 DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
5651 common_header_len, number_of_event_types));
5652 /* If alloc fails, we'll detect it in is_valid() */
5653
5654 post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
5655 number_of_event_types*
5656 sizeof(*post_header_len),
5657 MYF(0));
5658 calc_server_version_split();
5659 if ((ver_calc= get_version_product()) >= checksum_version_product)
5660 {
5661 /* the last bytes are the checksum alg desc and value (or value's room) */
5662 number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
5663 /*
5664 FD from the checksum-home version server (ver_calc ==
5665 checksum_version_product) must have
5666 number_of_event_types == LOG_EVENT_TYPES.
5667 */
5668 DBUG_ASSERT(ver_calc != checksum_version_product ||
5669 number_of_event_types == LOG_EVENT_TYPES);
5670 checksum_alg= post_header_len[number_of_event_types];
5671 }
5672 else
5673 {
5674 checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5675 }
5676
5677 /*
5678 In some previous versions, the events were given other event type
5679 id numbers than in the present version. When replicating from such
5680 a version, we therefore set up an array that maps those id numbers
5681 to the id numbers of the present server.
5682
5683 If post_header_len is null, it means malloc failed, and is_valid
5684 will fail, so there is no need to do anything.
5685
5686 The trees in which events have wrong id's are:
5687
5688 mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
5689 mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
5690 mysql-5.1-wl2325-no-dd
5691
5692 (this was found by grepping for two lines in sequence where the
5693 first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
5694 "TABLE_MAP_EVENT," in log_event.h in all trees)
5695
5696 In these trees, the following server_versions existed since
5697 TABLE_MAP_EVENT was introduced:
5698
5699 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
5700 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
5701 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
5702 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
5703 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
5704 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
5705 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
5706 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
5707 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
5708 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
5709 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
5710 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
5711 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
5712 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
5713 5.2.2-a_drop6p13c
5714
5715 (this was found by grepping for "mysql," in all historical
5716 versions of configure.in in the trees listed above).
5717
5718 There are 5.1.1-alpha versions that use the new event id's, so we
5719 do not test that version string. So replication from 5.1.1-alpha
5720 with the other event id's to a new version does not work.
5721 Moreover, we can safely ignore the part after drop[56]. This
5722 allows us to simplify the big list above to the following regexes:
5723
5724 5\.1\.[1-5]-a_drop5.*
5725 5\.1\.4-a_drop6.*
5726 5\.2\.[0-2]-a_drop6.*
5727
5728 This is what we test for in the 'if' below.
5729 */
5730 if (post_header_len &&
5731 server_version[0] == '5' && server_version[1] == '.' &&
5732 server_version[3] == '.' &&
5733 strncmp(server_version + 5, "-a_drop", 7) == 0 &&
5734 ((server_version[2] == '1' &&
5735 server_version[4] >= '1' && server_version[4] <= '5' &&
5736 server_version[12] == '5') ||
5737 (server_version[2] == '1' &&
5738 server_version[4] == '4' &&
5739 server_version[12] == '6') ||
5740 (server_version[2] == '2' &&
5741 server_version[4] >= '0' && server_version[4] <= '2' &&
5742 server_version[12] == '6')))
5743 {
5744 if (number_of_event_types != 22)
5745 {
5746 DBUG_PRINT("info", (" number_of_event_types=%d",
5747 number_of_event_types));
5748 /* this makes is_valid() return false. */
5749 my_free(post_header_len);
5750 post_header_len= NULL;
5751 DBUG_VOID_RETURN;
5752 }
5753 static const uint8 perm[EVENT_TYPE_PERMUTATION_NUM]=
5754 {
5755 UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
5756 INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
5757 APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
5758 NEW_LOAD_EVENT,
5759 RAND_EVENT, USER_VAR_EVENT,
5760 FORMAT_DESCRIPTION_EVENT,
5761 TABLE_MAP_EVENT,
5762 PRE_GA_WRITE_ROWS_EVENT,
5763 PRE_GA_UPDATE_ROWS_EVENT,
5764 PRE_GA_DELETE_ROWS_EVENT,
5765 XID_EVENT,
5766 BEGIN_LOAD_QUERY_EVENT,
5767 EXECUTE_LOAD_QUERY_EVENT,
5768 };
5769 event_type_permutation= perm;
5770 /*
5771 Since we use (permuted) event id's to index the post_header_len
5772 array, we need to permute the post_header_len array too.
5773 */
5774 uint8 post_header_len_temp[EVENT_TYPE_PERMUTATION_NUM];
5775 for (uint i= 1; i < EVENT_TYPE_PERMUTATION_NUM; i++)
5776 post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
5777 for (uint i= 0; i < EVENT_TYPE_PERMUTATION_NUM - 1; i++)
5778 post_header_len[i] = post_header_len_temp[i];
5779 }
5780 DBUG_VOID_RETURN;
5781 }
5782
5783 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5784 bool Format_description_log_event::write(IO_CACHE* file)
5785 {
5786 bool ret;
5787 bool no_checksum;
5788 /*
5789 We don't call Start_log_event_v3::write() because this would make 2
5790 my_b_safe_write().
5791 */
5792 uchar buff[FORMAT_DESCRIPTION_HEADER_LEN + BINLOG_CHECKSUM_ALG_DESC_LEN];
5793 size_t rec_size= sizeof(buff);
5794 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5795 memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5796 if (!dont_set_created)
5797 created= get_time();
5798 int4store(buff + ST_CREATED_OFFSET,created);
5799 buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
5800 memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
5801 LOG_EVENT_TYPES);
5802 /*
5803 if checksum is requested
5804 record the checksum-algorithm descriptor next to
5805 post_header_len vector which will be followed by the checksum value.
5806 Master is supposed to trigger checksum computing by binlog_checksum_options,
5807 slave does it via marking the event according to
5808 FD_queue checksum_alg value.
5809 */
5810 compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
5811 #ifndef DBUG_OFF
5812 data_written= 0; // to prepare for need_checksum assert
5813 #endif
5814 buff[FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
5815 checksum_alg : (uint8) BINLOG_CHECKSUM_ALG_OFF;
5816 /*
5817 FD of checksum-aware server is always checksum-equipped, (V) is in,
5818 regardless of @@global.binlog_checksum policy.
5819 Thereby a combination of (A) == 0, (V) != 0 means
5820 it's the checksum-aware server's FD event that heads checksum-free binlog
5821 file.
5822 Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
5823 A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
5824 heading the checksummed binlog.
5825 (A), (V) presence in FD of the checksum-aware server makes the event
5826 1 + 4 bytes bigger comparing to the former FD.
5827 */
5828
5829 if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
5830 {
5831 checksum_alg= BINLOG_CHECKSUM_ALG_CRC32; // Forcing (V) room to fill anyway
5832 }
5833 ret= (write_header(file, rec_size) ||
5834 wrapper_my_b_safe_write(file, buff, rec_size) ||
5835 write_footer(file));
5836 if (no_checksum)
5837 checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
5838 return ret;
5839 }
5840 #endif
5841
5842 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5843 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
5844 {
5845 int ret= 0;
5846 DBUG_ENTER("Format_description_log_event::do_apply_event");
5847
5848 /*
5849 As a transaction NEVER spans on 2 or more binlogs:
5850 if we have an active transaction at this point, the master died
5851 while writing the transaction to the binary log, i.e. while
5852 flushing the binlog cache to the binlog. XA guarantees that master has
5853 rolled back. So we roll back.
5854 Note: this event could be sent by the master to inform us of the
5855 format of its binlog; in other words maybe it is not at its
5856 original place when it comes to us; we'll know this by checking
5857 log_pos ("artificial" events have log_pos == 0).
5858 */
5859 if (!thd->rli_fake && !is_artificial_event() && created
5860 && thd->transaction.all.ha_list)
5861 {
5862 /* This is not an error (XA is safe), just an information */
5863 rli->report(INFORMATION_LEVEL, 0,
5864 "Rolling back unfinished transaction (no COMMIT "
5865 "or ROLLBACK in relay log). A probable cause is that "
5866 "the master died while writing the transaction to "
5867 "its binary log, thus rolled back too.");
5868 const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
5869 }
5870
5871 /*
5872 If this event comes from ourselves, there is no cleaning task to
5873 perform, we don't call Start_log_event_v3::do_apply_event()
5874 (this was just to update the log's description event).
5875 */
5876 if (server_id != (uint32) ::server_id)
5877 {
5878 /*
5879 If the event was not requested by the slave i.e. the master sent
5880 it while the slave asked for a position >4, the event will make
5881 rli->group_master_log_pos advance. Say that the slave asked for
5882 position 1000, and the Format_desc event's end is 96. Then in
5883 the beginning of replication rli->group_master_log_pos will be
5884 0, then 96, then jump to first really asked event (which is
5885 >96). So this is ok.
5886 */
5887 ret= Start_log_event_v3::do_apply_event(rli);
5888 }
5889
5890 if (!ret)
5891 {
5892 /* Save the information describing this binlog */
5893 const_cast<Relay_log_info *>(rli)->set_rli_description_event(this);
5894 }
5895
5896 DBUG_RETURN(ret);
5897 }
5898
do_update_pos(Relay_log_info * rli)5899 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
5900 {
5901 if (server_id == (uint32) ::server_id)
5902 {
5903 /*
5904 We only increase the relay log position if we are skipping
5905 events and do not touch any group_* variables, nor flush the
5906 relay log info. If there is a crash, we will have to re-skip
5907 the events again, but that is a minor issue.
5908
5909 If we do not skip stepping the group log position (and the
5910 server id was changed when restarting the server), it might well
5911 be that we start executing at a position that is invalid, e.g.,
5912 at a Rows_log_event or a Query_log_event preceeded by a
5913 Intvar_log_event instead of starting at a Table_map_log_event or
5914 the Intvar_log_event respectively.
5915 */
5916 rli->inc_event_relay_log_pos();
5917 return 0;
5918 }
5919 else
5920 {
5921 return Log_event::do_update_pos(rli);
5922 }
5923 }
5924
5925 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5926 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
5927 {
5928 return Log_event::EVENT_SKIP_NOT;
5929 }
5930
5931 #endif
5932
5933
5934 /**
5935 'server_version_split' is used for lookups to find if the server which
5936 created this event has some known bug.
5937 */
calc_server_version_split()5938 void Format_description_log_event::calc_server_version_split()
5939 {
5940 do_server_version_split(server_version, server_version_split);
5941
5942 DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
5943 " '%s' %d %d %d", server_version,
5944 server_version_split[0],
5945 server_version_split[1], server_version_split[2]));
5946 }
5947
5948 /**
5949 @return integer representing the version of server that originated
5950 the current FD instance.
5951 */
get_version_product() const5952 ulong Format_description_log_event::get_version_product() const
5953 {
5954 return version_product(server_version_split);
5955 }
5956
5957 /**
5958 @return TRUE is the event's version is earlier than one that introduced
5959 the replication event checksum. FALSE otherwise.
5960 */
is_version_before_checksum() const5961 bool Format_description_log_event::is_version_before_checksum() const
5962 {
5963 return get_version_product() < checksum_version_product;
5964 }
5965
5966 /**
5967 @param buf buffer holding serialized FD event
5968 @param len netto (possible checksum is stripped off) length of the event buf
5969
5970 @return the version-safe checksum alg descriptor where zero
5971 designates no checksum, 255 - the orginator is
5972 checksum-unaware (effectively no checksum) and the actuall
5973 [1-254] range alg descriptor.
5974 */
get_checksum_alg(const char * buf,ulong len)5975 uint8 get_checksum_alg(const char* buf, ulong len)
5976 {
5977 uint8 ret;
5978 char version[ST_SERVER_VER_LEN];
5979 uchar version_split[3];
5980
5981 DBUG_ENTER("get_checksum_alg");
5982 DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
5983
5984 memcpy(version, buf +
5985 buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
5986 + ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
5987 version[ST_SERVER_VER_LEN - 1]= 0;
5988
5989 do_server_version_split(version, version_split);
5990 ret= (version_product(version_split) < checksum_version_product) ?
5991 (uint8) BINLOG_CHECKSUM_ALG_UNDEF :
5992 * (uint8*) (buf + len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN);
5993 DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
5994 ret == BINLOG_CHECKSUM_ALG_UNDEF ||
5995 ret == BINLOG_CHECKSUM_ALG_CRC32);
5996 DBUG_RETURN(ret);
5997 }
5998
5999
6000 /**************************************************************************
6001 Load_log_event methods
6002 General note about Load_log_event: the binlogging of LOAD DATA INFILE is
6003 going to be changed in 5.0 (or maybe in 5.1; not decided yet).
6004 However, the 5.0 slave could still have to read such events (from a 4.x
6005 master), convert them (which just means maybe expand the header, when 5.0
6006 servers have a UID in events) (remember that whatever is after the header
6007 will be like in 4.x, as this event's format is not modified in 5.0 as we
6008 will use new types of events to log the new LOAD DATA INFILE features).
6009 To be able to read/convert, we just need to not assume that the common
6010 header is of length LOG_EVENT_HEADER_LEN (we must use the description
6011 event).
6012 Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
6013 between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
6014 positions displayed in SHOW SLAVE STATUS then are fine too).
6015 **************************************************************************/
6016
6017 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_query_buffer_length()6018 uint Load_log_event::get_query_buffer_length()
6019 {
6020 return
6021 //the DB name may double if we escape the quote character
6022 5 + 2*db_len + 3 +
6023 18 + fname_len*4 + 2 + // "LOAD DATA INFILE 'file''"
6024 11 + // "CONCURRENT "
6025 7 + // LOCAL
6026 9 + // " REPLACE or IGNORE "
6027 13 + table_name_len*2 + // "INTO TABLE `table`"
6028 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
6029 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
6030 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
6031 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
6032 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
6033 15 + 22 + // " IGNORE xxx LINES"
6034 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
6035 }
6036
6037
print_query(bool need_db,const char * cs,char * buf,char ** end,char ** fn_start,char ** fn_end)6038 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
6039 char **end, char **fn_start, char **fn_end)
6040 {
6041 char quoted_id[1 + NAME_LEN * 2 + 2];//quoted length
6042 int quoted_id_len= 0;
6043 char *pos= buf;
6044
6045 if (need_db && db && db_len)
6046 {
6047 pos= strmov(pos, "use ");
6048 #ifdef MYSQL_SERVER
6049 quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
6050 db, 0);
6051 #else
6052 quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
6053 #endif
6054 quoted_id[quoted_id_len]= '\0';
6055 pos= strmov(pos, quoted_id);
6056 pos= strmov(pos, "; ");
6057 }
6058
6059 pos= strmov(pos, "LOAD DATA ");
6060
6061 if (is_concurrent)
6062 pos= strmov(pos, "CONCURRENT ");
6063
6064 if (fn_start)
6065 *fn_start= pos;
6066
6067 if (check_fname_outside_temp_buf())
6068 pos= strmov(pos, "LOCAL ");
6069 pos= strmov(pos, "INFILE ");
6070 pos= pretty_print_str(pos, fname, fname_len);
6071 pos= strmov(pos, " ");
6072
6073 if (sql_ex.opt_flags & REPLACE_FLAG)
6074 pos= strmov(pos, "REPLACE ");
6075 else if (sql_ex.opt_flags & IGNORE_FLAG)
6076 pos= strmov(pos, "IGNORE ");
6077
6078 pos= strmov(pos ,"INTO");
6079
6080 if (fn_end)
6081 *fn_end= pos;
6082
6083 pos= strmov(pos ," TABLE ");
6084 memcpy(pos, table_name, table_name_len);
6085 pos+= table_name_len;
6086
6087 if (cs != NULL)
6088 {
6089 pos= strmov(pos ," CHARACTER SET ");
6090 pos= strmov(pos , cs);
6091 }
6092
6093 /* We have to create all optional fields as the default is not empty */
6094 pos= strmov(pos, " FIELDS TERMINATED BY ");
6095 pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
6096 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6097 pos= strmov(pos, " OPTIONALLY ");
6098 pos= strmov(pos, " ENCLOSED BY ");
6099 pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
6100
6101 pos= strmov(pos, " ESCAPED BY ");
6102 pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
6103
6104 pos= strmov(pos, " LINES TERMINATED BY ");
6105 pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
6106 if (sql_ex.line_start_len)
6107 {
6108 pos= strmov(pos, " STARTING BY ");
6109 pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
6110 }
6111
6112 if ((long) skip_lines > 0)
6113 {
6114 pos= strmov(pos, " IGNORE ");
6115 pos= longlong10_to_str((longlong) skip_lines, pos, 10);
6116 pos= strmov(pos," LINES ");
6117 }
6118
6119 if (num_fields)
6120 {
6121 uint i;
6122 const char *field= fields;
6123 pos= strmov(pos, " (");
6124 for (i = 0; i < num_fields; i++)
6125 {
6126 if (i)
6127 {
6128 *pos++= ' ';
6129 *pos++= ',';
6130 }
6131 quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
6132 0);
6133 memcpy(pos, quoted_id, quoted_id_len-1);
6134 }
6135 *pos++= ')';
6136 }
6137
6138 *end= pos;
6139 }
6140
6141
pack_info(Protocol * protocol)6142 int Load_log_event::pack_info(Protocol *protocol)
6143 {
6144 char *buf, *end;
6145
6146 if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
6147 return 1;
6148 print_query(TRUE, NULL, buf, &end, 0, 0);
6149 protocol->store(buf, end-buf, &my_charset_bin);
6150 my_free(buf);
6151 return 0;
6152 }
6153 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6154
6155
6156 #ifndef MYSQL_CLIENT
6157
6158 /*
6159 Load_log_event::write_data_header()
6160 */
6161
write_data_header(IO_CACHE * file)6162 bool Load_log_event::write_data_header(IO_CACHE* file)
6163 {
6164 char buf[LOAD_HEADER_LEN];
6165 int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
6166 int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
6167 int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
6168 buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
6169 buf[L_DB_LEN_OFFSET] = (char)db_len;
6170 int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
6171 return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
6172 }
6173
6174
6175 /*
6176 Load_log_event::write_data_body()
6177 */
6178
write_data_body(IO_CACHE * file)6179 bool Load_log_event::write_data_body(IO_CACHE* file)
6180 {
6181 if (sql_ex.write_data(file))
6182 return 1;
6183 if (num_fields && fields && field_lens)
6184 {
6185 if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
6186 my_b_safe_write(file, (uchar*)fields, field_block_len))
6187 return 1;
6188 }
6189 return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
6190 my_b_safe_write(file, (uchar*)db, db_len + 1) ||
6191 my_b_safe_write(file, (uchar*)fname, fname_len));
6192 }
6193
6194
6195 /*
6196 Load_log_event::Load_log_event()
6197 */
6198
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)6199 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
6200 const char *db_arg, const char *table_name_arg,
6201 List<Item> &fields_arg,
6202 bool is_concurrent_arg,
6203 enum enum_duplicates handle_dup,
6204 bool ignore, bool using_trans)
6205 :Log_event(thd_arg,
6206 thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
6207 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
6208 Log_event::EVENT_STMT_CACHE,
6209 Log_event::EVENT_NORMAL_LOGGING),
6210 thread_id(thd_arg->thread_id),
6211 slave_proxy_id(thd_arg->variables.pseudo_thread_id),
6212 num_fields(0),fields(0),
6213 field_lens(0),field_block_len(0),
6214 table_name(table_name_arg ? table_name_arg : ""),
6215 db(db_arg), fname(ex->file_name), local_fname(FALSE),
6216 is_concurrent(is_concurrent_arg)
6217 {
6218
6219 /*
6220 exec_time calculation has changed to use the same method that is used
6221 to fill out "thd_arg->start_time"
6222 */
6223
6224 struct timeval end_time;
6225 ulonglong micro_end_time= my_micro_time();
6226 my_micro_time_to_timeval(micro_end_time, &end_time);
6227
6228 exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
6229
6230 /* db can never be a zero pointer in 4.0 */
6231 db_len = (uint32) strlen(db);
6232 table_name_len = (uint32) strlen(table_name);
6233 fname_len = (fname) ? (uint) strlen(fname) : 0;
6234 sql_ex.field_term = (char*) ex->field_term->ptr();
6235 sql_ex.field_term_len = (uint8) ex->field_term->length();
6236 sql_ex.enclosed = (char*) ex->enclosed->ptr();
6237 sql_ex.enclosed_len = (uint8) ex->enclosed->length();
6238 sql_ex.line_term = (char*) ex->line_term->ptr();
6239 sql_ex.line_term_len = (uint8) ex->line_term->length();
6240 sql_ex.line_start = (char*) ex->line_start->ptr();
6241 sql_ex.line_start_len = (uint8) ex->line_start->length();
6242 sql_ex.escaped = (char*) ex->escaped->ptr();
6243 sql_ex.escaped_len = (uint8) ex->escaped->length();
6244 sql_ex.opt_flags = 0;
6245 sql_ex.cached_new_format = -1;
6246
6247 if (ex->dumpfile)
6248 sql_ex.opt_flags|= DUMPFILE_FLAG;
6249 if (ex->opt_enclosed)
6250 sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
6251
6252 sql_ex.empty_flags= 0;
6253
6254 switch (handle_dup) {
6255 case DUP_REPLACE:
6256 sql_ex.opt_flags|= REPLACE_FLAG;
6257 break;
6258 case DUP_UPDATE: // Impossible here
6259 case DUP_ERROR:
6260 break;
6261 }
6262 if (ignore)
6263 sql_ex.opt_flags|= IGNORE_FLAG;
6264
6265 if (!ex->field_term->length())
6266 sql_ex.empty_flags |= FIELD_TERM_EMPTY;
6267 if (!ex->enclosed->length())
6268 sql_ex.empty_flags |= ENCLOSED_EMPTY;
6269 if (!ex->line_term->length())
6270 sql_ex.empty_flags |= LINE_TERM_EMPTY;
6271 if (!ex->line_start->length())
6272 sql_ex.empty_flags |= LINE_START_EMPTY;
6273 if (!ex->escaped->length())
6274 sql_ex.empty_flags |= ESCAPED_EMPTY;
6275
6276 skip_lines = ex->skip_lines;
6277
6278 List_iterator<Item> li(fields_arg);
6279 field_lens_buf.length(0);
6280 fields_buf.length(0);
6281 Item* item;
6282 while ((item = li++))
6283 {
6284 num_fields++;
6285 uchar len= (uchar) item->item_name.length();
6286 field_block_len += len + 1;
6287 fields_buf.append(item->item_name.ptr(), len + 1);
6288 field_lens_buf.append((char*)&len, 1);
6289 }
6290
6291 field_lens = (const uchar*)field_lens_buf.ptr();
6292 fields = fields_buf.ptr();
6293 }
6294 #endif /* !MYSQL_CLIENT */
6295
6296
6297 /**
6298 @note
6299 The caller must do buf[event_len] = 0 before he starts using the
6300 constructed event.
6301 */
Load_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6302 Load_log_event::Load_log_event(const char *buf, uint event_len,
6303 const Format_description_log_event *description_event)
6304 :Log_event(buf, description_event), num_fields(0), fields(0),
6305 field_lens(0),field_block_len(0),
6306 table_name(0), db(0), fname(0), local_fname(FALSE),
6307 /*
6308 Load_log_event which comes from the binary log does not contain
6309 information about the type of insert which was used on the master.
6310 Assume that it was an ordinary, non-concurrent LOAD DATA.
6311 */
6312 is_concurrent(FALSE)
6313 {
6314 DBUG_ENTER("Load_log_event");
6315 /*
6316 I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6317 4.0->5.0 and 5.0->5.0 and it works.
6318 */
6319 if (event_len)
6320 copy_log_event(buf, event_len,
6321 ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
6322 LOAD_HEADER_LEN +
6323 description_event->common_header_len :
6324 LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
6325 description_event);
6326 /* otherwise it's a derived class, will call copy_log_event() itself */
6327 DBUG_VOID_RETURN;
6328 }
6329
6330
6331 /*
6332 Load_log_event::copy_log_event()
6333 */
6334
copy_log_event(const char * buf,ulong event_len,int body_offset,const Format_description_log_event * description_event)6335 int Load_log_event::copy_log_event(const char *buf, ulong event_len,
6336 int body_offset,
6337 const Format_description_log_event *description_event)
6338 {
6339 DBUG_ENTER("Load_log_event::copy_log_event");
6340 uint data_len;
6341 char* buf_end = (char*)buf + event_len;
6342 /* this is the beginning of the post-header */
6343 const char* data_head = buf + description_event->common_header_len;
6344 slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
6345 exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
6346 skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
6347 table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
6348 db_len = (uint)data_head[L_DB_LEN_OFFSET];
6349 num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
6350
6351 if ((int) event_len < body_offset)
6352 DBUG_RETURN(1);
6353 /*
6354 Sql_ex.init() on success returns the pointer to the first byte after
6355 the sql_ex structure, which is the start of field lengths array.
6356 */
6357 if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
6358 buf_end,
6359 buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
6360 DBUG_RETURN(1);
6361
6362 data_len = event_len - body_offset;
6363 if (num_fields > data_len) // simple sanity check against corruption
6364 DBUG_RETURN(1);
6365 for (uint i = 0; i < num_fields; i++)
6366 field_block_len += (uint)field_lens[i] + 1;
6367
6368 fields = (char*)field_lens + num_fields;
6369 table_name = fields + field_block_len;
6370 if (strlen(table_name) > NAME_LEN)
6371 goto err;
6372
6373 db = table_name + table_name_len + 1;
6374 DBUG_EXECUTE_IF ("simulate_invalid_address",
6375 db_len = data_len;);
6376 fname = db + db_len + 1;
6377 if ((db_len > data_len) || (fname > buf_end))
6378 goto err;
6379 fname_len = (uint) strlen(fname);
6380 if ((fname_len > data_len) || (fname + fname_len > buf_end))
6381 goto err;
6382 // null termination is accomplished by the caller doing buf[event_len]=0
6383
6384 DBUG_RETURN(0);
6385
6386 err:
6387 // Invalid event.
6388 table_name = 0;
6389 DBUG_RETURN(1);
6390 }
6391
6392
6393 /*
6394 Load_log_event::print()
6395 */
6396
6397 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6398 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6399 {
6400 print(file, print_event_info, 0);
6401 }
6402
6403
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info,bool commented)6404 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
6405 bool commented)
6406 {
6407 IO_CACHE *const head= &print_event_info->head_cache;
6408 size_t id_len= 0;
6409 char temp_buf[1 + 2*FN_REFLEN + 2];
6410
6411 DBUG_ENTER("Load_log_event::print");
6412 if (!print_event_info->short_form)
6413 {
6414 print_header(head, print_event_info, FALSE);
6415 my_b_printf(head, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
6416 thread_id, exec_time);
6417 }
6418
6419 bool different_db= 1;
6420 if (db)
6421 {
6422 /*
6423 If the database is different from the one of the previous statement, we
6424 need to print the "use" command, and we update the last_db.
6425 But if commented, the "use" is going to be commented so we should not
6426 update the last_db.
6427 */
6428 if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
6429 !commented)
6430 memcpy(print_event_info->db, db, db_len + 1);
6431 }
6432
6433 if (db && db[0] && different_db)
6434 {
6435 #ifdef MYSQL_SERVER
6436 id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
6437 #else
6438 id_len= my_strmov_quoted_identifier(temp_buf, db);
6439 #endif
6440 temp_buf[id_len]= '\0';
6441 my_b_printf(head, "%suse %s%s\n",
6442 commented ? "# " : "", temp_buf, print_event_info->delimiter);
6443 }
6444 if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
6445 my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
6446 commented ? "# " : "", (ulong)thread_id,
6447 print_event_info->delimiter);
6448 my_b_printf(head, "%sLOAD DATA ",
6449 commented ? "# " : "");
6450 if (check_fname_outside_temp_buf())
6451 my_b_printf(head, "LOCAL ");
6452 my_b_printf(head, "INFILE '%-*s' ", fname_len, fname);
6453
6454 if (sql_ex.opt_flags & REPLACE_FLAG)
6455 my_b_printf(head,"REPLACE ");
6456 else if (sql_ex.opt_flags & IGNORE_FLAG)
6457 my_b_printf(head,"IGNORE ");
6458
6459 #ifdef MYSQL_SERVER
6460 id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
6461 #else
6462 id_len= my_strmov_quoted_identifier(temp_buf, table_name);
6463 #endif
6464 temp_buf[id_len]= '\0';
6465 my_b_printf(head, "INTO TABLE %s", temp_buf);
6466
6467 my_b_printf(head, " FIELDS TERMINATED BY ");
6468 pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len);
6469
6470 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6471 my_b_printf(head," OPTIONALLY ");
6472 my_b_printf(head, " ENCLOSED BY ");
6473 pretty_print_str(head, sql_ex.enclosed, sql_ex.enclosed_len);
6474
6475 my_b_printf(head, " ESCAPED BY ");
6476 pretty_print_str(head, sql_ex.escaped, sql_ex.escaped_len);
6477
6478 my_b_printf(head," LINES TERMINATED BY ");
6479 pretty_print_str(head, sql_ex.line_term, sql_ex.line_term_len);
6480
6481
6482 if (sql_ex.line_start)
6483 {
6484 my_b_printf(head," STARTING BY ");
6485 pretty_print_str(head, sql_ex.line_start, sql_ex.line_start_len);
6486 }
6487 if ((long) skip_lines > 0)
6488 my_b_printf(head, " IGNORE %ld LINES", (long) skip_lines);
6489
6490 if (num_fields)
6491 {
6492 uint i;
6493 const char* field = fields;
6494 my_b_printf(head, " (");
6495 for (i = 0; i < num_fields; i++)
6496 {
6497 if (i)
6498 my_b_printf(head, ",");
6499 id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
6500 temp_buf[id_len]= '\0';
6501 my_b_printf(head, "%s", temp_buf);
6502
6503 field += field_lens[i] + 1;
6504 }
6505 my_b_printf(head, ")");
6506 }
6507
6508 my_b_printf(head, "%s\n", print_event_info->delimiter);
6509 DBUG_VOID_RETURN;
6510 }
6511 #endif /* MYSQL_CLIENT */
6512
6513 #ifndef MYSQL_CLIENT
6514
6515 /**
6516 Load_log_event::set_fields()
6517
6518 @note
6519 This function can not use the member variable
6520 for the database, since LOAD DATA INFILE on the slave
6521 can be for a different database than the current one.
6522 This is the reason for the affected_db argument to this method.
6523 */
6524
set_fields(const char * affected_db,List<Item> & field_list,Name_resolution_context * context)6525 void Load_log_event::set_fields(const char* affected_db,
6526 List<Item> &field_list,
6527 Name_resolution_context *context)
6528 {
6529 uint i;
6530 const char* field = fields;
6531 for (i= 0; i < num_fields; i++)
6532 {
6533 field_list.push_back(new Item_field(context,
6534 affected_db, table_name, field));
6535 field+= field_lens[i] + 1;
6536 }
6537 }
6538 #endif /* !MYSQL_CLIENT */
6539
6540
6541 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6542 /**
6543 Does the data loading job when executing a LOAD DATA on the slave.
6544
6545 @param net
6546 @param rli
6547 @param use_rli_only_for_errors If set to 1, rli is provided to
6548 Load_log_event::exec_event only for this
6549 function to have rli->get_rpl_log_name and
6550 rli->last_slave_error, both being used by
6551 error reports. rli's position advancing
6552 is skipped (done by the caller which is
6553 Execute_load_log_event::exec_event).
6554 If set to 0, rli is provided for full use,
6555 i.e. for error reports and position
6556 advancing.
6557
6558 @todo
6559 fix this; this can be done by testing rules in
6560 Create_file_log_event::exec_event() and then discarding Append_block and
6561 al.
6562 @todo
6563 this is a bug - this needs to be moved to the I/O thread
6564
6565 @retval
6566 0 Success
6567 @retval
6568 1 Failure
6569 */
6570
do_apply_event(NET * net,Relay_log_info const * rli,bool use_rli_only_for_errors)6571 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
6572 bool use_rli_only_for_errors)
6573 {
6574 DBUG_ASSERT(thd->query() == 0);
6575 thd->reset_query_inner(); // Should not be needed
6576 set_thd_db(thd, db, db_len);
6577 thd->is_slave_error= 0;
6578 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
6579
6580 /* see Query_log_event::do_apply_event() and BUG#13360 */
6581 DBUG_ASSERT(!rli->m_table_map.count());
6582 /*
6583 Usually lex_start() is called by mysql_parse(), but we need it here
6584 as the present method does not call mysql_parse().
6585 */
6586 lex_start(thd);
6587 thd->lex->local_file= local_fname;
6588 mysql_reset_thd_for_next_command(thd);
6589
6590 if (!use_rli_only_for_errors)
6591 {
6592 /*
6593 Saved for InnoDB, see comment in
6594 Query_log_event::do_apply_event()
6595 */
6596 const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
6597 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
6598 }
6599
6600 /*
6601 We test replicate_*_db rules. Note that we have already prepared
6602 the file to load, even if we are going to ignore and delete it
6603 now. So it is possible that we did a lot of disk writes for
6604 nothing. In other words, a big LOAD DATA INFILE on the master will
6605 still consume a lot of space on the slave (space in the relay log
6606 + space of temp files: twice the space of the file to load...)
6607 even if it will finally be ignored. TODO: fix this; this can be
6608 done by testing rules in Create_file_log_event::do_apply_event()
6609 and then discarding Append_block and al. Another way is do the
6610 filtering in the I/O thread (more efficient: no disk writes at
6611 all).
6612
6613
6614 Note: We do not need to execute reset_one_shot_variables() if this
6615 db_ok() test fails.
6616 Reason: The db stored in binlog events is the same for SET and for
6617 its companion query. If the SET is ignored because of
6618 db_ok(), the companion query will also be ignored, and if
6619 the companion query is ignored in the db_ok() test of
6620 ::do_apply_event(), then the companion SET also have so
6621 we don't need to reset_one_shot_variables().
6622 */
6623 if (rpl_filter->db_ok(thd->db))
6624 {
6625 thd->set_time(&when);
6626 thd->set_query_id(next_query_id());
6627 thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
6628
6629 TABLE_LIST tables;
6630 char table_buf[NAME_LEN + 1];
6631 strmov(table_buf, table_name);
6632 if (lower_case_table_names == 1)
6633 my_casedn_str(system_charset_info, table_buf);
6634 tables.init_one_table(thd->strmake(thd->db, thd->db_length),
6635 thd->db_length,
6636 table_buf, strlen(table_buf),
6637 table_buf, TL_WRITE);
6638 tables.updating= 1;
6639
6640 // the table will be opened in mysql_load
6641 if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
6642 {
6643 // TODO: this is a bug - this needs to be moved to the I/O thread
6644 if (net)
6645 skip_load_data_infile(net);
6646 }
6647 else
6648 {
6649 char llbuff[22];
6650 char *end;
6651 enum enum_duplicates handle_dup;
6652 bool ignore= 0;
6653 char *load_data_query;
6654
6655 /*
6656 Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
6657 and written to slave's binlog if binlogging is on.
6658 */
6659 if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
6660 {
6661 /*
6662 This will set thd->fatal_error in case of OOM. So we surely will notice
6663 that something is wrong.
6664 */
6665 goto error;
6666 }
6667
6668 print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
6669 *end= 0;
6670 thd->set_query(load_data_query, (uint) (end - load_data_query));
6671
6672 if (sql_ex.opt_flags & REPLACE_FLAG)
6673 handle_dup= DUP_REPLACE;
6674 else if (sql_ex.opt_flags & IGNORE_FLAG)
6675 {
6676 ignore= 1;
6677 handle_dup= DUP_ERROR;
6678 }
6679 else
6680 {
6681 /*
6682 When replication is running fine, if it was DUP_ERROR on the
6683 master then we could choose IGNORE here, because if DUP_ERROR
6684 suceeded on master, and data is identical on the master and slave,
6685 then there should be no uniqueness errors on slave, so IGNORE is
6686 the same as DUP_ERROR. But in the unlikely case of uniqueness errors
6687 (because the data on the master and slave happen to be different
6688 (user error or bug), we want LOAD DATA to print an error message on
6689 the slave to discover the problem.
6690
6691 If reading from net (a 3.23 master), mysql_load() will change this
6692 to IGNORE.
6693 */
6694 handle_dup= DUP_ERROR;
6695 }
6696 /*
6697 We need to set thd->lex->sql_command and thd->lex->duplicates
6698 since InnoDB tests these variables to decide if this is a LOAD
6699 DATA ... REPLACE INTO ... statement even though mysql_parse()
6700 is not called. This is not needed in 5.0 since there the LOAD
6701 DATA ... statement is replicated using mysql_parse(), which
6702 sets the thd->lex fields correctly.
6703 */
6704 thd->lex->sql_command= SQLCOM_LOAD;
6705 thd->lex->duplicates= handle_dup;
6706
6707 sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
6708 String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
6709 String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
6710 String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
6711 String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
6712 String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
6713 const String empty_str("", 0, log_cs);
6714 ex.field_term= &field_term;
6715 ex.enclosed= &enclosed;
6716 ex.line_term= &line_term;
6717 ex.line_start= &line_start;
6718 ex.escaped= &escaped;
6719
6720 ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
6721 if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
6722 ex.field_term= &empty_str;
6723
6724 ex.skip_lines = skip_lines;
6725 List<Item> field_list;
6726 thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
6727 set_fields(tables.db, field_list, &thd->lex->select_lex.context);
6728 thd->variables.pseudo_thread_id= thread_id;
6729 if (net)
6730 {
6731 // mysql_load will use thd->net to read the file
6732 thd->net.vio = net->vio;
6733 // Make sure the client does not get confused about the packet sequence
6734 thd->net.pkt_nr = net->pkt_nr;
6735 }
6736 /*
6737 It is safe to use tmp_list twice because we are not going to
6738 update it inside mysql_load().
6739 */
6740 List<Item> tmp_list;
6741 if (open_temporary_tables(thd, &tables) ||
6742 mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
6743 handle_dup, ignore, net != 0))
6744 thd->is_slave_error= 1;
6745 if (thd->cuted_fields)
6746 {
6747 /* log_pos is the position of the LOAD event in the master log */
6748 sql_print_warning("Slave: load data infile on table '%s' at "
6749 "log position %s in log '%s' produced %ld "
6750 "warning(s). Default database: '%s'",
6751 (char*) table_name,
6752 llstr(log_pos,llbuff),
6753 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
6754 (ulong) thd->cuted_fields,
6755 print_slave_db_safe(thd->db));
6756 }
6757 if (net)
6758 net->pkt_nr= thd->net.pkt_nr;
6759 }
6760 }
6761 else
6762 {
6763 /*
6764 We will just ask the master to send us /dev/null if we do not
6765 want to load the data.
6766 TODO: this a bug - needs to be done in I/O thread
6767 */
6768 if (net)
6769 skip_load_data_infile(net);
6770 }
6771
6772 error:
6773 thd->net.vio = 0;
6774 const char *remember_db= thd->db;
6775 thd->catalog= 0;
6776 thd->set_db(NULL, 0); /* will free the current database */
6777 thd->reset_query();
6778 thd->get_stmt_da()->set_overwrite_status(true);
6779 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
6780 thd->get_stmt_da()->set_overwrite_status(false);
6781 close_thread_tables(thd);
6782 /*
6783 - If transaction rollback was requested due to deadlock
6784 perform it and release metadata locks.
6785 - If inside a multi-statement transaction,
6786 defer the release of metadata locks until the current
6787 transaction is either committed or rolled back. This prevents
6788 other statements from modifying the table for the entire
6789 duration of this transaction. This provides commit ordering
6790 and guarantees serializability across multiple transactions.
6791 - If in autocommit mode, or outside a transactional context,
6792 automatically release metadata locks of the current statement.
6793 */
6794 if (thd->transaction_rollback_request)
6795 {
6796 trans_rollback_implicit(thd);
6797 thd->mdl_context.release_transactional_locks();
6798 }
6799 else if (! thd->in_multi_stmt_transaction_mode())
6800 thd->mdl_context.release_transactional_locks();
6801 else
6802 thd->mdl_context.release_statement_locks();
6803
6804 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
6805 thd->is_slave_error= 0; thd->is_fatal_error= 1;);
6806
6807 if (thd->is_slave_error)
6808 {
6809 /* this err/sql_errno code is copy-paste from net_send_error() */
6810 const char *err;
6811 int sql_errno;
6812 if (thd->is_error())
6813 {
6814 err= thd->get_stmt_da()->message();
6815 sql_errno= thd->get_stmt_da()->sql_errno();
6816 }
6817 else
6818 {
6819 sql_errno=ER_UNKNOWN_ERROR;
6820 err=ER(sql_errno);
6821 }
6822 rli->report(ERROR_LEVEL, sql_errno,"\
6823 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
6824 err, (char*)table_name, print_slave_db_safe(remember_db));
6825 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6826 return 1;
6827 }
6828 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6829
6830 if (thd->is_fatal_error)
6831 {
6832 char buf[256];
6833 my_snprintf(buf, sizeof(buf),
6834 "Running LOAD DATA INFILE on table '%-.64s'."
6835 " Default database: '%-.64s'",
6836 (char*)table_name,
6837 print_slave_db_safe(remember_db));
6838
6839 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6840 ER(ER_SLAVE_FATAL_ERROR), buf);
6841 return 1;
6842 }
6843
6844 return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
6845 }
6846 #endif
6847
6848
6849 /**************************************************************************
6850 Rotate_log_event methods
6851 **************************************************************************/
6852
6853 /*
6854 Rotate_log_event::pack_info()
6855 */
6856
6857 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6858 int Rotate_log_event::pack_info(Protocol *protocol)
6859 {
6860 char buf1[256], buf[22];
6861 String tmp(buf1, sizeof(buf1), log_cs);
6862 tmp.length(0);
6863 tmp.append(new_log_ident, ident_len);
6864 tmp.append(STRING_WITH_LEN(";pos="));
6865 tmp.append(llstr(pos,buf));
6866 protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
6867 return 0;
6868 }
6869 #endif
6870
6871
6872 /*
6873 Rotate_log_event::print()
6874 */
6875
6876 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6877 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6878 {
6879 char buf[22];
6880 IO_CACHE *const head= &print_event_info->head_cache;
6881
6882 if (print_event_info->short_form)
6883 return;
6884 print_header(head, print_event_info, FALSE);
6885 my_b_printf(head, "\tRotate to ");
6886 if (new_log_ident)
6887 my_b_write(head, (uchar*) new_log_ident, (uint)ident_len);
6888 my_b_printf(head, " pos: %s\n", llstr(pos, buf));
6889 }
6890 #endif /* MYSQL_CLIENT */
6891
6892
6893
6894 /*
6895 Rotate_log_event::Rotate_log_event() (2 constructors)
6896 */
6897
6898
6899 #ifndef MYSQL_CLIENT
Rotate_log_event(const char * new_log_ident_arg,uint ident_len_arg,ulonglong pos_arg,uint flags_arg)6900 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
6901 uint ident_len_arg, ulonglong pos_arg,
6902 uint flags_arg)
6903 :Log_event(Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING),
6904 new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ?
6905 ident_len_arg : (uint) strlen(new_log_ident_arg)), flags(flags_arg)
6906 {
6907 #ifndef DBUG_OFF
6908 char buff[22];
6909 DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
6910 DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
6911 llstr(pos_arg, buff), (ulong) flags));
6912 #endif
6913 if (flags & DUP_NAME)
6914 new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
6915 if (flags & RELAY_LOG)
6916 set_relay_log_event();
6917 DBUG_VOID_RETURN;
6918 }
6919 #endif
6920
6921
Rotate_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6922 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
6923 const Format_description_log_event* description_event)
6924 :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
6925 {
6926 DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
6927 // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
6928 uint8 header_size= description_event->common_header_len;
6929 uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
6930 uint ident_offset;
6931 if (event_len < header_size)
6932 DBUG_VOID_RETURN;
6933 buf += header_size;
6934 pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
6935 ident_len = (uint)(event_len -
6936 (header_size+post_header_len));
6937 ident_offset = post_header_len;
6938 set_if_smaller(ident_len,FN_REFLEN-1);
6939 new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
6940 DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
6941 DBUG_VOID_RETURN;
6942 }
6943
6944
6945 /*
6946 Rotate_log_event::write()
6947 */
6948
6949 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6950 bool Rotate_log_event::write(IO_CACHE* file)
6951 {
6952 char buf[ROTATE_HEADER_LEN];
6953 int8store(buf + R_POS_OFFSET, pos);
6954 return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
6955 wrapper_my_b_safe_write(file, (uchar*) buf, ROTATE_HEADER_LEN) ||
6956 wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
6957 (uint) ident_len) ||
6958 write_footer(file));
6959 }
6960 #endif
6961
6962
6963 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6964
6965 /*
6966 Got a rotate log event from the master.
6967
6968 This is mainly used so that we can later figure out the logname and
6969 position for the master.
6970
6971 We can't rotate the slave's BINlog as this will cause infinitive rotations
6972 in a A -> B -> A setup.
6973 The NOTES below is a wrong comment which will disappear when 4.1 is merged.
6974
6975 This must only be called from the Slave SQL thread, since it calls
6976 flush_relay_log_info().
6977
6978 @retval
6979 0 ok
6980 */
do_update_pos(Relay_log_info * rli)6981 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
6982 {
6983 int error= 0;
6984 DBUG_ENTER("Rotate_log_event::do_update_pos");
6985 #ifndef DBUG_OFF
6986 char buf[32];
6987 #endif
6988
6989 DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
6990 (ulong) this->server_id, (ulong) ::server_id));
6991 DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
6992 DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
6993
6994 /*
6995 If we are in a transaction or in a group: the only normal case is
6996 when the I/O thread was copying a big transaction, then it was
6997 stopped and restarted: we have this in the relay log:
6998
6999 BEGIN
7000 ...
7001 ROTATE (a fake one)
7002 ...
7003 COMMIT or ROLLBACK
7004
7005 In that case, we don't want to touch the coordinates which
7006 correspond to the beginning of the transaction. Starting from
7007 5.0.0, there also are some rotates from the slave itself, in the
7008 relay log, which shall not change the group positions.
7009 */
7010
7011 /*
7012 The way we check if SQL thread is currently in a group is different
7013 for STS and MTS.
7014 */
7015 bool in_group = rli->is_parallel_exec() ?
7016 (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) :
7017 rli->is_in_group();
7018
7019 if ((server_id != ::server_id || rli->replicate_same_server_id) &&
7020 !is_relay_log_event() &&
7021 !in_group)
7022 {
7023 if (rli->is_parallel_exec())
7024 {
7025 /*
7026 Rotate events are special events that are handled as a
7027 synchronization point. For that reason, the checkpoint
7028 routine is being called here.
7029 */
7030 if ((error= mts_checkpoint_routine(rli, 0, false,
7031 true/*need_data_lock=true*/)))
7032 goto err;
7033 }
7034
7035 mysql_mutex_lock(&rli->data_lock);
7036 DBUG_PRINT("info", ("old group_master_log_name: '%s' "
7037 "old group_master_log_pos: %lu",
7038 rli->get_group_master_log_name(),
7039 (ulong) rli->get_group_master_log_pos()));
7040
7041 memcpy((void *)rli->get_group_master_log_name(),
7042 new_log_ident, ident_len + 1);
7043 rli->notify_group_master_log_name_update();
7044 if ((error= rli->inc_group_relay_log_pos(pos,
7045 false/*need_data_lock=false*/)))
7046 {
7047 mysql_mutex_unlock(&rli->data_lock);
7048 goto err;
7049 }
7050
7051 DBUG_PRINT("info", ("new group_master_log_name: '%s' "
7052 "new group_master_log_pos: %lu",
7053 rli->get_group_master_log_name(),
7054 (ulong) rli->get_group_master_log_pos()));
7055 mysql_mutex_unlock(&rli->data_lock);
7056 if (rli->is_parallel_exec())
7057 {
7058 bool real_event= server_id && !is_artificial_event();
7059 rli->reset_notified_checkpoint(0,
7060 real_event ? when.tv_sec + (time_t) exec_time : 0,
7061 true/*need_data_lock=true*/);
7062 }
7063
7064 /*
7065 Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
7066 a master's downgrade from 5.0 to 4.0.
7067 However, no need to reset rli_description_event: indeed, if the next
7068 master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
7069 master is 4.0 then the events are in the slave's format (conversion).
7070 */
7071 set_slave_thread_options(thd);
7072 set_slave_thread_default_charset(thd, rli);
7073 thd->variables.sql_mode= global_system_variables.sql_mode;
7074 thd->variables.auto_increment_increment=
7075 thd->variables.auto_increment_offset= 1;
7076 }
7077 else
7078 rli->inc_event_relay_log_pos();
7079
7080 err:
7081 DBUG_RETURN(error);
7082 }
7083
7084
7085 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7086 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
7087 {
7088 enum_skip_reason reason= Log_event::do_shall_skip(rli);
7089
7090 switch (reason) {
7091 case Log_event::EVENT_SKIP_NOT:
7092 case Log_event::EVENT_SKIP_COUNT:
7093 return Log_event::EVENT_SKIP_NOT;
7094
7095 case Log_event::EVENT_SKIP_IGNORE:
7096 return Log_event::EVENT_SKIP_IGNORE;
7097 }
7098 DBUG_ASSERT(0);
7099 return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
7100 }
7101
7102 #endif
7103
7104
7105 /**************************************************************************
7106 Intvar_log_event methods
7107 **************************************************************************/
7108
7109 /*
7110 Intvar_log_event::pack_info()
7111 */
7112
7113 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7114 int Intvar_log_event::pack_info(Protocol *protocol)
7115 {
7116 char buf[256], *pos;
7117 pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
7118 *pos++= '=';
7119 pos= longlong10_to_str(val, pos, -10);
7120 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7121 return 0;
7122 }
7123 #endif
7124
7125
7126 /*
7127 Intvar_log_event::Intvar_log_event()
7128 */
7129
Intvar_log_event(const char * buf,const Format_description_log_event * description_event)7130 Intvar_log_event::Intvar_log_event(const char* buf,
7131 const Format_description_log_event* description_event)
7132 :Log_event(buf, description_event)
7133 {
7134 /* The Post-Header is empty. The Varible Data part begins immediately. */
7135 buf+= description_event->common_header_len +
7136 description_event->post_header_len[INTVAR_EVENT-1];
7137 type= buf[I_TYPE_OFFSET];
7138 val= uint8korr(buf+I_VAL_OFFSET);
7139 }
7140
7141
7142 /*
7143 Intvar_log_event::get_var_type_name()
7144 */
7145
get_var_type_name()7146 const char* Intvar_log_event::get_var_type_name()
7147 {
7148 switch(type) {
7149 case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
7150 case INSERT_ID_EVENT: return "INSERT_ID";
7151 default: /* impossible */ return "UNKNOWN";
7152 }
7153 }
7154
7155
7156 /*
7157 Intvar_log_event::write()
7158 */
7159
7160 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7161 bool Intvar_log_event::write(IO_CACHE* file)
7162 {
7163 uchar buf[9];
7164 buf[I_TYPE_OFFSET]= (uchar) type;
7165 int8store(buf + I_VAL_OFFSET, val);
7166 return (write_header(file, sizeof(buf)) ||
7167 wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7168 write_footer(file));
7169 }
7170 #endif
7171
7172
7173 /*
7174 Intvar_log_event::print()
7175 */
7176
7177 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7178 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7179 {
7180 char llbuff[22];
7181 const char *msg;
7182 LINT_INIT(msg);
7183 IO_CACHE *const head= &print_event_info->head_cache;
7184
7185 if (!print_event_info->short_form)
7186 {
7187 print_header(head, print_event_info, FALSE);
7188 my_b_printf(head, "\tIntvar\n");
7189 }
7190
7191 my_b_printf(head, "SET ");
7192 switch (type) {
7193 case LAST_INSERT_ID_EVENT:
7194 msg="LAST_INSERT_ID";
7195 break;
7196 case INSERT_ID_EVENT:
7197 msg="INSERT_ID";
7198 break;
7199 case INVALID_INT_EVENT:
7200 default: // cannot happen
7201 msg="INVALID_INT";
7202 break;
7203 }
7204 my_b_printf(head, "%s=%s%s\n",
7205 msg, llstr(val,llbuff), print_event_info->delimiter);
7206 }
7207 #endif
7208
7209
7210 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
7211
7212 /*
7213 Intvar_log_event::do_apply_event()
7214 */
7215
do_apply_event(Relay_log_info const * rli)7216 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
7217 {
7218 /*
7219 We are now in a statement until the associated query log event has
7220 been processed.
7221 */
7222 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7223
7224 if (rli->deferred_events_collecting)
7225 return rli->deferred_events->add(this);
7226
7227 switch (type) {
7228 case LAST_INSERT_ID_EVENT:
7229 thd->first_successful_insert_id_in_prev_stmt= val;
7230 break;
7231 case INSERT_ID_EVENT:
7232 thd->force_one_auto_inc_interval(val);
7233 break;
7234 }
7235 return 0;
7236 }
7237
do_update_pos(Relay_log_info * rli)7238 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
7239 {
7240 rli->inc_event_relay_log_pos();
7241 return 0;
7242 }
7243
7244
7245 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7246 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
7247 {
7248 /*
7249 It is a common error to set the slave skip counter to 1 instead of
7250 2 when recovering from an insert which used a auto increment,
7251 rand, or user var. Therefore, if the slave skip counter is 1, we
7252 just say that this event should be skipped by ignoring it, meaning
7253 that we do not change the value of the slave skip counter since it
7254 will be decreased by the following insert event.
7255 */
7256 return continue_group(rli);
7257 }
7258
7259 #endif
7260
7261
7262 /**************************************************************************
7263 Rand_log_event methods
7264 **************************************************************************/
7265
7266 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7267 int Rand_log_event::pack_info(Protocol *protocol)
7268 {
7269 char buf1[256], *pos;
7270 pos= strmov(buf1,"rand_seed1=");
7271 pos= int10_to_str((long) seed1, pos, 10);
7272 pos= strmov(pos, ",rand_seed2=");
7273 pos= int10_to_str((long) seed2, pos, 10);
7274 protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
7275 return 0;
7276 }
7277 #endif
7278
7279
Rand_log_event(const char * buf,const Format_description_log_event * description_event)7280 Rand_log_event::Rand_log_event(const char* buf,
7281 const Format_description_log_event* description_event)
7282 :Log_event(buf, description_event)
7283 {
7284 /* The Post-Header is empty. The Variable Data part begins immediately. */
7285 buf+= description_event->common_header_len +
7286 description_event->post_header_len[RAND_EVENT-1];
7287 seed1= uint8korr(buf+RAND_SEED1_OFFSET);
7288 seed2= uint8korr(buf+RAND_SEED2_OFFSET);
7289 }
7290
7291
7292 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7293 bool Rand_log_event::write(IO_CACHE* file)
7294 {
7295 uchar buf[16];
7296 int8store(buf + RAND_SEED1_OFFSET, seed1);
7297 int8store(buf + RAND_SEED2_OFFSET, seed2);
7298 return (write_header(file, sizeof(buf)) ||
7299 wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7300 write_footer(file));
7301 }
7302 #endif
7303
7304
7305 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7306 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7307 {
7308 IO_CACHE *const head= &print_event_info->head_cache;
7309
7310 char llbuff[22],llbuff2[22];
7311 if (!print_event_info->short_form)
7312 {
7313 print_header(head, print_event_info, FALSE);
7314 my_b_printf(head, "\tRand\n");
7315 }
7316 my_b_printf(head, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
7317 llstr(seed1, llbuff),llstr(seed2, llbuff2),
7318 print_event_info->delimiter);
7319 }
7320 #endif /* MYSQL_CLIENT */
7321
7322
7323 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)7324 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
7325 {
7326 /*
7327 We are now in a statement until the associated query log event has
7328 been processed.
7329 */
7330 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7331
7332 if (rli->deferred_events_collecting)
7333 return rli->deferred_events->add(this);
7334
7335 thd->rand.seed1= (ulong) seed1;
7336 thd->rand.seed2= (ulong) seed2;
7337 return 0;
7338 }
7339
do_update_pos(Relay_log_info * rli)7340 int Rand_log_event::do_update_pos(Relay_log_info *rli)
7341 {
7342 rli->inc_event_relay_log_pos();
7343 return 0;
7344 }
7345
7346
7347 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7348 Rand_log_event::do_shall_skip(Relay_log_info *rli)
7349 {
7350 /*
7351 It is a common error to set the slave skip counter to 1 instead of
7352 2 when recovering from an insert which used a auto increment,
7353 rand, or user var. Therefore, if the slave skip counter is 1, we
7354 just say that this event should be skipped by ignoring it, meaning
7355 that we do not change the value of the slave skip counter since it
7356 will be decreased by the following insert event.
7357 */
7358 return continue_group(rli);
7359 }
7360
7361 /**
7362 Exec deferred Int-, Rand- and User- var events prefixing
7363 a Query-log-event event.
7364
7365 @param thd THD handle
7366
7367 @return false on success, true if a failure in an event applying occurred.
7368 */
slave_execute_deferred_events(THD * thd)7369 bool slave_execute_deferred_events(THD *thd)
7370 {
7371 bool res= false;
7372 Relay_log_info *rli= thd->rli_slave;
7373
7374 DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
7375
7376 if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
7377 return res;
7378
7379 res= rli->deferred_events->execute(rli);
7380
7381 return res;
7382 }
7383
7384 #endif /* !MYSQL_CLIENT */
7385
7386
7387 /**************************************************************************
7388 Xid_log_event methods
7389 **************************************************************************/
7390
7391 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7392 int Xid_log_event::pack_info(Protocol *protocol)
7393 {
7394 char buf[128], *pos;
7395 pos= strmov(buf, "COMMIT /* xid=");
7396 pos= longlong10_to_str(xid, pos, 10);
7397 pos= strmov(pos, " */");
7398 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7399 return 0;
7400 }
7401 #endif
7402
7403 /**
7404 @note
7405 It's ok not to use int8store here,
7406 as long as xid_t::set(ulonglong) and
7407 xid_t::get_my_xid doesn't do it either.
7408 We don't care about actual values of xids as long as
7409 identical numbers compare identically
7410 */
7411
7412 Xid_log_event::
Xid_log_event(const char * buf,const Format_description_log_event * description_event)7413 Xid_log_event(const char* buf,
7414 const Format_description_log_event *description_event)
7415 :Log_event(buf, description_event)
7416 {
7417 /* The Post-Header is empty. The Variable Data part begins immediately. */
7418 buf+= description_event->common_header_len +
7419 description_event->post_header_len[XID_EVENT-1];
7420 memcpy((char*) &xid, buf, sizeof(xid));
7421 }
7422
7423
7424 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7425 bool Xid_log_event::write(IO_CACHE* file)
7426 {
7427 DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
7428 return (write_header(file, sizeof(xid)) ||
7429 wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
7430 write_footer(file));
7431 }
7432 #endif
7433
7434
7435 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7436 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7437 {
7438 IO_CACHE *const head= &print_event_info->head_cache;
7439
7440 if (!print_event_info->short_form)
7441 {
7442 char buf[64];
7443 longlong10_to_str(xid, buf, 10);
7444
7445 print_header(head, print_event_info, FALSE);
7446 my_b_printf(head, "\tXid = %s\n", buf);
7447 }
7448 my_b_printf(head, "COMMIT%s\n", print_event_info->delimiter);
7449 }
7450 #endif /* MYSQL_CLIENT */
7451
7452
7453 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7454 /**
7455 The methods combines few commit actions to make it useable
7456 as in the single- so multi- threaded case.
7457
7458 @param thd a pointer to THD handle
7459 @return false as success and
7460 true as an error
7461 */
7462
do_commit(THD * thd)7463 bool Xid_log_event::do_commit(THD *thd)
7464 {
7465 DBUG_EXECUTE_IF("dbug.reached_commit",
7466 {DBUG_SET("+d,dbug.enabled_commit");});
7467 bool error= trans_commit(thd); /* Automatically rolls back on error. */
7468 DBUG_EXECUTE_IF("crash_after_apply",
7469 sql_print_information("Crashing crash_after_apply.");
7470 DBUG_SUICIDE(););
7471 thd->mdl_context.release_transactional_locks();
7472
7473 if (thd->variables.gtid_next.type == GTID_GROUP &&
7474 thd->owned_gtid.sidno != 0)
7475 {
7476 // GTID logging and cleanup runs regardless of the current res
7477 error |= gtid_empty_group_log_and_cleanup(thd);
7478 }
7479
7480 /*
7481 Increment the global status commit count variable
7482 */
7483 if (!error)
7484 status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
7485
7486 return error;
7487 }
7488
7489 /**
7490 Worker commits Xid transaction and in case of its transactional
7491 info table marks the current group as done in the Coordnator's
7492 Group Assigned Queue.
7493
7494 @return zero as success or non-zero as an error
7495 */
do_apply_event_worker(Slave_worker * w)7496 int Xid_log_event::do_apply_event_worker(Slave_worker *w)
7497 {
7498 int error= 0;
7499 lex_start(thd);
7500 mysql_reset_thd_for_next_command(thd);
7501 Slave_committed_queue *coordinator_gaq= w->c_rli->gaq;
7502
7503 /* For a slave Xid_log_event is COMMIT */
7504 general_log_print(thd, COM_QUERY,
7505 "COMMIT /* implicit, from Xid_log_event */");
7506
7507 DBUG_PRINT("mts", ("do_apply group master %s %llu group relay %s %llu event %s %llu.",
7508 w->get_group_master_log_name(),
7509 w->get_group_master_log_pos(),
7510 w->get_group_relay_log_name(),
7511 w->get_group_relay_log_pos(),
7512 w->get_event_relay_log_name(),
7513 w->get_event_relay_log_pos()));
7514
7515 DBUG_EXECUTE_IF("crash_before_update_pos",
7516 sql_print_information("Crashing crash_before_update_pos.");
7517 DBUG_SUICIDE(););
7518
7519 ulong gaq_idx= mts_group_idx;
7520 Slave_job_group *ptr_group= coordinator_gaq->get_job_group(gaq_idx);
7521
7522 if ((error= w->commit_positions(this, ptr_group,
7523 w->c_rli->is_transactional())))
7524 goto err;
7525
7526 DBUG_PRINT("mts", ("do_apply group master %s %llu group relay %s %llu event %s %llu.",
7527 w->get_group_master_log_name(),
7528 w->get_group_master_log_pos(),
7529 w->get_group_relay_log_name(),
7530 w->get_group_relay_log_pos(),
7531 w->get_event_relay_log_name(),
7532 w->get_event_relay_log_pos()));
7533
7534 DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7535 sql_print_information("Crashing crash_after_update_pos_before_apply.");
7536 DBUG_SUICIDE(););
7537
7538 error= do_commit(thd);
7539 if (error)
7540 w->rollback_positions(ptr_group);
7541 err:
7542 return error;
7543 }
7544
do_apply_event(Relay_log_info const * rli)7545 int Xid_log_event::do_apply_event(Relay_log_info const *rli)
7546 {
7547 DBUG_ENTER("Xid_log_event::do_apply_event");
7548 int error= 0;
7549 char saved_group_master_log_name[FN_REFLEN];
7550 char saved_group_relay_log_name[FN_REFLEN];
7551 volatile my_off_t saved_group_master_log_pos;
7552 volatile my_off_t saved_group_relay_log_pos;
7553
7554 char new_group_master_log_name[FN_REFLEN];
7555 char new_group_relay_log_name[FN_REFLEN];
7556 volatile my_off_t new_group_master_log_pos;
7557 volatile my_off_t new_group_relay_log_pos;
7558
7559 lex_start(thd);
7560 mysql_reset_thd_for_next_command(thd);
7561 Relay_log_info *rli_ptr= const_cast<Relay_log_info *>(rli);
7562
7563 /* For a slave Xid_log_event is COMMIT */
7564 general_log_print(thd, COM_QUERY,
7565 "COMMIT /* implicit, from Xid_log_event */");
7566
7567 mysql_mutex_lock(&rli_ptr->data_lock);
7568
7569 /*
7570 Save the rli positions. We need them to temporarily reset the positions
7571 just before the commit.
7572 */
7573 strmake(saved_group_master_log_name, rli_ptr->get_group_master_log_name(),
7574 FN_REFLEN - 1);
7575 saved_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7576 strmake(saved_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7577 FN_REFLEN - 1);
7578 saved_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7579
7580 DBUG_PRINT("info", ("do_apply group master %s %llu group relay %s %llu event %s %llu\n",
7581 rli_ptr->get_group_master_log_name(),
7582 rli_ptr->get_group_master_log_pos(),
7583 rli_ptr->get_group_relay_log_name(),
7584 rli_ptr->get_group_relay_log_pos(),
7585 rli_ptr->get_event_relay_log_name(),
7586 rli_ptr->get_event_relay_log_pos()));
7587
7588 DBUG_EXECUTE_IF("crash_before_update_pos",
7589 sql_print_information("Crashing crash_before_update_pos.");
7590 DBUG_SUICIDE(););
7591
7592 /*
7593 We need to update the positions in here to make it transactional.
7594 */
7595 rli_ptr->inc_event_relay_log_pos();
7596 rli_ptr->set_group_relay_log_pos(rli_ptr->get_event_relay_log_pos());
7597 rli_ptr->set_group_relay_log_name(rli_ptr->get_event_relay_log_name());
7598
7599 rli_ptr->notify_group_relay_log_name_update();
7600
7601 if (log_pos) // 3.23 binlogs don't have log_posx
7602 rli_ptr->set_group_master_log_pos(log_pos);
7603
7604 /*
7605 rli repository being transactional means replication is crash safe.
7606 Positions are written into transactional tables ahead of commit and the
7607 changes are made permanent during commit.
7608 */
7609 if (rli_ptr->is_transactional())
7610 {
7611 if ((error= rli_ptr->flush_info(true)))
7612 goto err;
7613 }
7614
7615 DBUG_PRINT("info", ("do_apply group master %s %llu group relay %s %llu event %s %llu\n",
7616 rli_ptr->get_group_master_log_name(),
7617 rli_ptr->get_group_master_log_pos(),
7618 rli_ptr->get_group_relay_log_name(),
7619 rli_ptr->get_group_relay_log_pos(),
7620 rli_ptr->get_event_relay_log_name(),
7621 rli_ptr->get_event_relay_log_pos()));
7622
7623 DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7624 sql_print_information("Crashing crash_after_update_pos_before_apply.");
7625 DBUG_SUICIDE(););
7626
7627 /**
7628 Commit operation expects the global transaction state variable 'xa_state'to
7629 be set to 'XA_NOTR'. In order to simulate commit failure we set
7630 the 'xa_state' to 'XA_IDLE' so that the commit reports 'ER_XAER_RMFAIL'
7631 error.
7632 */
7633 DBUG_EXECUTE_IF("simulate_commit_failure",
7634 {
7635 thd->transaction.xid_state.xa_state = XA_IDLE;
7636 });
7637
7638 /*
7639 Save the new rli positions. These positions will be set back to group*
7640 positions on successful completion of the commit operation.
7641 */
7642 strmake(new_group_master_log_name, rli_ptr->get_group_master_log_name(),
7643 FN_REFLEN - 1);
7644 new_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7645 strmake(new_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7646 FN_REFLEN - 1);
7647 new_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7648 /*
7649 Rollback positions in memory just before commit. Position values will be
7650 reset to their new values only on successful commit operation.
7651 */
7652 rli_ptr->set_group_master_log_name(saved_group_master_log_name);
7653 rli_ptr->notify_group_master_log_name_update();
7654 rli_ptr->set_group_master_log_pos(saved_group_master_log_pos);
7655 rli_ptr->set_group_relay_log_name(saved_group_relay_log_name);
7656 rli_ptr->notify_group_relay_log_name_update();
7657 rli_ptr->set_group_relay_log_pos(saved_group_relay_log_pos);
7658
7659 DBUG_PRINT("info", ("Rolling back to group master %s %llu group relay %s"
7660 " %llu\n", rli_ptr->get_group_master_log_name(),
7661 rli_ptr->get_group_master_log_pos(),
7662 rli_ptr->get_group_relay_log_name(),
7663 rli_ptr->get_group_relay_log_pos()));
7664 mysql_mutex_unlock(&rli_ptr->data_lock);
7665 error= do_commit(thd);
7666 mysql_mutex_lock(&rli_ptr->data_lock);
7667 if (error)
7668 {
7669 #ifdef WITH_WSREP
7670 /* if slave transaction has to be replayed, do not report error message */
7671 if ((!WSREP(thd) || thd->wsrep_conflict_state != MUST_REPLAY))
7672 #endif /* WITH_WSREP */
7673 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
7674 "Error in Xid_log_event: Commit could not be completed, '%s'",
7675 thd->get_stmt_da()->message());
7676 }
7677 else
7678 {
7679 DBUG_EXECUTE_IF("crash_after_commit_before_update_pos",
7680 sql_print_information("Crashing "
7681 "crash_after_commit_before_update_pos.");
7682 DBUG_SUICIDE(););
7683 /* Update positions on successful commit */
7684 rli_ptr->set_group_master_log_name(new_group_master_log_name);
7685 rli_ptr->notify_group_master_log_name_update();
7686 rli_ptr->set_group_master_log_pos(new_group_master_log_pos);
7687 rli_ptr->set_group_relay_log_name(new_group_relay_log_name);
7688 rli_ptr->notify_group_relay_log_name_update();
7689 rli_ptr->set_group_relay_log_pos(new_group_relay_log_pos);
7690
7691 DBUG_PRINT("info", ("Updating positions on succesful commit to group master"
7692 " %s %llu group relay %s %llu\n",
7693 rli_ptr->get_group_master_log_name(),
7694 rli_ptr->get_group_master_log_pos(),
7695 rli_ptr->get_group_relay_log_name(),
7696 rli_ptr->get_group_relay_log_pos()));
7697
7698 /*
7699 For transactional repository the positions are flushed ahead of commit.
7700 Where as for non transactional rli repository the positions are flushed
7701 only on succesful commit.
7702 */
7703 if (!rli_ptr->is_transactional())
7704 rli_ptr->flush_info(false);
7705 }
7706 err:
7707 mysql_cond_broadcast(&rli_ptr->data_cond);
7708 mysql_mutex_unlock(&rli_ptr->data_lock);
7709
7710 DBUG_RETURN(error);
7711 }
7712
7713 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7714 Xid_log_event::do_shall_skip(Relay_log_info *rli)
7715 {
7716 DBUG_ENTER("Xid_log_event::do_shall_skip");
7717 if (rli->slave_skip_counter > 0) {
7718 thd->variables.option_bits&= ~OPTION_BEGIN;
7719 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
7720 }
7721 DBUG_RETURN(Log_event::do_shall_skip(rli));
7722 }
7723 #endif /* !MYSQL_CLIENT */
7724
7725
7726 /**************************************************************************
7727 User_var_log_event methods
7728 **************************************************************************/
7729
7730 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7731 int User_var_log_event::pack_info(Protocol* protocol)
7732 {
7733 char *buf= 0;
7734 char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
7735 int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len);
7736 quoted_id[id_len]= '\0';
7737 uint val_offset= 2 + id_len;
7738 uint event_len= val_offset;
7739
7740 if (is_null)
7741 {
7742 if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
7743 return 1;
7744 strmov(buf + val_offset, "NULL");
7745 event_len= val_offset + 4;
7746 }
7747 else
7748 {
7749 switch (type) {
7750 case REAL_RESULT:
7751 double real_val;
7752 float8get(real_val, val);
7753 if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
7754 MYF(MY_WME))))
7755 return 1;
7756 event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
7757 buf + val_offset, NULL);
7758 break;
7759 case INT_RESULT:
7760 if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
7761 return 1;
7762 event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
7763 ((flags & User_var_log_event::UNSIGNED_F) ?
7764 10 : -10))-buf;
7765 break;
7766 case DECIMAL_RESULT:
7767 {
7768 if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH + 1,
7769 MYF(MY_WME))))
7770 return 1;
7771 String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin);
7772 my_decimal dec;
7773 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
7774 val[1]);
7775 my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
7776 event_len= str.length() + val_offset;
7777 break;
7778 }
7779 case STRING_RESULT:
7780 /* 15 is for 'COLLATE' and other chars */
7781 buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
7782 MYF(MY_WME));
7783 CHARSET_INFO *cs;
7784 if (!buf)
7785 return 1;
7786 if (!(cs= get_charset(charset_number, MYF(0))))
7787 {
7788 strmov(buf+val_offset, "???");
7789 event_len+= 3;
7790 }
7791 else
7792 {
7793 char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
7794 p= str_to_hex(p, val, val_len);
7795 p= strxmov(p, " COLLATE ", cs->name, NullS);
7796 event_len= p-buf;
7797 }
7798 break;
7799 case ROW_RESULT:
7800 default:
7801 DBUG_ASSERT(1);
7802 return 1;
7803 }
7804 }
7805 buf[0]= '@';
7806 memcpy(buf + 1, quoted_id, id_len);
7807 buf[1 + id_len]= '=';
7808 protocol->store(buf, event_len, &my_charset_bin);
7809 my_free(buf);
7810 return 0;
7811 }
7812 #endif /* !MYSQL_CLIENT */
7813
7814
7815 User_var_log_event::
User_var_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)7816 User_var_log_event(const char* buf, uint event_len,
7817 const Format_description_log_event* description_event)
7818 :Log_event(buf, description_event)
7819 #ifndef MYSQL_CLIENT
7820 , deferred(false), query_id(0)
7821 #endif
7822 {
7823 bool error= false;
7824 const char* buf_start= buf;
7825 /* The Post-Header is empty. The Variable Data part begins immediately. */
7826 const char *start= buf;
7827 buf+= description_event->common_header_len +
7828 description_event->post_header_len[USER_VAR_EVENT-1];
7829 name_len= uint4korr(buf);
7830 /* Avoid reading out of buffer */
7831 if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
7832 {
7833 error= true;
7834 goto err;
7835 }
7836
7837 name= (char *) buf + UV_NAME_LEN_SIZE;
7838
7839 /*
7840 We don't know yet is_null value, so we must assume that name_len
7841 may have the bigger value possible, is_null= True and there is no
7842 payload for val, or even that name_len is 0.
7843 */
7844 if (!valid_buffer_range<uint>(name_len, buf_start, name,
7845 event_len - UV_VAL_IS_NULL))
7846 {
7847 error= true;
7848 goto err;
7849 }
7850
7851 buf+= UV_NAME_LEN_SIZE + name_len;
7852 is_null= (bool) *buf;
7853 flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
7854 if (is_null)
7855 {
7856 type= STRING_RESULT;
7857 charset_number= my_charset_bin.number;
7858 val_len= 0;
7859 val= 0;
7860 }
7861 else
7862 {
7863 if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
7864 + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
7865 buf_start, buf, event_len))
7866 {
7867 error= true;
7868 goto err;
7869 }
7870
7871 type= (Item_result) buf[UV_VAL_IS_NULL];
7872 charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
7873 val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7874 UV_CHARSET_NUMBER_SIZE);
7875 val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7876 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
7877
7878 if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
7879 {
7880 error= true;
7881 goto err;
7882 }
7883
7884 /**
7885 We need to check if this is from an old server
7886 that did not pack information for flags.
7887 We do this by checking if there are extra bytes
7888 after the packed value. If there are we take the
7889 extra byte and it's value is assumed to contain
7890 the flags value.
7891
7892 Old events will not have this extra byte, thence,
7893 we keep the flags set to UNDEF_F.
7894 */
7895 uint bytes_read= ((val + val_len) - start);
7896 if (bytes_read > event_len)
7897 {
7898 error= true;
7899 goto err;
7900 }
7901 #ifndef DBUG_OFF
7902 bool old_pre_checksum_fd= description_event->is_version_before_checksum();
7903 #endif
7904 DBUG_ASSERT((bytes_read == data_written -
7905 (old_pre_checksum_fd ||
7906 (description_event->checksum_alg ==
7907 BINLOG_CHECKSUM_ALG_OFF)) ?
7908 0 : BINLOG_CHECKSUM_LEN)
7909 ||
7910 (bytes_read == data_written -1 -
7911 (old_pre_checksum_fd ||
7912 (description_event->checksum_alg ==
7913 BINLOG_CHECKSUM_ALG_OFF)) ?
7914 0 : BINLOG_CHECKSUM_LEN));
7915 if ((data_written - bytes_read) > 0)
7916 {
7917 flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7918 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
7919 val_len);
7920 }
7921 }
7922
7923 err:
7924 if (error)
7925 name= 0;
7926 }
7927
7928
7929 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7930 bool User_var_log_event::write(IO_CACHE* file)
7931 {
7932 char buf[UV_NAME_LEN_SIZE];
7933 char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7934 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
7935 uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
7936 uint unsigned_len= 0;
7937 uint buf1_length;
7938 ulong event_length;
7939
7940 int4store(buf, name_len);
7941
7942 if ((buf1[0]= is_null))
7943 {
7944 buf1_length= 1;
7945 val_len= 0; // Length of 'pos'
7946 }
7947 else
7948 {
7949 buf1[1]= type;
7950 int4store(buf1 + 2, charset_number);
7951
7952 switch (type) {
7953 case REAL_RESULT:
7954 float8store(buf2, *(double*) val);
7955 break;
7956 case INT_RESULT:
7957 int8store(buf2, *(longlong*) val);
7958 unsigned_len= 1;
7959 break;
7960 case DECIMAL_RESULT:
7961 {
7962 my_decimal *dec= (my_decimal *)val;
7963 dec->fix_buffer_pointer();
7964 buf2[0]= (char)(dec->intg + dec->frac);
7965 buf2[1]= (char)dec->frac;
7966 decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
7967 val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
7968 break;
7969 }
7970 case STRING_RESULT:
7971 pos= (uchar*) val;
7972 break;
7973 case ROW_RESULT:
7974 default:
7975 DBUG_ASSERT(1);
7976 return 0;
7977 }
7978 int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
7979 buf1_length= 10;
7980 }
7981
7982 /* Length of the whole event */
7983 event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
7984
7985 return (write_header(file, event_length) ||
7986 wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
7987 wrapper_my_b_safe_write(file, (uchar*) name, name_len) ||
7988 wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
7989 wrapper_my_b_safe_write(file, pos, val_len) ||
7990 wrapper_my_b_safe_write(file, &flags, unsigned_len) ||
7991 write_footer(file));
7992 }
7993 #endif
7994
7995
7996 /*
7997 User_var_log_event::print()
7998 */
7999
8000 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8001 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8002 {
8003 IO_CACHE *const head= &print_event_info->head_cache;
8004 char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
8005 char name_id[NAME_LEN];
8006 int quoted_len= 0;
8007
8008 if (!print_event_info->short_form)
8009 {
8010 print_header(head, print_event_info, FALSE);
8011 my_b_printf(head, "\tUser_var\n");
8012 }
8013 strmov(name_id, name);
8014 name_id[name_len]= '\0';
8015 my_b_printf(head, "SET @");
8016 quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
8017 (const char *) name_id);
8018 quoted_id[quoted_len]= '\0';
8019 my_b_write(head, (uchar*) quoted_id, quoted_len);
8020
8021 if (is_null)
8022 {
8023 my_b_printf(head, ":=NULL%s\n", print_event_info->delimiter);
8024 }
8025 else
8026 {
8027 switch (type) {
8028 case REAL_RESULT:
8029 double real_val;
8030 char real_buf[FMT_G_BUFSIZE(14)];
8031 float8get(real_val, val);
8032 sprintf(real_buf, "%.14g", real_val);
8033 my_b_printf(head, ":=%s%s\n", real_buf, print_event_info->delimiter);
8034 break;
8035 case INT_RESULT:
8036 char int_buf[22];
8037 longlong10_to_str(uint8korr(val), int_buf,
8038 ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
8039 my_b_printf(head, ":=%s%s\n", int_buf, print_event_info->delimiter);
8040 break;
8041 case DECIMAL_RESULT:
8042 {
8043 char str_buf[200];
8044 int str_len= sizeof(str_buf) - 1;
8045 int precision= (int)val[0];
8046 int scale= (int)val[1];
8047 decimal_digit_t dec_buf[10];
8048 decimal_t dec;
8049 dec.len= 10;
8050 dec.buf= dec_buf;
8051
8052 bin2decimal((uchar*) val+2, &dec, precision, scale);
8053 decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
8054 str_buf[str_len]= 0;
8055 my_b_printf(head, ":=%s%s\n", str_buf, print_event_info->delimiter);
8056 break;
8057 }
8058 case STRING_RESULT:
8059 {
8060 /*
8061 Let's express the string in hex. That's the most robust way. If we
8062 print it in character form instead, we need to escape it with
8063 character_set_client which we don't know (we will know it in 5.0, but
8064 in 4.1 we don't know it easily when we are printing
8065 User_var_log_event). Explanation why we would need to bother with
8066 character_set_client (quoting Bar):
8067 > Note, the parser doesn't switch to another unescaping mode after
8068 > it has met a character set introducer.
8069 > For example, if an SJIS client says something like:
8070 > SET @a= _ucs2 \0a\0b'
8071 > the string constant is still unescaped according to SJIS, not
8072 > according to UCS2.
8073 */
8074 char *hex_str;
8075 CHARSET_INFO *cs;
8076
8077 hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
8078 if (!hex_str)
8079 return;
8080 str_to_hex(hex_str, val, val_len);
8081 /*
8082 For proper behaviour when mysqlbinlog|mysql, we need to explicitely
8083 specify the variable's collation. It will however cause problems when
8084 people want to mysqlbinlog|mysql into another server not supporting the
8085 character set. But there's not much to do about this and it's unlikely.
8086 */
8087 if (!(cs= get_charset(charset_number, MYF(0))))
8088 /*
8089 Generate an unusable command (=> syntax error) is probably the best
8090 thing we can do here.
8091 */
8092 my_b_printf(head, ":=???%s\n", print_event_info->delimiter);
8093 else
8094 my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n",
8095 cs->csname, hex_str, cs->name,
8096 print_event_info->delimiter);
8097 my_free(hex_str);
8098 }
8099 break;
8100 case ROW_RESULT:
8101 default:
8102 DBUG_ASSERT(1);
8103 return;
8104 }
8105 }
8106 }
8107 #endif
8108
8109
8110 /*
8111 User_var_log_event::do_apply_event()
8112 */
8113
8114 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8115 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
8116 {
8117 Item *it= 0;
8118 CHARSET_INFO *charset;
8119 query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
8120
8121 if (rli->deferred_events_collecting)
8122 {
8123 set_deferred(current_thd->query_id);
8124 return rli->deferred_events->add(this);
8125 } else if (is_deferred())
8126 {
8127 sav_query_id= current_thd->query_id;
8128 current_thd->query_id= query_id; /* recreating original time context */
8129 }
8130
8131 if (!(charset= get_charset(charset_number, MYF(MY_WME))))
8132 {
8133 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8134 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8135 "Invalid character set for User var event");
8136 return 1;
8137 }
8138 double real_val;
8139 longlong int_val;
8140
8141 /*
8142 We are now in a statement until the associated query log event has
8143 been processed.
8144 */
8145 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
8146
8147 if (is_null)
8148 {
8149 it= new Item_null();
8150 }
8151 else
8152 {
8153 switch (type) {
8154 case REAL_RESULT:
8155 if (val_len != 8)
8156 {
8157 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8158 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8159 "Invalid variable length at User var event");
8160 return 1;
8161 }
8162 float8get(real_val, val);
8163 it= new Item_float(real_val, 0);
8164 val= (char*) &real_val; // Pointer to value in native format
8165 val_len= 8;
8166 break;
8167 case INT_RESULT:
8168 if (val_len != 8)
8169 {
8170 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8171 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8172 "Invalid variable length at User var event");
8173 return 1;
8174 }
8175 int_val= (longlong) uint8korr(val);
8176 it= new Item_int(int_val);
8177 val= (char*) &int_val; // Pointer to value in native format
8178 val_len= 8;
8179 break;
8180 case DECIMAL_RESULT:
8181 {
8182 if (val_len < 3)
8183 {
8184 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8185 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8186 "Invalid variable length at User var event");
8187 return 1;
8188 }
8189 Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
8190 it= dec;
8191 val= (char *)dec->val_decimal(NULL);
8192 val_len= sizeof(my_decimal);
8193 break;
8194 }
8195 case STRING_RESULT:
8196 it= new Item_string(val, val_len, charset);
8197 break;
8198 case ROW_RESULT:
8199 default:
8200 DBUG_ASSERT(1);
8201 return 0;
8202 }
8203 }
8204 Item_func_set_user_var *e=
8205 new Item_func_set_user_var(Name_string(name, name_len, false), it, false);
8206 /*
8207 Item_func_set_user_var can't substitute something else on its place =>
8208 0 can be passed as last argument (reference on item)
8209
8210 Fix_fields() can fail, in which case a call of update_hash() might
8211 crash the server, so if fix fields fails, we just return with an
8212 error.
8213 */
8214 if (e->fix_fields(thd, 0))
8215 return 1;
8216
8217 /*
8218 A variable can just be considered as a table with
8219 a single record and with a single column. Thus, like
8220 a column value, it could always have IMPLICIT derivation.
8221 */
8222 e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
8223 (flags & User_var_log_event::UNSIGNED_F));
8224 if (!is_deferred())
8225 free_root(thd->mem_root, 0);
8226 else
8227 current_thd->query_id= sav_query_id; /* restore current query's context */
8228
8229 return 0;
8230 }
8231
do_update_pos(Relay_log_info * rli)8232 int User_var_log_event::do_update_pos(Relay_log_info *rli)
8233 {
8234 rli->inc_event_relay_log_pos();
8235 return 0;
8236 }
8237
8238 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)8239 User_var_log_event::do_shall_skip(Relay_log_info *rli)
8240 {
8241 /*
8242 It is a common error to set the slave skip counter to 1 instead
8243 of 2 when recovering from an insert which used a auto increment,
8244 rand, or user var. Therefore, if the slave skip counter is 1, we
8245 just say that this event should be skipped by ignoring it, meaning
8246 that we do not change the value of the slave skip counter since it
8247 will be decreased by the following insert event.
8248 */
8249 return continue_group(rli);
8250 }
8251 #endif /* !MYSQL_CLIENT */
8252
8253
8254 /**************************************************************************
8255 Unknown_log_event methods
8256 **************************************************************************/
8257
8258 #ifdef HAVE_REPLICATION
8259 #ifdef MYSQL_CLIENT
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info)8260 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
8261 {
8262 if (print_event_info->short_form)
8263 return;
8264 print_header(&print_event_info->head_cache, print_event_info, FALSE);
8265 my_b_printf(&print_event_info->head_cache, "\n# %s", "Unknown event\n");
8266 }
8267 #endif
8268
8269 /**************************************************************************
8270 Stop_log_event methods
8271 **************************************************************************/
8272
8273 /*
8274 Stop_log_event::print()
8275 */
8276
8277 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8278 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8279 {
8280 if (print_event_info->short_form)
8281 return;
8282
8283 print_header(&print_event_info->head_cache, print_event_info, FALSE);
8284 my_b_printf(&print_event_info->head_cache, "\tStop\n");
8285 }
8286 #endif /* MYSQL_CLIENT */
8287
8288
8289 #ifndef MYSQL_CLIENT
8290 /*
8291 The master stopped. We used to clean up all temporary tables but
8292 this is useless as, as the master has shut down properly, it has
8293 written all DROP TEMPORARY TABLE (prepared statements' deletion is
8294 TODO only when we binlog prep stmts). We used to clean up
8295 slave_load_tmpdir, but this is useless as it has been cleared at the
8296 end of LOAD DATA INFILE. So we have nothing to do here. The place
8297 were we must do this cleaning is in
8298 Start_log_event_v3::do_apply_event(), not here. Because if we come
8299 here, the master was sane.
8300
8301 This must only be called from the Slave SQL thread, since it calls
8302 flush_relay_log_info().
8303 */
do_update_pos(Relay_log_info * rli)8304 int Stop_log_event::do_update_pos(Relay_log_info *rli)
8305 {
8306 int error_inc= 0;
8307 int error_flush= 0;
8308 /*
8309 We do not want to update master_log pos because we get a rotate event
8310 before stop, so by now group_master_log_name is set to the next log.
8311 If we updated it, we will have incorrect master coordinates and this
8312 could give false triggers in MASTER_POS_WAIT() that we have reached
8313 the target position when in fact we have not.
8314 The group position is always unchanged in MTS mode because the event
8315 is never executed so can't be scheduled to a Worker.
8316 */
8317 if ((thd->variables.option_bits & OPTION_BEGIN) || rli->is_parallel_exec())
8318 rli->inc_event_relay_log_pos();
8319 else
8320 {
8321 error_inc= rli->inc_group_relay_log_pos(0, true/*need_data_lock=true*/);
8322 error_flush= rli->flush_info(TRUE);
8323 }
8324 return (error_inc || error_flush);
8325 }
8326
8327 #endif /* !MYSQL_CLIENT */
8328 #endif /* HAVE_REPLICATION */
8329
8330
8331 /**************************************************************************
8332 Create_file_log_event methods
8333 **************************************************************************/
8334
8335 /*
8336 Create_file_log_event ctor
8337 */
8338
8339 #ifndef MYSQL_CLIENT
8340 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)8341 Create_file_log_event(THD* thd_arg, sql_exchange* ex,
8342 const char* db_arg, const char* table_name_arg,
8343 List<Item>& fields_arg,
8344 bool is_concurrent_arg,
8345 enum enum_duplicates handle_dup,
8346 bool ignore,
8347 uchar* block_arg, uint block_len_arg, bool using_trans)
8348 :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
8349 is_concurrent_arg,
8350 handle_dup, ignore, using_trans),
8351 fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
8352 file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
8353 {
8354 DBUG_ENTER("Create_file_log_event");
8355 sql_ex.force_new_format();
8356 DBUG_VOID_RETURN;
8357 }
8358
8359
8360 /*
8361 Create_file_log_event::write_data_body()
8362 */
8363
write_data_body(IO_CACHE * file)8364 bool Create_file_log_event::write_data_body(IO_CACHE* file)
8365 {
8366 bool res;
8367 if ((res= Load_log_event::write_data_body(file)) || fake_base)
8368 return res;
8369 return (my_b_safe_write(file, (uchar*) "", 1) ||
8370 my_b_safe_write(file, (uchar*) block, block_len));
8371 }
8372
8373
8374 /*
8375 Create_file_log_event::write_data_header()
8376 */
8377
write_data_header(IO_CACHE * file)8378 bool Create_file_log_event::write_data_header(IO_CACHE* file)
8379 {
8380 bool res;
8381 uchar buf[CREATE_FILE_HEADER_LEN];
8382 if ((res= Load_log_event::write_data_header(file)) || fake_base)
8383 return res;
8384 int4store(buf + CF_FILE_ID_OFFSET, file_id);
8385 return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
8386 }
8387
8388
8389 /*
8390 Create_file_log_event::write_base()
8391 */
8392
write_base(IO_CACHE * file)8393 bool Create_file_log_event::write_base(IO_CACHE* file)
8394 {
8395 bool res;
8396 fake_base= 1; // pretend we are Load event
8397 res= write(file);
8398 fake_base= 0;
8399 return res;
8400 }
8401
8402 #endif /* !MYSQL_CLIENT */
8403
8404 /*
8405 Create_file_log_event ctor
8406 */
8407
Create_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8408 Create_file_log_event::Create_file_log_event(const char* buf, uint len,
8409 const Format_description_log_event* description_event)
8410 :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
8411 {
8412 DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
8413 uint block_offset;
8414 uint header_len= description_event->common_header_len;
8415 uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
8416 uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
8417 if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
8418 copy_log_event(event_buf,len,
8419 ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
8420 load_header_len + header_len :
8421 (fake_base ? (header_len+load_header_len) :
8422 (header_len+load_header_len) +
8423 create_file_header_len)),
8424 description_event))
8425 DBUG_VOID_RETURN;
8426 if (description_event->binlog_version!=1)
8427 {
8428 file_id= uint4korr(buf +
8429 header_len +
8430 load_header_len + CF_FILE_ID_OFFSET);
8431 /*
8432 Note that it's ok to use get_data_size() below, because it is computed
8433 with values we have already read from this event (because we called
8434 copy_log_event()); we are not using slave's format info to decode
8435 master's format, we are really using master's format info.
8436 Anyway, both formats should be identical (except the common_header_len)
8437 as these Load events are not changed between 4.0 and 5.0 (as logging of
8438 LOAD DATA INFILE does not use Load_log_event in 5.0).
8439
8440 The + 1 is for \0 terminating fname
8441 */
8442 block_offset= (description_event->common_header_len +
8443 Load_log_event::get_data_size() +
8444 create_file_header_len + 1);
8445 if (len < block_offset)
8446 DBUG_VOID_RETURN;
8447 block = (uchar*)buf + block_offset;
8448 block_len = len - block_offset;
8449 }
8450 else
8451 {
8452 sql_ex.force_new_format();
8453 inited_from_old = 1;
8454 }
8455 DBUG_VOID_RETURN;
8456 }
8457
8458
8459 /*
8460 Create_file_log_event::print()
8461 */
8462
8463 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info,bool enable_local)8464 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
8465 bool enable_local)
8466 {
8467 if (print_event_info->short_form)
8468 {
8469 if (enable_local && check_fname_outside_temp_buf())
8470 Load_log_event::print(file, print_event_info);
8471 return;
8472 }
8473
8474 if (enable_local)
8475 {
8476 Load_log_event::print(file, print_event_info,
8477 !check_fname_outside_temp_buf());
8478 /**
8479 reduce the size of io cache so that the write function is called
8480 for every call to my_b_printf().
8481 */
8482 DBUG_EXECUTE_IF ("simulate_create_event_write_error",
8483 {(&print_event_info->head_cache)->write_pos=
8484 (&print_event_info->head_cache)->write_end;
8485 DBUG_SET("+d,simulate_file_write_error");});
8486 /*
8487 That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
8488 SHOW BINLOG EVENTS we don't.
8489 */
8490 my_b_printf(&print_event_info->head_cache, "#");
8491 }
8492
8493 my_b_printf(&print_event_info->head_cache,
8494 " file_id: %d block_len: %d\n", file_id, block_len);
8495 }
8496
8497
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8498 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8499 {
8500 print(file, print_event_info, 0);
8501 }
8502 #endif /* MYSQL_CLIENT */
8503
8504
8505 /*
8506 Create_file_log_event::pack_info()
8507 */
8508
8509 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8510 int Create_file_log_event::pack_info(Protocol *protocol)
8511 {
8512 char buf[NAME_LEN*2 + 30 + 21*2], *pos;
8513 pos= strmov(buf, "db=");
8514 memcpy(pos, db, db_len);
8515 pos= strmov(pos + db_len, ";table=");
8516 memcpy(pos, table_name, table_name_len);
8517 pos= strmov(pos + table_name_len, ";file_id=");
8518 pos= int10_to_str((long) file_id, pos, 10);
8519 pos= strmov(pos, ";block_len=");
8520 pos= int10_to_str((long) block_len, pos, 10);
8521 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8522 return 0;
8523 }
8524 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8525
8526
8527 /**
8528 Create_file_log_event::do_apply_event()
8529 Constructor for Create_file_log_event to intantiate an event
8530 from the relay log on the slave.
8531
8532 @retval
8533 0 Success
8534 @retval
8535 1 Failure
8536 */
8537
8538 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8539 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
8540 {
8541 char fname_buf[FN_REFLEN+TEMP_FILE_MAX_LEN];
8542 char *ext;
8543 int fd = -1;
8544 IO_CACHE file;
8545 int error = 1;
8546
8547 lex_start(thd);
8548 mysql_reset_thd_for_next_command(thd);
8549 THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
8550 memset(&file, 0, sizeof(file));
8551 ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
8552 /* old copy may exist already */
8553 mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8554 /**
8555 To simulate file creation failure, convert the file name to a
8556 directory by appending a "/" to the file name.
8557 */
8558 DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event",
8559 {
8560 strcat(fname_buf,"/");
8561 });
8562 if ((fd= mysql_file_create(key_file_log_event_info,
8563 fname_buf, CREATE_MODE,
8564 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8565 MYF(MY_WME))) < 0 ||
8566 init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
8567 MYF(MY_WME|MY_NABP)))
8568 {
8569 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8570 "Error in Create_file event: could not open file '%s'",
8571 fname_buf);
8572 goto err;
8573 }
8574
8575 // a trick to avoid allocating another buffer
8576 fname= fname_buf;
8577 fname_len= (uint) (strmov(ext, ".data") - fname);
8578 if (write_base(&file))
8579 {
8580 strmov(ext, ".info"); // to have it right in the error message
8581 rli->report(ERROR_LEVEL, my_errno,
8582 "Error in Create_file event: could not write to file '%s'",
8583 fname_buf);
8584 goto err;
8585 }
8586 end_io_cache(&file);
8587 mysql_file_close(fd, MYF(0));
8588
8589 // fname_buf now already has .data, not .info, because we did our trick
8590 /* old copy may exist already */
8591 mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8592 if ((fd= mysql_file_create(key_file_log_event_data,
8593 fname_buf, CREATE_MODE,
8594 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8595 MYF(MY_WME))) < 0)
8596 {
8597 rli->report(ERROR_LEVEL, my_errno,
8598 "Error in Create_file event: could not open file '%s'",
8599 fname_buf);
8600 goto err;
8601 }
8602 /**
8603 To simulate file write failure,close the file before the write operation.
8604 Write will fail with an error reporting file is UNOPENED.
8605 */
8606 DBUG_EXECUTE_IF("simulate_file_write_error_create_log_event",
8607 {
8608 mysql_file_close(fd, MYF(0));
8609 });
8610 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8611 {
8612 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8613 "Error in Create_file event: write to '%s' failed",
8614 fname_buf);
8615 goto err;
8616 }
8617 error=0; // Everything is ok
8618
8619 err:
8620 if (error)
8621 end_io_cache(&file);
8622 if (fd >= 0)
8623 mysql_file_close(fd, MYF(0));
8624 return error != 0;
8625 }
8626 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8627
8628
8629 /**************************************************************************
8630 Append_block_log_event methods
8631 **************************************************************************/
8632
8633 /*
8634 Append_block_log_event ctor
8635 */
8636
8637 #ifndef MYSQL_CLIENT
Append_block_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)8638 Append_block_log_event::Append_block_log_event(THD *thd_arg,
8639 const char *db_arg,
8640 uchar *block_arg,
8641 uint block_len_arg,
8642 bool using_trans)
8643 :Log_event(thd_arg, 0,
8644 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8645 Log_event::EVENT_STMT_CACHE,
8646 Log_event::EVENT_NORMAL_LOGGING),
8647 block(block_arg),
8648 block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
8649 {
8650 }
8651 #endif
8652
8653
8654 /*
8655 Append_block_log_event ctor
8656 */
8657
Append_block_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8658 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
8659 const Format_description_log_event* description_event)
8660 :Log_event(buf, description_event),block(0)
8661 {
8662 DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
8663 uint8 common_header_len= description_event->common_header_len;
8664 uint8 append_block_header_len=
8665 description_event->post_header_len[APPEND_BLOCK_EVENT-1];
8666 uint total_header_len= common_header_len+append_block_header_len;
8667 if (len < total_header_len)
8668 DBUG_VOID_RETURN;
8669 file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
8670 block= (uchar*)buf + total_header_len;
8671 block_len= len - total_header_len;
8672 DBUG_VOID_RETURN;
8673 }
8674
8675
8676 /*
8677 Append_block_log_event::write()
8678 */
8679
8680 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8681 bool Append_block_log_event::write(IO_CACHE* file)
8682 {
8683 uchar buf[APPEND_BLOCK_HEADER_LEN];
8684 int4store(buf + AB_FILE_ID_OFFSET, file_id);
8685 return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
8686 wrapper_my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
8687 wrapper_my_b_safe_write(file, (uchar*) block, block_len) ||
8688 write_footer(file));
8689 }
8690 #endif
8691
8692
8693 /*
8694 Append_block_log_event::print()
8695 */
8696
8697 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8698 void Append_block_log_event::print(FILE* file,
8699 PRINT_EVENT_INFO* print_event_info)
8700 {
8701 if (print_event_info->short_form)
8702 return;
8703 print_header(&print_event_info->head_cache, print_event_info, FALSE);
8704 my_b_printf(&print_event_info->head_cache,
8705 "\n#%s: file_id: %d block_len: %d\n",
8706 get_type_str(), file_id, block_len);
8707 }
8708 #endif /* MYSQL_CLIENT */
8709
8710
8711 /*
8712 Append_block_log_event::pack_info()
8713 */
8714
8715 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8716 int Append_block_log_event::pack_info(Protocol *protocol)
8717 {
8718 char buf[256];
8719 size_t length;
8720 length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
8721 file_id, block_len);
8722 protocol->store(buf, length, &my_charset_bin);
8723 return 0;
8724 }
8725
8726
8727 /*
8728 Append_block_log_event::get_create_or_append()
8729 */
8730
get_create_or_append() const8731 int Append_block_log_event::get_create_or_append() const
8732 {
8733 return 0; /* append to the file, fail if not exists */
8734 }
8735
8736 /*
8737 Append_block_log_event::do_apply_event()
8738 */
8739
do_apply_event(Relay_log_info const * rli)8740 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
8741 {
8742 char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8743 int fd;
8744 int error = 1;
8745 DBUG_ENTER("Append_block_log_event::do_apply_event");
8746
8747 THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
8748 slave_load_file_stem(fname, file_id, server_id, ".data");
8749 if (get_create_or_append())
8750 {
8751 /*
8752 Usually lex_start() is called by mysql_parse(), but we need it here
8753 as the present method does not call mysql_parse().
8754 */
8755 lex_start(thd);
8756 mysql_reset_thd_for_next_command(thd);
8757 /* old copy may exist already */
8758 mysql_file_delete(key_file_log_event_data, fname, MYF(0));
8759 if ((fd= mysql_file_create(key_file_log_event_data,
8760 fname, CREATE_MODE,
8761 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8762 MYF(MY_WME))) < 0)
8763 {
8764 rli->report(ERROR_LEVEL, my_errno,
8765 "Error in %s event: could not create file '%s'",
8766 get_type_str(), fname);
8767 goto err;
8768 }
8769 }
8770 else if ((fd= mysql_file_open(key_file_log_event_data,
8771 fname,
8772 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
8773 MYF(MY_WME))) < 0)
8774 {
8775 rli->report(ERROR_LEVEL, my_errno,
8776 "Error in %s event: could not open file '%s'",
8777 get_type_str(), fname);
8778 goto err;
8779 }
8780
8781 DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
8782 {
8783 my_delete_allow_opened(fname, MYF(0));
8784 });
8785
8786 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8787 {
8788 rli->report(ERROR_LEVEL, my_errno,
8789 "Error in %s event: write to '%s' failed",
8790 get_type_str(), fname);
8791 goto err;
8792 }
8793 error=0;
8794
8795 err:
8796 if (fd >= 0)
8797 mysql_file_close(fd, MYF(0));
8798 DBUG_RETURN(error);
8799 }
8800 #endif
8801
8802
8803 /**************************************************************************
8804 Delete_file_log_event methods
8805 **************************************************************************/
8806
8807 /*
8808 Delete_file_log_event ctor
8809 */
8810
8811 #ifndef MYSQL_CLIENT
Delete_file_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8812 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
8813 bool using_trans)
8814 :Log_event(thd_arg, 0,
8815 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8816 Log_event::EVENT_STMT_CACHE,
8817 Log_event::EVENT_NORMAL_LOGGING),
8818 file_id(thd_arg->file_id), db(db_arg)
8819 {
8820 }
8821 #endif
8822
8823 /*
8824 Delete_file_log_event ctor
8825 */
8826
Delete_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8827 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
8828 const Format_description_log_event* description_event)
8829 :Log_event(buf, description_event),file_id(0)
8830 {
8831 uint8 common_header_len= description_event->common_header_len;
8832 uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
8833 if (len < (uint)(common_header_len + delete_file_header_len))
8834 return;
8835 file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
8836 }
8837
8838
8839 /*
8840 Delete_file_log_event::write()
8841 */
8842
8843 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8844 bool Delete_file_log_event::write(IO_CACHE* file)
8845 {
8846 uchar buf[DELETE_FILE_HEADER_LEN];
8847 int4store(buf + DF_FILE_ID_OFFSET, file_id);
8848 return (write_header(file, sizeof(buf)) ||
8849 wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8850 write_footer(file));
8851 }
8852 #endif
8853
8854
8855 /*
8856 Delete_file_log_event::print()
8857 */
8858
8859 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8860 void Delete_file_log_event::print(FILE* file,
8861 PRINT_EVENT_INFO* print_event_info)
8862 {
8863 if (print_event_info->short_form)
8864 return;
8865 print_header(&print_event_info->head_cache, print_event_info, FALSE);
8866 my_b_printf(&print_event_info->head_cache,
8867 "\n#Delete_file: file_id=%u\n", file_id);
8868 }
8869 #endif /* MYSQL_CLIENT */
8870
8871 /*
8872 Delete_file_log_event::pack_info()
8873 */
8874
8875 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8876 int Delete_file_log_event::pack_info(Protocol *protocol)
8877 {
8878 char buf[64];
8879 size_t length;
8880 length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8881 protocol->store(buf, length, &my_charset_bin);
8882 return 0;
8883 }
8884 #endif
8885
8886 /*
8887 Delete_file_log_event::do_apply_event()
8888 */
8889
8890 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8891 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
8892 {
8893 char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8894 lex_start(thd);
8895 mysql_reset_thd_for_next_command(thd);
8896 char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
8897 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8898 strmov(ext, ".info");
8899 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8900 return 0;
8901 }
8902 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8903
8904
8905 /**************************************************************************
8906 Execute_load_log_event methods
8907 **************************************************************************/
8908
8909 /*
8910 Execute_load_log_event ctor
8911 */
8912
8913 #ifndef MYSQL_CLIENT
Execute_load_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8914 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
8915 const char* db_arg,
8916 bool using_trans)
8917 :Log_event(thd_arg, 0,
8918 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8919 Log_event::EVENT_STMT_CACHE,
8920 Log_event::EVENT_NORMAL_LOGGING),
8921 file_id(thd_arg->file_id), db(db_arg)
8922 {
8923 }
8924 #endif
8925
8926
8927 /*
8928 Execute_load_log_event ctor
8929 */
8930
Execute_load_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8931 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
8932 const Format_description_log_event* description_event)
8933 :Log_event(buf, description_event), file_id(0)
8934 {
8935 uint8 common_header_len= description_event->common_header_len;
8936 uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
8937 if (len < (uint)(common_header_len+exec_load_header_len))
8938 return;
8939 file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
8940 }
8941
8942
8943 /*
8944 Execute_load_log_event::write()
8945 */
8946
8947 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8948 bool Execute_load_log_event::write(IO_CACHE* file)
8949 {
8950 uchar buf[EXEC_LOAD_HEADER_LEN];
8951 int4store(buf + EL_FILE_ID_OFFSET, file_id);
8952 return (write_header(file, sizeof(buf)) ||
8953 wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8954 write_footer(file));
8955 }
8956 #endif
8957
8958
8959 /*
8960 Execute_load_log_event::print()
8961 */
8962
8963 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8964 void Execute_load_log_event::print(FILE* file,
8965 PRINT_EVENT_INFO* print_event_info)
8966 {
8967 if (print_event_info->short_form)
8968 return;
8969 print_header(&print_event_info->head_cache, print_event_info, FALSE);
8970 my_b_printf(&print_event_info->head_cache, "\n#Exec_load: file_id=%d\n",
8971 file_id);
8972 }
8973 #endif
8974
8975 /*
8976 Execute_load_log_event::pack_info()
8977 */
8978
8979 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8980 int Execute_load_log_event::pack_info(Protocol *protocol)
8981 {
8982 char buf[64];
8983 size_t length;
8984 length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8985 protocol->store(buf, length, &my_charset_bin);
8986 return 0;
8987 }
8988
8989
8990 /*
8991 Execute_load_log_event::do_apply_event()
8992 */
8993
do_apply_event(Relay_log_info const * rli)8994 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
8995 {
8996 char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8997 char *ext;
8998 int fd;
8999 int error= 1;
9000 IO_CACHE file;
9001 Load_log_event *lev= 0;
9002
9003 lex_start(thd);
9004 mysql_reset_thd_for_next_command(thd);
9005 ext= slave_load_file_stem(fname, file_id, server_id, ".info");
9006 /**
9007 To simulate file open failure, convert the file name to a
9008 directory by appending a "/" to the file name. File open
9009 will fail with an error reporting it is not a directory.
9010 */
9011 DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
9012 {
9013 strcat(fname,"/");
9014 });
9015 if ((fd= mysql_file_open(key_file_log_event_info,
9016 fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
9017 MYF(MY_WME))) < 0 ||
9018 init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
9019 MYF(MY_WME|MY_NABP)))
9020 {
9021 rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
9022 "Error in Exec_load event: could not open file '%s'",
9023 fname);
9024 goto err;
9025 }
9026 if (!(lev= (Load_log_event*)
9027 Log_event::read_log_event(&file,
9028 (mysql_mutex_t*) 0,
9029 rli->get_rli_description_event(),
9030 opt_slave_sql_verify_checksum)) ||
9031 lev->get_type_code() != NEW_LOAD_EVENT)
9032 {
9033 rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
9034 "file '%s' appears corrupted", fname);
9035 goto err;
9036 }
9037 lev->thd = thd;
9038 /*
9039 lev->do_apply_event should use rli only for errors i.e. should
9040 not advance rli's position.
9041
9042 lev->do_apply_event is the place where the table is loaded (it
9043 calls mysql_load()).
9044 */
9045 const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
9046 if (lev->do_apply_event(0,rli,1))
9047 {
9048 /*
9049 We want to indicate the name of the file that could not be loaded
9050 (SQL_LOADxxx).
9051 But as we are here we are sure the error is in rli->last_slave_error and
9052 rli->last_slave_errno (example of error: duplicate entry for key), so we
9053 don't want to overwrite it with the filename.
9054 What we want instead is add the filename to the current error message.
9055 */
9056 char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
9057 if (tmp)
9058 {
9059 rli->report(ERROR_LEVEL, rli->last_error().number,
9060 "%s. Failed executing load from '%s'", tmp, fname);
9061 my_free(tmp);
9062 }
9063 goto err;
9064 }
9065 /*
9066 We have an open file descriptor to the .info file; we need to close it
9067 or Windows will refuse to delete the file in mysql_file_delete().
9068 */
9069 if (fd >= 0)
9070 {
9071 mysql_file_close(fd, MYF(0));
9072 end_io_cache(&file);
9073 fd= -1;
9074 }
9075 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
9076 memcpy(ext, ".data", 6);
9077 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9078 error = 0;
9079
9080 err:
9081 delete lev;
9082 if (fd >= 0)
9083 {
9084 mysql_file_close(fd, MYF(0));
9085 end_io_cache(&file);
9086 }
9087 return error;
9088 }
9089
9090 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9091
9092
9093 /**************************************************************************
9094 Begin_load_query_log_event methods
9095 **************************************************************************/
9096
9097 #ifndef MYSQL_CLIENT
9098 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)9099 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
9100 uint block_len_arg, bool using_trans)
9101 :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
9102 using_trans)
9103 {
9104 file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
9105 }
9106 #endif
9107
9108
9109 Begin_load_query_log_event::
Begin_load_query_log_event(const char * buf,uint len,const Format_description_log_event * desc_event)9110 Begin_load_query_log_event(const char* buf, uint len,
9111 const Format_description_log_event* desc_event)
9112 :Append_block_log_event(buf, len, desc_event)
9113 {
9114 }
9115
9116
9117 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_create_or_append() const9118 int Begin_load_query_log_event::get_create_or_append() const
9119 {
9120 return 1; /* create the file */
9121 }
9122 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9123
9124
9125 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9126 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)9127 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
9128 {
9129 /*
9130 If the slave skip counter is 1, then we should not start executing
9131 on the next event.
9132 */
9133 return continue_group(rli);
9134 }
9135 #endif
9136
9137
9138 /**************************************************************************
9139 Execute_load_query_log_event methods
9140 **************************************************************************/
9141
9142
9143 #ifndef MYSQL_CLIENT
9144 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 immediate,bool suppress_use,int errcode)9145 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
9146 ulong query_length_arg, uint fn_pos_start_arg,
9147 uint fn_pos_end_arg,
9148 enum_load_dup_handling dup_handling_arg,
9149 bool using_trans, bool immediate, bool suppress_use,
9150 int errcode):
9151 Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
9152 suppress_use, errcode),
9153 file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
9154 fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
9155 {
9156 }
9157 #endif /* !MYSQL_CLIENT */
9158
9159
9160 Execute_load_query_log_event::
Execute_load_query_log_event(const char * buf,uint event_len,const Format_description_log_event * desc_event)9161 Execute_load_query_log_event(const char* buf, uint event_len,
9162 const Format_description_log_event* desc_event):
9163 Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
9164 file_id(0), fn_pos_start(0), fn_pos_end(0)
9165 {
9166 if (!Query_log_event::is_valid())
9167 return;
9168
9169 buf+= desc_event->common_header_len;
9170
9171 fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
9172 fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
9173 dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
9174
9175 if (fn_pos_start > q_len || fn_pos_end > q_len ||
9176 dup_handling > LOAD_DUP_REPLACE)
9177 return;
9178
9179 file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
9180 }
9181
9182
get_post_header_size_for_derived()9183 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
9184 {
9185 return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
9186 }
9187
9188
9189 #ifndef MYSQL_CLIENT
9190 bool
write_post_header_for_derived(IO_CACHE * file)9191 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
9192 {
9193 uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
9194 int4store(buf, file_id);
9195 int4store(buf + 4, fn_pos_start);
9196 int4store(buf + 4 + 4, fn_pos_end);
9197 *(buf + 4 + 4 + 4)= (uchar) dup_handling;
9198 return wrapper_my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
9199 }
9200 #endif
9201
9202
9203 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)9204 void Execute_load_query_log_event::print(FILE* file,
9205 PRINT_EVENT_INFO* print_event_info)
9206 {
9207 print(file, print_event_info, 0);
9208 }
9209
9210 /**
9211 Prints the query as LOAD DATA LOCAL and with rewritten filename.
9212 */
print(FILE * file,PRINT_EVENT_INFO * print_event_info,const char * local_fname)9213 void Execute_load_query_log_event::print(FILE* file,
9214 PRINT_EVENT_INFO* print_event_info,
9215 const char *local_fname)
9216 {
9217 IO_CACHE *const head= &print_event_info->head_cache;
9218
9219 print_query_header(head, print_event_info);
9220 /**
9221 reduce the size of io cache so that the write function is called
9222 for every call to my_b_printf().
9223 */
9224 DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
9225 {head->write_pos= head->write_end;
9226 DBUG_SET("+d,simulate_file_write_error");});
9227
9228 if (local_fname)
9229 {
9230 my_b_write(head, (uchar*) query, fn_pos_start);
9231 my_b_printf(head, " LOCAL INFILE ");
9232 pretty_print_str(head, local_fname, strlen(local_fname));
9233
9234 if (dup_handling == LOAD_DUP_REPLACE)
9235 my_b_printf(head, " REPLACE");
9236 my_b_printf(head, " INTO");
9237 my_b_write(head, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
9238 my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9239 }
9240 else
9241 {
9242 my_b_write(head, (uchar*) query, q_len);
9243 my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9244 }
9245
9246 if (!print_event_info->short_form)
9247 my_b_printf(head, "# file_id: %d \n", file_id);
9248 }
9249 #endif
9250
9251
9252 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9253 int Execute_load_query_log_event::pack_info(Protocol *protocol)
9254 {
9255 char *buf, *pos;
9256 if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
9257 MYF(MY_WME))))
9258 return 1;
9259 pos= buf;
9260 if (db && db_len)
9261 {
9262 /*
9263 Statically allocates room to store '\0' and an identifier
9264 that may have NAME_LEN * 2 due to quoting and there are
9265 two quoting characters that wrap them.
9266 */
9267 char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
9268 size_t size= 0;
9269 size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
9270 pos= strmov(buf, "use ");
9271 memcpy(pos, quoted_db, size);
9272 pos= strmov(pos + size, "; ");
9273 }
9274 if (query && q_len)
9275 {
9276 memcpy(pos, query, q_len);
9277 pos+= q_len;
9278 }
9279 pos= strmov(pos, " ;file_id=");
9280 pos= int10_to_str((long) file_id, pos, 10);
9281 protocol->store(buf, pos-buf, &my_charset_bin);
9282 my_free(buf);
9283 return 0;
9284 }
9285
9286
9287 int
do_apply_event(Relay_log_info const * rli)9288 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
9289 {
9290 char *p;
9291 char *buf;
9292 char *fname;
9293 char *fname_end;
9294 int error;
9295
9296 buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
9297 (FN_REFLEN + TEMP_FILE_MAX_LEN) + 10 + 8 + 5, MYF(MY_WME));
9298
9299 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
9300
9301 /* Replace filename and LOCAL keyword in query before executing it */
9302 if (buf == NULL)
9303 {
9304 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9305 ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
9306 return 1;
9307 }
9308
9309 p= buf;
9310 memcpy(p, query, fn_pos_start);
9311 p+= fn_pos_start;
9312 fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
9313 p= slave_load_file_stem(p, file_id, server_id, ".data");
9314 fname_end= p= strend(p); // Safer than p=p+5
9315 *(p++)='\'';
9316 switch (dup_handling) {
9317 case LOAD_DUP_IGNORE:
9318 p= strmake(p, STRING_WITH_LEN(" IGNORE"));
9319 break;
9320 case LOAD_DUP_REPLACE:
9321 p= strmake(p, STRING_WITH_LEN(" REPLACE"));
9322 break;
9323 default:
9324 /* Ordinary load data */
9325 break;
9326 }
9327 p= strmake(p, STRING_WITH_LEN(" INTO "));
9328 p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
9329
9330 error= Query_log_event::do_apply_event(rli, buf, p-buf);
9331
9332 /* Forging file name for deletion in same buffer */
9333 *fname_end= 0;
9334
9335 /*
9336 If there was an error the slave is going to stop, leave the
9337 file so that we can re-execute this event at START SLAVE.
9338 */
9339 if (!error)
9340 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9341
9342 my_free(buf);
9343 return error;
9344 }
9345 #endif
9346
9347
9348 /**************************************************************************
9349 sql_ex_info methods
9350 **************************************************************************/
9351
9352 /*
9353 sql_ex_info::write_data()
9354 */
9355
write_data(IO_CACHE * file)9356 bool sql_ex_info::write_data(IO_CACHE* file)
9357 {
9358 if (new_format())
9359 {
9360 return (write_str_at_most_255_bytes(file, field_term, (uint) field_term_len) ||
9361 write_str_at_most_255_bytes(file, enclosed, (uint) enclosed_len) ||
9362 write_str_at_most_255_bytes(file, line_term, (uint) line_term_len) ||
9363 write_str_at_most_255_bytes(file, line_start, (uint) line_start_len) ||
9364 write_str_at_most_255_bytes(file, escaped, (uint) escaped_len) ||
9365 my_b_safe_write(file,(uchar*) &opt_flags,1));
9366 }
9367 else
9368 {
9369 /**
9370 @todo This is sensitive to field padding. We should write a
9371 char[7], not an old_sql_ex. /sven
9372 */
9373 old_sql_ex old_ex;
9374 old_ex.field_term= *field_term;
9375 old_ex.enclosed= *enclosed;
9376 old_ex.line_term= *line_term;
9377 old_ex.line_start= *line_start;
9378 old_ex.escaped= *escaped;
9379 old_ex.opt_flags= opt_flags;
9380 old_ex.empty_flags=empty_flags;
9381 return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
9382 }
9383 }
9384
9385
9386 /*
9387 sql_ex_info::init()
9388 */
9389
init(const char * buf,const char * buf_end,bool use_new_format)9390 const char *sql_ex_info::init(const char *buf, const char *buf_end,
9391 bool use_new_format)
9392 {
9393 cached_new_format = use_new_format;
9394 if (use_new_format)
9395 {
9396 empty_flags=0;
9397 /*
9398 The code below assumes that buf will not disappear from
9399 under our feet during the lifetime of the event. This assumption
9400 holds true in the slave thread if the log is in new format, but is not
9401 the case when we have old format because we will be reusing net buffer
9402 to read the actual file before we write out the Create_file event.
9403 */
9404 if (read_str_at_most_255_bytes(&buf, buf_end, &field_term, &field_term_len) ||
9405 read_str_at_most_255_bytes(&buf, buf_end, &enclosed, &enclosed_len) ||
9406 read_str_at_most_255_bytes(&buf, buf_end, &line_term, &line_term_len) ||
9407 read_str_at_most_255_bytes(&buf, buf_end, &line_start, &line_start_len) ||
9408 read_str_at_most_255_bytes(&buf, buf_end, &escaped, &escaped_len))
9409 return 0;
9410 opt_flags = *buf++;
9411 }
9412 else
9413 {
9414 field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
9415 field_term = buf++; // Use first byte in string
9416 enclosed= buf++;
9417 line_term= buf++;
9418 line_start= buf++;
9419 escaped= buf++;
9420 opt_flags = *buf++;
9421 empty_flags= *buf++;
9422 if (empty_flags & FIELD_TERM_EMPTY)
9423 field_term_len=0;
9424 if (empty_flags & ENCLOSED_EMPTY)
9425 enclosed_len=0;
9426 if (empty_flags & LINE_TERM_EMPTY)
9427 line_term_len=0;
9428 if (empty_flags & LINE_START_EMPTY)
9429 line_start_len=0;
9430 if (empty_flags & ESCAPED_EMPTY)
9431 escaped_len=0;
9432 }
9433 return buf;
9434 }
9435
9436 #ifndef DBUG_OFF
9437 #ifndef MYSQL_CLIENT
9438 static uchar dbug_extra_row_data_val= 0;
9439
9440 /**
9441 set_extra_data
9442
9443 Called during self-test to generate various
9444 self-consistent binlog row event extra
9445 thread data structures which can be checked
9446 when reading the binlog.
9447
9448 @param arr Buffer to use
9449 */
set_extra_data(uchar * arr)9450 const uchar* set_extra_data(uchar* arr)
9451 {
9452 uchar val= (dbug_extra_row_data_val++) %
9453 (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
9454 arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
9455 arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
9456 for (uchar i=0; i<val; i++)
9457 arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
9458
9459 return arr;
9460 }
9461
9462 #endif // #ifndef MYSQL_CLIENT
9463
9464 /**
9465 check_extra_data
9466
9467 Called during self-test to check that
9468 binlog row event extra data is self-
9469 consistent as defined by the set_extra_data
9470 function above.
9471
9472 Will assert(false) if not.
9473
9474 @param extra_row_data
9475 */
check_extra_data(uchar * extra_row_data)9476 void check_extra_data(uchar* extra_row_data)
9477 {
9478 assert(extra_row_data);
9479 uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
9480 uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
9481 assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
9482 for (uint16 i= 0; i < val; i++)
9483 {
9484 assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
9485 }
9486 }
9487
9488 #endif // #ifndef DBUG_OFF
9489
9490 /**************************************************************************
9491 Rows_log_event member functions
9492 **************************************************************************/
9493
9494 #ifndef MYSQL_CLIENT
Rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,MY_BITMAP const * cols,bool using_trans,Log_event_type event_type,const uchar * extra_row_info)9495 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, const Table_id& tid,
9496 MY_BITMAP const *cols, bool using_trans,
9497 Log_event_type event_type,
9498 const uchar* extra_row_info)
9499 : Log_event(thd_arg, 0,
9500 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
9501 Log_event::EVENT_STMT_CACHE,
9502 Log_event::EVENT_NORMAL_LOGGING),
9503 m_row_count(0),
9504 m_table(tbl_arg),
9505 m_table_id(tid),
9506 m_width(tbl_arg ? tbl_arg->s->fields : 1),
9507 m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
9508 m_type(event_type), m_extra_row_data(0)
9509 #ifdef HAVE_REPLICATION
9510 , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9511 m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9512 #endif
9513 {
9514 DBUG_ASSERT(tbl_arg && tbl_arg->s && tid.is_valid());
9515
9516 if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
9517 set_flags(NO_FOREIGN_KEY_CHECKS_F);
9518 if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
9519 set_flags(RELAXED_UNIQUE_CHECKS_F);
9520 #ifndef DBUG_OFF
9521 uchar extra_data[255];
9522 DBUG_EXECUTE_IF("extra_row_data_set",
9523 /* Set extra row data to a known value */
9524 extra_row_info = set_extra_data(extra_data););
9525 #endif
9526 if (extra_row_info)
9527 {
9528 /* Copy Extra data from thd into new event */
9529 uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
9530 assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
9531
9532 m_extra_row_data= (uchar*) my_malloc(extra_data_len, MYF(MY_WME));
9533
9534 if (likely(m_extra_row_data != NULL))
9535 {
9536 memcpy(m_extra_row_data, extra_row_info,
9537 extra_data_len);
9538 }
9539 }
9540
9541 /* if bitmap_init fails, caught in is_valid() */
9542 if (likely(!bitmap_init(&m_cols,
9543 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9544 m_width,
9545 false)))
9546 {
9547 /* Cols can be zero if this is a dummy binrows event */
9548 if (likely(cols != NULL))
9549 {
9550 memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
9551 create_last_word_mask(&m_cols);
9552 }
9553 }
9554 else
9555 {
9556 // Needed because bitmap_init() does not set it to null on failure
9557 m_cols.bitmap= 0;
9558 }
9559 }
9560 #endif
9561
Rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)9562 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
9563 const Format_description_log_event
9564 *description_event)
9565 : Log_event(buf, description_event),
9566 m_row_count(0),
9567 #ifndef MYSQL_CLIENT
9568 m_table(NULL),
9569 #endif
9570 m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
9571 m_extra_row_data(0)
9572 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9573 , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9574 m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9575 #endif
9576 {
9577 DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
9578 uint8 const common_header_len= description_event->common_header_len;
9579 Log_event_type event_type= (Log_event_type) buf[EVENT_TYPE_OFFSET];
9580 m_type= event_type;
9581
9582 uint8 const post_header_len= description_event->post_header_len[event_type-1];
9583
9584 DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
9585 "post_header_len: %d",
9586 event_len, common_header_len,
9587 post_header_len));
9588
9589 const char *post_start= buf + common_header_len;
9590 post_start+= RW_MAPID_OFFSET;
9591 if (post_header_len == 6)
9592 {
9593 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
9594 m_table_id= uint4korr(post_start);
9595 post_start+= 4;
9596 }
9597 else
9598 {
9599 m_table_id= uint6korr(post_start);
9600 post_start+= RW_FLAGS_OFFSET;
9601 }
9602
9603 m_flags= uint2korr(post_start);
9604 post_start+= 2;
9605
9606 uint16 var_header_len= 0;
9607 if (post_header_len == ROWS_HEADER_LEN_V2)
9608 {
9609 /*
9610 Have variable length header, check length,
9611 which includes length bytes
9612 */
9613 var_header_len= uint2korr(post_start);
9614 /* Check length and also avoid out of buffer read */
9615 if (var_header_len < 2 ||
9616 event_len < static_cast<unsigned int>(var_header_len +
9617 (post_start - buf)))
9618 {
9619 m_cols.bitmap= NULL;
9620 DBUG_VOID_RETURN;
9621 }
9622
9623 var_header_len-= 2;
9624
9625 /* Iterate over var-len header, extracting 'chunks' */
9626 const char* start= post_start + 2;
9627 const char* end= start + var_header_len;
9628 for (const char* pos= start; pos < end;)
9629 {
9630 switch(*pos++)
9631 {
9632 case RW_V_EXTRAINFO_TAG:
9633 {
9634 /* Have an 'extra info' section, read it in */
9635 assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
9636 uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
9637 assert((end - pos) >= infoLen);
9638 /* Just store/use the first tag of this type, skip others */
9639 if (likely(!m_extra_row_data))
9640 {
9641 m_extra_row_data= (uchar*) my_malloc(infoLen,
9642 MYF(MY_WME));
9643 if (likely(m_extra_row_data != NULL))
9644 {
9645 memcpy(m_extra_row_data, pos, infoLen);
9646 }
9647 DBUG_EXECUTE_IF("extra_row_data_check",
9648 /* Check extra data has expected value */
9649 check_extra_data(m_extra_row_data););
9650 }
9651 pos+= infoLen;
9652 break;
9653 }
9654 default:
9655 /* Unknown code, we will not understand anything further here */
9656 pos= end; /* Break loop */
9657 }
9658 }
9659 }
9660
9661 uchar const *const var_start=
9662 (const uchar *)buf + common_header_len + post_header_len + var_header_len;
9663 uchar const *const ptr_width= var_start;
9664 uchar *ptr_after_width= (uchar*) ptr_width;
9665 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9666 m_width = net_field_length(&ptr_after_width);
9667 DBUG_PRINT("debug", ("m_width=%lu", m_width));
9668 /* Avoid reading out of buffer */
9669 if (static_cast<unsigned int>((ptr_after_width +
9670 (m_width + 7) / 8) -
9671 (uchar*)buf) > event_len)
9672 {
9673 m_cols.bitmap= NULL;
9674 DBUG_VOID_RETURN;
9675 }
9676
9677 /* if bitmap_init fails, catched in is_valid() */
9678 if (likely(!bitmap_init(&m_cols,
9679 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9680 m_width,
9681 false)))
9682 {
9683 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9684 memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
9685 create_last_word_mask(&m_cols);
9686 ptr_after_width+= (m_width + 7) / 8;
9687 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
9688 }
9689 else
9690 {
9691 // Needed because bitmap_init() does not set it to null on failure
9692 m_cols.bitmap= NULL;
9693 DBUG_VOID_RETURN;
9694 }
9695
9696 m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
9697
9698 if ((event_type == UPDATE_ROWS_EVENT) ||
9699 (event_type == UPDATE_ROWS_EVENT_V1))
9700 {
9701 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9702
9703 /* if bitmap_init fails, caught in is_valid() */
9704 if (likely(!bitmap_init(&m_cols_ai,
9705 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
9706 m_width,
9707 false)))
9708 {
9709 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9710 memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
9711 create_last_word_mask(&m_cols_ai);
9712 ptr_after_width+= (m_width + 7) / 8;
9713 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
9714 no_bytes_in_map(&m_cols_ai));
9715 }
9716 else
9717 {
9718 // Needed because bitmap_init() does not set it to null on failure
9719 m_cols_ai.bitmap= 0;
9720 DBUG_VOID_RETURN;
9721 }
9722 }
9723
9724 const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
9725
9726 size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
9727 if (read_size > event_len)
9728 {
9729 DBUG_VOID_RETURN;
9730 }
9731
9732 size_t const data_size= event_len - read_size;
9733 DBUG_PRINT("info",("m_table_id: %llu m_flags: %d m_width: %lu data_size: %lu",
9734 m_table_id.id(), m_flags, m_width, (ulong) data_size));
9735
9736 m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
9737 if (likely((bool)m_rows_buf))
9738 {
9739 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9740 m_curr_row= m_rows_buf;
9741 #endif
9742 m_rows_end= m_rows_buf + data_size;
9743 m_rows_cur= m_rows_end;
9744 memcpy(m_rows_buf, ptr_rows_data, data_size);
9745 }
9746 else
9747 m_cols.bitmap= 0; // to not free it
9748
9749 DBUG_VOID_RETURN;
9750 }
9751
~Rows_log_event()9752 Rows_log_event::~Rows_log_event()
9753 {
9754 if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
9755 m_cols.bitmap= 0; // so no my_free in bitmap_free
9756 bitmap_free(&m_cols); // To pair with bitmap_init().
9757 my_free(m_rows_buf);
9758 my_free(m_extra_row_data);
9759 }
9760
get_data_size()9761 int Rows_log_event::get_data_size()
9762 {
9763 int const general_type_code= get_general_type_code();
9764
9765 uchar buf[sizeof(m_width) + 1];
9766 uchar *end= net_store_length(buf, m_width);
9767
9768 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9769 return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
9770 (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
9771 (m_rows_cur - m_rows_buf););
9772
9773 int data_size= 0;
9774 bool is_v2_event= get_type_code() > DELETE_ROWS_EVENT_V1;
9775 if (is_v2_event)
9776 {
9777 data_size= ROWS_HEADER_LEN_V2 +
9778 (m_extra_row_data ?
9779 RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
9780 0);
9781 }
9782 else
9783 {
9784 data_size= ROWS_HEADER_LEN_V1;
9785 }
9786 data_size+= no_bytes_in_map(&m_cols);
9787 data_size+= (uint) (end - buf);
9788
9789 if (general_type_code == UPDATE_ROWS_EVENT)
9790 data_size+= no_bytes_in_map(&m_cols_ai);
9791
9792 data_size+= (uint) (m_rows_cur - m_rows_buf);
9793 return data_size;
9794 }
9795
9796
9797 #ifndef MYSQL_CLIENT
do_add_row_data(uchar * row_data,size_t length)9798 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
9799 {
9800 /*
9801 When the table has a primary key, we would probably want, by default, to
9802 log only the primary key value instead of the entire "before image". This
9803 would save binlog space. TODO
9804 */
9805 DBUG_ENTER("Rows_log_event::do_add_row_data");
9806 DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data,
9807 (ulong) length));
9808
9809 /*
9810 If length is zero, there is nothing to write, so we just
9811 return. Note that this is not an optimization, since calling
9812 realloc() with size 0 means free().
9813 */
9814 if (length == 0)
9815 {
9816 m_row_count++;
9817 DBUG_RETURN(0);
9818 }
9819
9820 /*
9821 Don't print debug messages when running valgrind since they can
9822 trigger false warnings.
9823 */
9824 #ifndef HAVE_purify
9825 DBUG_DUMP("row_data", row_data, min<size_t>(length, 32));
9826 #endif
9827
9828 DBUG_ASSERT(m_rows_buf <= m_rows_cur);
9829 DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
9830 DBUG_ASSERT(m_rows_cur <= m_rows_end);
9831
9832 /* The cast will always work since m_rows_cur <= m_rows_end */
9833 if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
9834 {
9835 size_t const block_size= 1024;
9836 ulong cur_size= m_rows_cur - m_rows_buf;
9837 DBUG_EXECUTE_IF("simulate_too_big_row_case1",
9838 cur_size= UINT_MAX32 - (block_size * 10);
9839 length= UINT_MAX32 - (block_size * 10););
9840 DBUG_EXECUTE_IF("simulate_too_big_row_case2",
9841 cur_size= UINT_MAX32 - (block_size * 10);
9842 length= block_size * 10;);
9843 DBUG_EXECUTE_IF("simulate_too_big_row_case3",
9844 cur_size= block_size * 10;
9845 length= UINT_MAX32 - (block_size * 10););
9846 DBUG_EXECUTE_IF("simulate_too_big_row_case4",
9847 cur_size= UINT_MAX32 - (block_size * 10);
9848 length= (block_size * 10) - block_size + 1;);
9849 ulong remaining_space= UINT_MAX32 - cur_size;
9850 /* Check that the new data fits within remaining space and we can add
9851 block_size without wrapping.
9852 */
9853 if (length > remaining_space ||
9854 ((length + block_size) > remaining_space))
9855 {
9856 sql_print_error("The row data is greater than 4GB, which is too big to "
9857 "write to the binary log.");
9858 DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
9859 }
9860 ulong const new_alloc=
9861 block_size * ((cur_size + length + block_size - 1) / block_size);
9862
9863 uchar* const new_buf=
9864 (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
9865 MYF(MY_ALLOW_ZERO_PTR|MY_WME));
9866 if (unlikely(!new_buf))
9867 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
9868
9869 /* If the memory moved, we need to move the pointers */
9870 if (new_buf != m_rows_buf)
9871 {
9872 m_rows_buf= new_buf;
9873 m_rows_cur= m_rows_buf + cur_size;
9874 }
9875
9876 /*
9877 The end pointer should always be changed to point to the end of
9878 the allocated memory.
9879 */
9880 m_rows_end= m_rows_buf + new_alloc;
9881 }
9882
9883 DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
9884 memcpy(m_rows_cur, row_data, length);
9885 m_rows_cur+= length;
9886 m_row_count++;
9887 DBUG_RETURN(0);
9888 }
9889 #endif
9890
9891 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9892
9893 /**
9894 Checks if any of the columns in the given table is
9895 signaled in the bitmap.
9896
9897 For each column in the given table checks if it is
9898 signaled in the bitmap. This is most useful when deciding
9899 whether a before image (BI) can be used or not for
9900 searching a row. If no column is signaled, then the
9901 image cannot be used for searching a record (regardless
9902 of using position(), index scan or table scan). Here is
9903 an example:
9904
9905 MASTER> SET @@binlog_row_image='MINIMAL';
9906 MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9907 SLAVE> CREATE TABLE t1 (a int, b int);
9908 MASTER> INSERT INTO t1 VALUES (1,2,3);
9909 MASTER> UPDATE t1 SET a=2 WHERE b=2;
9910
9911 For the update statement only the PK (column c) is
9912 logged in the before image (BI). As such, given that
9913 the slave has no column c, it will not be able to
9914 find the row, because BI has no values for the columns
9915 the slave knows about (column a and b).
9916
9917 @param table the table reference on the slave.
9918 @param cols the bitmap signaling columns available in
9919 the BI.
9920
9921 @return TRUE if BI contains usable colums for searching,
9922 FALSE otherwise.
9923 */
9924 static
is_any_column_signaled_for_table(TABLE * table,MY_BITMAP * cols)9925 my_bool is_any_column_signaled_for_table(TABLE *table, MY_BITMAP *cols)
9926 {
9927 DBUG_ENTER("is_any_column_signaled_for_table");
9928
9929 for (Field **ptr= table->field ;
9930 *ptr && ((*ptr)->field_index < cols->n_bits);
9931 ptr++)
9932 {
9933 if (bitmap_is_set(cols, (*ptr)->field_index))
9934 DBUG_RETURN(TRUE);
9935 }
9936
9937 DBUG_RETURN (FALSE);
9938 }
9939
9940 /**
9941 Checks if the fields in the given key are signaled in
9942 the bitmap.
9943
9944 Validates whether the before image is usable for the
9945 given key. It can be the case that the before image
9946 does not contain values for the key (eg, master was
9947 using 'minimal' option for image logging and slave has
9948 different index structure on the table). Here is an
9949 example:
9950
9951 MASTER> SET @@binlog_row_image='MINIMAL';
9952 MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9953 SLAVE> CREATE TABLE t1 (a int, b int, c int, key(a,c));
9954 MASTER> INSERT INTO t1 VALUES (1,2,3);
9955 MASTER> UPDATE t1 SET a=2 WHERE b=2;
9956
9957 When finding the row on the slave, one cannot use the
9958 index (a,c) to search for the row, because there is only
9959 data in the before image for column c. This function
9960 checks the fields needed for a given key and searches
9961 the bitmap to see if all the fields required are
9962 signaled.
9963
9964 @param keyinfo reference to key.
9965 @param cols the bitmap signaling which columns
9966 have available data.
9967
9968 @return TRUE if all fields are signaled in the bitmap
9969 for the given key, FALSE otherwise.
9970 */
9971 static
are_all_columns_signaled_for_key(KEY * keyinfo,MY_BITMAP * cols)9972 my_bool are_all_columns_signaled_for_key(KEY *keyinfo, MY_BITMAP *cols)
9973 {
9974 DBUG_ENTER("are_all_columns_signaled_for_key");
9975
9976 for (uint i=0 ; i < keyinfo->user_defined_key_parts ;i++)
9977 {
9978 uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
9979 if (fieldnr >= cols->n_bits ||
9980 !bitmap_is_set(cols, fieldnr))
9981 DBUG_RETURN(FALSE);
9982 }
9983
9984 DBUG_RETURN(TRUE);
9985 }
9986
9987 /**
9988 Searches the table for a given key that can be used
9989 according to the existing values, ie, columns set
9990 in the bitmap.
9991
9992 The caller can specify which type of key to find by
9993 setting the following flags in the key_type parameter:
9994
9995 - PRI_KEY_FLAG
9996 Returns the primary key.
9997
9998 - UNIQUE_KEY_FLAG
9999 Returns a unique key (flagged with HA_NOSAME)
10000
10001 - MULTIPLE_KEY_FLAG
10002 Returns a key that is not unique (flagged with HA_NOSAME
10003 and without HA_NULL_PART_KEY) nor PK.
10004
10005 The above flags can be used together, in which case, the
10006 search is conducted in the above listed order. Eg, the
10007 following flag:
10008
10009 (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG)
10010
10011 means that a primary key is returned if it is suitable. If
10012 not then the unique keys are searched. If no unique key is
10013 suitable, then the keys are searched. Finally, if no key
10014 is suitable, MAX_KEY is returned.
10015
10016 @param table reference to the table.
10017 @param bi_cols a bitmap that filters out columns that should
10018 not be considered while searching the key.
10019 Columns that should be considered are set.
10020 @param key_type the type of key to search for.
10021
10022 @return MAX_KEY if no key, according to the key_type specified
10023 is suitable. Returns the key otherwise.
10024
10025 */
10026 static
10027 uint
search_key_in_table(TABLE * table,MY_BITMAP * bi_cols,uint key_type)10028 search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type)
10029 {
10030 DBUG_ENTER("search_key_in_table");
10031
10032 KEY *keyinfo;
10033 uint res= MAX_KEY;
10034 uint key;
10035
10036 if (key_type & PRI_KEY_FLAG &&
10037 (table->s->primary_key < MAX_KEY))
10038 {
10039 DBUG_PRINT("debug", ("Searching for PK"));
10040 keyinfo= table->s->key_info + (uint) table->s->primary_key;
10041 if (are_all_columns_signaled_for_key(keyinfo, bi_cols))
10042 DBUG_RETURN(table->s->primary_key);
10043 }
10044
10045 DBUG_PRINT("debug", ("Unique keys count: %u", table->s->uniques));
10046
10047 if (key_type & UNIQUE_KEY_FLAG && table->s->uniques)
10048 {
10049 DBUG_PRINT("debug", ("Searching for UK"));
10050 for (key=0,keyinfo= table->key_info ;
10051 (key < table->s->keys) && (res == MAX_KEY);
10052 key++,keyinfo++)
10053 {
10054 /*
10055 - Unique keys cannot be disabled, thence we skip the check.
10056 - Skip unique keys with nullable parts
10057 - Skip primary keys
10058 */
10059 if (!((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10060 (key == table->s->primary_key))
10061 continue;
10062 res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10063 key : MAX_KEY;
10064
10065 if (res < MAX_KEY)
10066 DBUG_RETURN(res);
10067 }
10068 DBUG_PRINT("debug", ("UK has NULLABLE parts or not all columns signaled."));
10069 }
10070
10071 if (key_type & MULTIPLE_KEY_FLAG && table->s->keys)
10072 {
10073 DBUG_PRINT("debug", ("Searching for K."));
10074 for (key=0,keyinfo= table->key_info ;
10075 (key < table->s->keys) && (res == MAX_KEY);
10076 key++,keyinfo++)
10077 {
10078 /*
10079 - Skip innactive keys
10080 - Skip unique keys without nullable parts
10081 - Skip indices that do not support ha_index_next() e.g. full-text
10082 - Skip primary keys
10083 */
10084 if (!(table->s->keys_in_use.is_set(key)) ||
10085 ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10086 !(table->file->index_flags(key, 0, true) & HA_READ_NEXT) ||
10087 (key == table->s->primary_key))
10088 continue;
10089
10090 res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10091 key : MAX_KEY;
10092
10093 if (res < MAX_KEY)
10094 DBUG_RETURN(res);
10095 }
10096 DBUG_PRINT("debug", ("Not all columns signaled for K."));
10097 }
10098
10099 DBUG_RETURN(res);
10100 }
10101
10102 void
decide_row_lookup_algorithm_and_key()10103 Rows_log_event::decide_row_lookup_algorithm_and_key()
10104 {
10105
10106 DBUG_ENTER("decide_row_lookup_algorithm_and_key");
10107
10108 /*
10109 Decision table:
10110 - I --> Index scan / search
10111 - T --> Table scan
10112 - Hi --> Hash over index
10113 - Ht --> Hash over the entire table
10114
10115 |--------------+-----------+------+------+------|
10116 | Index\Option | I , T , H | I, T | I, H | T, H |
10117 |--------------+-----------+------+------+------|
10118 | PK / UK | I | I | I | Hi |
10119 | K | Hi | I | Hi | Hi |
10120 | No Index | Ht | T | Ht | Ht |
10121 |--------------+-----------+------+------+------|
10122
10123 */
10124
10125 TABLE *table= this->m_table;
10126 uint event_type= this->get_general_type_code();
10127 MY_BITMAP *cols= &this->m_cols;
10128 this->m_rows_lookup_algorithm= ROW_LOOKUP_NOT_NEEDED;
10129 this->m_key_index= MAX_KEY;
10130 this->m_key_info= NULL;
10131
10132 if (event_type == WRITE_ROWS_EVENT) // row lookup not needed
10133 DBUG_VOID_RETURN;
10134
10135 if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN))
10136 goto TABLE_OR_INDEX_HASH_SCAN;
10137
10138 /* PK or UK => use LOOKUP_INDEX_SCAN */
10139 this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG));
10140 if (this->m_key_index != MAX_KEY)
10141 {
10142 DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10143 this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10144 goto end;
10145 }
10146
10147 TABLE_OR_INDEX_HASH_SCAN:
10148
10149 /*
10150 NOTE: Engines like Blackhole cannot use HASH_SCAN, because
10151 they do not syncronize reads .
10152 */
10153 if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_HASH_SCAN) ||
10154 (table->file->ha_table_flags() & HA_READ_OUT_OF_SYNC))
10155 goto TABLE_OR_INDEX_FULL_SCAN;
10156
10157 /* search for a key to see if we can narrow the lookup domain further. */
10158 this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10159 this->m_rows_lookup_algorithm= ROW_LOOKUP_HASH_SCAN;
10160 if (m_key_index < MAX_KEY)
10161 m_distinct_key_spare_buf= (uchar*) thd->alloc(table->key_info[m_key_index].key_length);
10162 DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - HASH_SCAN"));
10163 goto end;
10164
10165 TABLE_OR_INDEX_FULL_SCAN:
10166
10167 this->m_key_index= MAX_KEY;
10168
10169 /* If we can use an index, try to narrow the scan a bit further. */
10170 if (slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN)
10171 this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10172
10173 if (this->m_key_index != MAX_KEY)
10174 {
10175 DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10176 this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10177 }
10178 else
10179 {
10180 DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - TABLE_SCAN"));
10181 this->m_rows_lookup_algorithm= ROW_LOOKUP_TABLE_SCAN;
10182 }
10183
10184 end:
10185
10186 /* m_key_index is ready, set m_key_info now. */
10187 m_key_info= m_table->key_info + m_key_index;
10188 /*
10189 m_key_info will influence key comparison code in HASH_SCAN mode,
10190 so the m_distinct_keys set should still be empty.
10191 */
10192 DBUG_ASSERT(m_distinct_keys.empty());
10193
10194 #ifndef DBUG_OFF
10195 const char* s= ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
10196 ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
10197 "INDEX_SCAN"));
10198
10199 // only for testing purposes
10200 slave_rows_last_search_algorithm_used= m_rows_lookup_algorithm;
10201 DBUG_PRINT("debug", ("Row lookup method: %s", s));
10202 #endif
10203
10204 DBUG_VOID_RETURN;
10205 }
10206
10207 /*
10208 Encapsulates the operations to be done before applying
10209 row events for update and delete.
10210
10211 @ret value error code
10212 0 success
10213 */
10214 int
row_operations_scan_and_key_setup()10215 Rows_log_event::row_operations_scan_and_key_setup()
10216 {
10217 int error= 0;
10218 DBUG_ENTER("Row_log_event::row_operations_scan_and_key_setup");
10219
10220 /*
10221 Prepare memory structures for search operations. If
10222 search is performed:
10223
10224 1. using hash search => initialize the hash
10225 2. using key => decide on key to use and allocate mem structures
10226 3. using table scan => do nothing
10227 */
10228 decide_row_lookup_algorithm_and_key();
10229
10230 switch (m_rows_lookup_algorithm)
10231 {
10232 case ROW_LOOKUP_HASH_SCAN:
10233 {
10234 if (m_hash.init())
10235 error= HA_ERR_OUT_OF_MEM;
10236 goto err;
10237 }
10238 case ROW_LOOKUP_INDEX_SCAN:
10239 {
10240 DBUG_ASSERT (m_key_index < MAX_KEY);
10241 // Allocate buffer for key searches
10242 m_key= (uchar*)my_malloc(m_key_info->key_length, MYF(MY_WME));
10243 if (!m_key)
10244 error= HA_ERR_OUT_OF_MEM;
10245 goto err;
10246 }
10247 case ROW_LOOKUP_TABLE_SCAN:
10248 default: break;
10249 }
10250 err:
10251 DBUG_RETURN(error);
10252 }
10253
10254 /*
10255 Encapsulates the operations to be done after applying
10256 row events for update and delete.
10257
10258 @ret value error code
10259 0 success
10260 */
10261
10262 int
row_operations_scan_and_key_teardown(int error)10263 Rows_log_event::row_operations_scan_and_key_teardown(int error)
10264 {
10265 DBUG_ENTER("Rows_log_event::row_operations_scan_and_key_teardown");
10266
10267 DBUG_ASSERT(!m_table->file->inited);
10268 switch (m_rows_lookup_algorithm)
10269 {
10270 case ROW_LOOKUP_HASH_SCAN:
10271 {
10272 m_hash.deinit(); // we don't need the hash anymore.
10273 goto err;
10274 }
10275
10276 case ROW_LOOKUP_INDEX_SCAN:
10277 {
10278 if (m_table->s->keys > 0)
10279 {
10280 my_free(m_key); // Free for multi_malloc
10281 m_key= NULL;
10282 m_key_index= MAX_KEY;
10283 m_key_info= NULL;
10284 }
10285 goto err;
10286 }
10287
10288 case ROW_LOOKUP_TABLE_SCAN:
10289 default: break;
10290 }
10291
10292 err:
10293 m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
10294 DBUG_RETURN(error);
10295 }
10296
10297 /*
10298 Compares table->record[0] and table->record[1]
10299
10300 Returns TRUE if different.
10301 */
record_compare(TABLE * table,MY_BITMAP * cols)10302 static bool record_compare(TABLE *table, MY_BITMAP *cols)
10303 {
10304 DBUG_ENTER("record_compare");
10305
10306 /*
10307 Need to set the X bit and the filler bits in both records since
10308 there are engines that do not set it correctly.
10309
10310 In addition, since MyISAM checks that one hasn't tampered with the
10311 record, it is necessary to restore the old bytes into the record
10312 after doing the comparison.
10313
10314 TODO[record format ndb]: Remove it once NDB returns correct
10315 records. Check that the other engines also return correct records.
10316 */
10317
10318 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10319 DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
10320
10321 bool result= false;
10322 uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
10323
10324 if (table->s->null_bytes > 0)
10325 {
10326 for (int i = 0 ; i < 2 ; ++i)
10327 {
10328 /*
10329 If we have an X bit then we need to take care of it.
10330 */
10331 if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10332 {
10333 saved_x[i]= table->record[i][0];
10334 table->record[i][0]|= 1U;
10335 }
10336
10337 /*
10338 If (last_null_bit_pos == 0 && null_bytes > 1), then:
10339
10340 X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
10341
10342 Ie, the entire byte is used.
10343 */
10344 if (table->s->last_null_bit_pos > 0)
10345 {
10346 saved_filler[i]= table->record[i][table->s->null_bytes - 1];
10347 table->record[i][table->s->null_bytes - 1]|=
10348 256U - (1U << table->s->last_null_bit_pos);
10349 }
10350 }
10351 }
10352
10353 /**
10354 Compare full record only if:
10355 - there are no blob fields (otherwise we would also need
10356 to compare blobs contents as well);
10357 - there are no varchar fields (otherwise we would also need
10358 to compare varchar contents as well);
10359 - there are no null fields, otherwise NULLed fields
10360 contents (i.e., the don't care bytes) may show arbitrary
10361 values, depending on how each engine handles internally.
10362 - if all the bitmap is set (both are full rows)
10363 */
10364 if ((table->s->blob_fields +
10365 table->s->varchar_fields +
10366 table->s->null_fields) == 0 &&
10367 bitmap_is_set_all(cols))
10368 {
10369 result= cmp_record(table,record[1]);
10370 }
10371
10372 /*
10373 Fallback to field-by-field comparison:
10374 1. start by checking if the field is signaled:
10375 2. if it is, first compare the null bit if the field is nullable
10376 3. then compare the contents of the field, if it is not
10377 set to null
10378 */
10379 else
10380 {
10381 for (Field **ptr=table->field ;
10382 *ptr && ((*ptr)->field_index < cols->n_bits) && !result;
10383 ptr++)
10384 {
10385 Field *field= *ptr;
10386 if (bitmap_is_set(cols, field->field_index))
10387 {
10388 /* compare null bit */
10389 if (field->is_null() != field->is_null_in_record(table->record[1]))
10390 result= true;
10391
10392 /* compare content, only if fields are not set to NULL */
10393 else if (!field->is_null())
10394 result= field->cmp_binary_offset(table->s->rec_buff_length);
10395 }
10396 }
10397 }
10398
10399 /*
10400 Restore the saved bytes.
10401
10402 TODO[record format ndb]: Remove this code once NDB returns the
10403 correct record format.
10404 */
10405 if (table->s->null_bytes > 0)
10406 {
10407 for (int i = 0 ; i < 2 ; ++i)
10408 {
10409 if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10410 table->record[i][0]= saved_x[i];
10411
10412 if (table->s->last_null_bit_pos)
10413 table->record[i][table->s->null_bytes - 1]= saved_filler[i];
10414 }
10415 }
10416
10417 DBUG_RETURN(result);
10418 }
10419
do_post_row_operations(Relay_log_info const * rli,int error)10420 void Rows_log_event::do_post_row_operations(Relay_log_info const *rli, int error)
10421 {
10422
10423 /*
10424 If m_curr_row_end was not set during event execution (e.g., because
10425 of errors) we can't proceed to the next row. If the error is transient
10426 (i.e., error==0 at this point) we must call unpack_current_row() to set
10427 m_curr_row_end.
10428 */
10429
10430 DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
10431 (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
10432
10433 if (!m_curr_row_end && !error)
10434 {
10435 const uchar *previous_m_curr_row= m_curr_row;
10436 error= unpack_current_row(rli, &m_cols);
10437
10438 if (!error && previous_m_curr_row == m_curr_row)
10439 {
10440 error= 1;
10441 }
10442 }
10443
10444 // at this moment m_curr_row_end should be set
10445 DBUG_ASSERT(error || m_curr_row_end != NULL);
10446 DBUG_ASSERT(error || m_curr_row <= m_curr_row_end);
10447 DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
10448
10449 m_curr_row= m_curr_row_end;
10450
10451 if (error == 0 && !m_table->file->has_transactions())
10452 {
10453 thd->transaction.all.set_unsafe_rollback_flags(TRUE);
10454 thd->transaction.stmt.set_unsafe_rollback_flags(TRUE);
10455 }
10456 }
10457
handle_idempotent_and_ignored_errors(Relay_log_info const * rli,int * err)10458 int Rows_log_event::handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err)
10459 {
10460 int error= *err;
10461 if (error)
10462 {
10463 int actual_error= convert_handler_error(error, thd, m_table);
10464 bool idempotent_error= (idempotent_error_code(error) &&
10465 (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
10466 bool ignored_error= (idempotent_error == 0 ?
10467 ignored_error_code(actual_error) : 0);
10468
10469 if (idempotent_error || ignored_error)
10470 {
10471 if ( (idempotent_error && log_warnings) ||
10472 (ignored_error && log_warnings > 1) )
10473 slave_rows_error_report(WARNING_LEVEL, error, rli, thd, m_table,
10474 get_type_str(),
10475 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
10476 (ulong) log_pos);
10477 thd->get_stmt_da()->clear_warning_info(thd->query_id);
10478 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
10479 *err= 0;
10480 if (idempotent_error == 0)
10481 return ignored_error;
10482 }
10483 }
10484
10485 return *err;
10486 }
10487
do_apply_row(Relay_log_info const * rli)10488 int Rows_log_event::do_apply_row(Relay_log_info const *rli)
10489 {
10490 DBUG_ENTER("Rows_log_event::do_apply_row");
10491
10492 int error= 0;
10493
10494 /* in_use can have been set to NULL in close_tables_for_reopen */
10495 THD* old_thd= m_table->in_use;
10496 if (!m_table->in_use)
10497 m_table->in_use= thd;
10498
10499 error= do_exec_row(rli);
10500
10501 if(error)
10502 {
10503 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10504 DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10505 }
10506
10507 m_table->in_use = old_thd;
10508
10509 DBUG_RETURN(error);
10510 }
10511
10512 /**
10513 Does the cleanup
10514 - closes the index if opened by open_record_scan
10515 - closes the table if opened for scanning.
10516 */
10517 int
close_record_scan()10518 Rows_log_event::close_record_scan()
10519 {
10520 DBUG_ENTER("Rows_log_event::close_record_scan");
10521 int error= 0;
10522
10523 // if there is something to actually close
10524 if (m_key_index < MAX_KEY)
10525 {
10526 if (m_table->file->inited)
10527 error= m_table->file->ha_index_end();
10528 }
10529 else if (m_table->file->inited)
10530 error= m_table->file->ha_rnd_end();
10531
10532 DBUG_RETURN(error);
10533 }
10534
10535 /**
10536 Fetches next row. If it is a HASH_SCAN over an index, it populates
10537 table->record[0] with the next row corresponding to the index. If
10538 the indexes are in non-contigous ranges it fetches record corresponding
10539 to the key value in the next range.
10540
10541 @parms: bool first_read : signifying if this is the first time we are reading a row
10542 over an index.
10543 @return_value: - error code when there are no more reeords to be fetched or some other
10544 error occured,
10545 - 0 otherwise.
10546 */
10547 int
next_record_scan(bool first_read)10548 Rows_log_event::next_record_scan(bool first_read)
10549 {
10550 DBUG_ENTER("Rows_log_event::next_record_scan");
10551 DBUG_ASSERT(m_table->file->inited);
10552 TABLE *table= m_table;
10553 int error= 0;
10554
10555 if (m_key_index >= MAX_KEY)
10556 error= table->file->ha_rnd_next(table->record[0]);
10557 else
10558 {
10559 /*
10560 We need to set the null bytes to ensure that the filler bit are
10561 all set when returning. There are storage engines that just set
10562 the necessary bits on the bytes and don't set the filler bits
10563 correctly.
10564 */
10565 if (table->s->null_bytes > 0)
10566 table->record[0][table->s->null_bytes - 1]|=
10567 256U - (1U << table->s->last_null_bit_pos);
10568
10569 if (!first_read)
10570 {
10571 /*
10572 if we fail to fetch next record corresponding to a key value, we
10573 move to the next key value. If we are out of key values as well an error
10574 will be returned.
10575 */
10576 error= table->file->ha_index_next_same(table->record[0], m_key,
10577 m_key_info->key_length);
10578 if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10579 {
10580 /*
10581 if we are out of rows for this particular key value, we reposition the
10582 marker according to the next key value that we have in the list.
10583 */
10584 if (error)
10585 {
10586 if (m_itr != m_distinct_keys.end())
10587 {
10588 m_key= *m_itr;
10589 m_itr++;
10590 first_read= true;
10591 }
10592 else
10593 error= HA_ERR_KEY_NOT_FOUND;
10594 }
10595 }
10596 }
10597
10598 if (first_read)
10599 if ((error= table->file->ha_index_read_map(table->record[0], m_key,
10600 HA_WHOLE_KEY,
10601 HA_READ_KEY_EXACT)))
10602 {
10603 DBUG_PRINT("info",("no record matching the key found in the table"));
10604 if (error == HA_ERR_RECORD_DELETED)
10605 error= HA_ERR_KEY_NOT_FOUND;
10606 }
10607 }
10608
10609 DBUG_RETURN(error);
10610 }
10611
10612 /**
10613 Initializes scanning of rows. Opens an index and initializes an iterator
10614 over a list of distinct keys (m_distinct_keys) if it is a HASH_SCAN
10615 over an index or the table if its a HASH_SCAN over the table.
10616 */
10617 int
open_record_scan()10618 Rows_log_event::open_record_scan()
10619 {
10620 int error= 0;
10621 TABLE *table= m_table;
10622 DBUG_ENTER("Rows_log_event::open_record_scan");
10623
10624 if (m_key_index < MAX_KEY )
10625 {
10626 if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10627 {
10628 /* initialize the iterator over the list of distinct keys that we have */
10629 m_itr= m_distinct_keys.begin();
10630
10631 /* get the first element from the list of keys and increment the
10632 iterator
10633 */
10634 m_key= *m_itr;
10635 m_itr++;
10636 }
10637 else {
10638 /* this is an INDEX_SCAN we need to store the key in m_key */
10639 DBUG_ASSERT((m_rows_lookup_algorithm == ROW_LOOKUP_INDEX_SCAN) && m_key);
10640 key_copy(m_key, m_table->record[0], m_key_info, 0);
10641 }
10642
10643 /*
10644 Save copy of the record in table->record[1]. It might be needed
10645 later if linear search is used to find exact match.
10646 */
10647 store_record(table,record[1]);
10648
10649 DBUG_PRINT("info",("locating record using a key (index_read)"));
10650
10651 /* The m_key_index'th key is active and usable: search the table using the index */
10652 if (!table->file->inited && (error= table->file->ha_index_init(m_key_index, FALSE)))
10653 {
10654 DBUG_PRINT("info",("ha_index_init returns error %d",error));
10655 goto end;
10656 }
10657
10658 /*
10659 Don't print debug messages when running valgrind since they can
10660 trigger false warnings.
10661 */
10662 #ifndef HAVE_purify
10663 DBUG_DUMP("key data", m_key, m_key_info->key_length);
10664 #endif
10665 }
10666 else
10667 {
10668 if ((error= table->file->ha_rnd_init(1)))
10669 {
10670 DBUG_PRINT("info",("error initializing table scan"
10671 " (ha_rnd_init returns %d)",error));
10672 table->file->print_error(error, MYF(0));
10673 }
10674 }
10675
10676 end:
10677 DBUG_RETURN(error);
10678 }
10679
10680 /**
10681 Populates the m_distinct_keys with unique keys to be modified
10682 during HASH_SCAN over keys.
10683 @return_value -0 success
10684 -Err_code
10685 */
10686 int
add_key_to_distinct_keyset()10687 Rows_log_event::add_key_to_distinct_keyset()
10688 {
10689 int error= 0;
10690 DBUG_ENTER("Rows_log_event::add_key_to_distinct_keyset");
10691 DBUG_ASSERT(m_key_index < MAX_KEY);
10692 key_copy(m_distinct_key_spare_buf, m_table->record[0], m_key_info, 0);
10693 std::pair<std::set<uchar *, Key_compare>::iterator,bool> ret=
10694 m_distinct_keys.insert(m_distinct_key_spare_buf);
10695 if (ret.second)
10696 {
10697 /* Insert is successful, so allocate a new buffer for next key */
10698 m_distinct_key_spare_buf= (uchar*) thd->alloc(m_key_info->key_length);
10699 if (!m_distinct_key_spare_buf)
10700 {
10701 error= HA_ERR_OUT_OF_MEM;
10702 goto err;
10703 }
10704 }
10705 err:
10706 DBUG_RETURN(error);
10707 }
10708
10709
do_index_scan_and_update(Relay_log_info const * rli)10710 int Rows_log_event::do_index_scan_and_update(Relay_log_info const *rli)
10711 {
10712 DBUG_ENTER("Rows_log_event::do_index_scan_and_update");
10713 DBUG_ASSERT(m_table && m_table->in_use != NULL);
10714
10715 int error= 0;
10716 const uchar *saved_m_curr_row= m_curr_row;
10717
10718 /*
10719 rpl_row_tabledefs.test specifies that
10720 if the extra field on the slave does not have a default value
10721 and this is okay with Delete or Update events.
10722 Todo: fix wl3228 hld that requires defaults for all types of events
10723 */
10724
10725 prepare_record(m_table, &m_cols, FALSE);
10726 if ((error= unpack_current_row(rli, &m_cols)))
10727 goto end;
10728
10729 // Temporary fix to find out why it fails [/Matz]
10730 memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
10731
10732 /*
10733 Trying to do an index scan without a usable key
10734 This is a valid state because we allow the user
10735 to set Slave_rows_search_algorithm= 'INDEX_SCAN'.
10736
10737 Therefore on tables with no indexes we will end
10738 up here.
10739 */
10740 if (m_key_index >= MAX_KEY)
10741 {
10742 error= HA_ERR_END_OF_FILE;
10743 goto end;
10744 }
10745
10746 #ifndef DBUG_OFF
10747 DBUG_PRINT("info",("looking for the following record"));
10748 DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10749 #endif
10750
10751 if (m_key_index != m_table->s->primary_key)
10752 /* we dont have a PK, or PK is not usable */
10753 goto INDEX_SCAN;
10754
10755 if ((m_table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL))
10756 {
10757 /*
10758 Read removal is possible since the engine supports write without
10759 previous read using full primary key
10760 */
10761 DBUG_PRINT("info", ("using read before write removal"));
10762 DBUG_ASSERT(m_key_index == m_table->s->primary_key);
10763
10764 /*
10765 Tell the handler to ignore if key exists or not, since it's
10766 not yet known if the key does exist(when using rbwr)
10767 */
10768 m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
10769
10770 goto end;
10771 }
10772
10773 if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION))
10774 {
10775 /*
10776 Use a more efficient method to fetch the record given by
10777 table->record[0] if the engine allows it. We first compute a
10778 row reference using the position() member function (it will be
10779 stored in table->file->ref) and then use rnd_pos() to position
10780 the "cursor" (i.e., record[0] in this case) at the correct row.
10781
10782 TODO: Check that the correct record has been fetched by
10783 comparing it with the original record. Take into account that the
10784 record on the master and slave can be of different
10785 length. Something along these lines should work:
10786
10787 ADD>>> store_record(table,record[1]);
10788 int error= table->file->rnd_pos(table->record[0], table->file->ref);
10789 ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
10790 table->s->reclength) == 0);
10791
10792 */
10793
10794 DBUG_PRINT("info",("locating record using primary key (position)"));
10795 if (m_table->file->inited && (error= m_table->file->ha_index_end()))
10796 goto end;
10797
10798 error= m_table->file->rnd_pos_by_record(m_table->record[0]);
10799 if (error)
10800 {
10801 DBUG_PRINT("info",("rnd_pos returns error %d",error));
10802 if (error == HA_ERR_RECORD_DELETED)
10803 error= HA_ERR_KEY_NOT_FOUND;
10804 }
10805
10806 goto end;
10807 }
10808
10809 // We can't use position() - try other methods.
10810
10811 INDEX_SCAN:
10812
10813 /* Use the m_key_index'th key */
10814
10815 if ((error= open_record_scan()))
10816 goto end;
10817
10818 error= next_record_scan(true);
10819 if (error)
10820 {
10821 DBUG_PRINT("info",("no record matching the key found in the table"));
10822 if (error == HA_ERR_RECORD_DELETED)
10823 error= HA_ERR_KEY_NOT_FOUND;
10824 goto end;
10825 }
10826
10827
10828 /*
10829 Don't print debug messages when running valgrind since they can
10830 trigger false warnings.
10831 */
10832 #ifndef HAVE_purify
10833 DBUG_PRINT("info",("found first matching record"));
10834 DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10835 #endif
10836 /*
10837 Below is a minor "optimization". If the key (i.e., key number
10838 0) has the HA_NOSAME flag set, we know that we have found the
10839 correct record (since there can be no duplicates); otherwise, we
10840 have to compare the record with the one found to see if it is
10841 the correct one.
10842
10843 CAVEAT! This behaviour is essential for the replication of,
10844 e.g., the mysql.proc table since the correct record *shall* be
10845 found using the primary key *only*. There shall be no
10846 comparison of non-PK columns to decide if the correct record is
10847 found. I can see no scenario where it would be incorrect to
10848 chose the row to change only using a PK or an UNNI.
10849 */
10850 if (m_key_info->flags & HA_NOSAME || m_key_index == m_table->s->primary_key)
10851 {
10852 /* Unique does not have non nullable part */
10853 if (!(m_key_info->flags & (HA_NULL_PART_KEY)))
10854 goto end; // record found
10855 else
10856 {
10857 /*
10858 Unique has nullable part. We need to check if there is any field in the
10859 BI image that is null and part of UNNI.
10860 */
10861 bool null_found= FALSE;
10862 for (uint i=0; i < m_key_info->user_defined_key_parts && !null_found; i++)
10863 {
10864 uint fieldnr= m_key_info->key_part[i].fieldnr - 1;
10865 Field **f= m_table->field+fieldnr;
10866 null_found= (*f)->is_null();
10867 }
10868
10869 if (!null_found)
10870 goto end; // record found
10871
10872 /* else fall through to index scan */
10873 }
10874 }
10875
10876 /*
10877 In case key is not unique, we still have to iterate over records found
10878 and find the one which is identical to the row given. A copy of the
10879 record we are looking for is stored in record[1].
10880 */
10881 DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10882
10883 while (record_compare(m_table, &m_cols))
10884 {
10885 while((error= next_record_scan(false)))
10886 {
10887 /* We just skip records that has already been deleted */
10888 if (error == HA_ERR_RECORD_DELETED)
10889 continue;
10890 DBUG_PRINT("info",("no record matching the given row found"));
10891 goto end;
10892 }
10893 }
10894
10895 end:
10896
10897 DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10898
10899 if (error && error != HA_ERR_RECORD_DELETED)
10900 m_table->file->print_error(error, MYF(0));
10901 else
10902 error= do_apply_row(rli);
10903
10904 if (!error)
10905 error= close_record_scan();
10906 else
10907 /*
10908 we are already with errors. Keep the error code and
10909 try to close the scan anyway.
10910 */
10911 (void) close_record_scan();
10912
10913 if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
10914 (saved_m_curr_row == m_curr_row))
10915 {
10916 /* we need to unpack the AI so that positions get updated */
10917 m_curr_row= m_curr_row_end;
10918 unpack_current_row(rli, &m_cols_ai);
10919 }
10920 m_table->default_column_bitmaps();
10921 DBUG_RETURN(error);
10922
10923 }
10924
do_hash_row(Relay_log_info const * rli)10925 int Rows_log_event::do_hash_row(Relay_log_info const *rli)
10926 {
10927 DBUG_ENTER("Rows_log_event::do_hash_row");
10928 DBUG_ASSERT(m_table && m_table->in_use != NULL);
10929 int error= 0;
10930
10931 /* create an empty entry to add to the hash table */
10932 HASH_ROW_ENTRY* entry= m_hash.make_entry();
10933 if (entry == NULL)
10934 {
10935 error= 1;
10936 goto end;
10937 }
10938 /* Prepare the record, unpack and save positions. */
10939 entry->positions->bi_start= m_curr_row; // save the bi start pos
10940 prepare_record(m_table, &m_cols, false);
10941 if ((error= unpack_current_row(rli, &m_cols)))
10942 goto end;
10943 entry->positions->bi_ends= m_curr_row_end; // save the bi end pos
10944
10945 /*
10946 Now that m_table->record[0] is filled in, we can add the entry
10947 to the hash table. Note that the put operation calculates the
10948 key based on record[0] contents (including BLOB fields).
10949 */
10950 m_hash.put(m_table, &m_cols, entry);
10951
10952 if (m_key_index < MAX_KEY)
10953 add_key_to_distinct_keyset();
10954
10955 /*
10956 We need to unpack the AI to advance the positions, so we
10957 know when we have reached m_rows_end and that we do not
10958 unpack the AI in the next iteration as if it was a BI.
10959 */
10960 if (get_general_type_code() == UPDATE_ROWS_EVENT)
10961 {
10962 /* Save a copy of the BI. */
10963 store_record(m_table, record[1]);
10964
10965 /*
10966 This is the situation after hashing the BI:
10967
10968 ===|=== before image ====|=== after image ===|===
10969 ^ ^
10970 m_curr_row m_curr_row_end
10971 */
10972
10973 /* Set the position to the start of the record to be unpacked. */
10974 m_curr_row= m_curr_row_end;
10975
10976 /* We shouldn't need this, but lets not leave loose ends */
10977 prepare_record(m_table, &m_cols, false);
10978 error= unpack_current_row(rli, &m_cols_ai);
10979
10980 /*
10981 This is the situation after unpacking the AI:
10982
10983 ===|=== before image ====|=== after image ===|===
10984 ^ ^
10985 m_curr_row m_curr_row_end
10986 */
10987
10988 /* Restore back the copy of the BI. */
10989 restore_record(m_table, record[1]);
10990 }
10991
10992 end:
10993 DBUG_RETURN(error);
10994 }
10995
do_scan_and_update(Relay_log_info const * rli)10996 int Rows_log_event::do_scan_and_update(Relay_log_info const *rli)
10997 {
10998 DBUG_ENTER("Rows_log_event::do_scan_and_update");
10999 DBUG_ASSERT(m_table && m_table->in_use != NULL);
11000 DBUG_ASSERT(m_hash.is_empty() == false);
11001 TABLE *table= m_table;
11002 int error= 0;
11003 const uchar *saved_last_m_curr_row= NULL;
11004 const uchar *saved_last_m_curr_row_end= NULL;
11005 /* create an empty entry to add to the hash table */
11006 HASH_ROW_ENTRY* entry= NULL;
11007 int idempotent_errors= 0;
11008 int i= 0;
11009
11010 saved_last_m_curr_row=m_curr_row;
11011 saved_last_m_curr_row_end=m_curr_row_end;
11012
11013 DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11014
11015 /* open table or index depending on whether we have set m_key_index or not. */
11016 if ((error= open_record_scan()))
11017 goto err;
11018
11019 /*
11020 Scan the table only once and compare against entries in hash.
11021 When a match is found, apply the changes.
11022 */
11023 do
11024 {
11025 /* get the next record from the table */
11026 error= next_record_scan(i == 0);
11027 i++;
11028
11029 if(error)
11030 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11031 switch (error) {
11032 case 0:
11033 {
11034 entry= m_hash.get(table, &m_cols);
11035 store_record(table, record[1]);
11036
11037 /**
11038 If there are collisions we need to be sure that this is
11039 indeed the record we want. Loop through all records for
11040 the given key and explicitly compare them against the
11041 record we got from the storage engine.
11042 */
11043 while(entry)
11044 {
11045 m_curr_row= entry->positions->bi_start;
11046 m_curr_row_end= entry->positions->bi_ends;
11047
11048 prepare_record(table, &m_cols, false);
11049 if ((error= unpack_current_row(rli, &m_cols)))
11050 goto close_table;
11051
11052 if (record_compare(table, &m_cols))
11053 m_hash.next(&entry);
11054 else
11055 break; // we found a match
11056 }
11057
11058 /**
11059 We found the entry we needed, just apply the changes.
11060 */
11061 if (entry)
11062 {
11063 // just to be safe, copy the record from the SE to table->record[0]
11064 restore_record(table, record[1]);
11065
11066 /**
11067 At this point, both table->record[0] and
11068 table->record[1] have the SE row that matched the one
11069 in the hash table.
11070
11071 Thence if this is a DELETE we wouldn't need to mess
11072 around with positions anymore, but since this can be an
11073 update, we need to provide positions so that AI is
11074 unpacked correctly to table->record[0] in UPDATE
11075 implementation of do_exec_row().
11076 */
11077 m_curr_row= entry->positions->bi_start;
11078 m_curr_row_end= entry->positions->bi_ends;
11079
11080 /* we don't need this entry anymore, just delete it */
11081 if ((error= m_hash.del(entry)))
11082 goto err;
11083
11084 if ((error= do_apply_row(rli)))
11085 {
11086 if (handle_idempotent_and_ignored_errors(rli, &error))
11087 goto close_table;
11088
11089 do_post_row_operations(rli, error);
11090 }
11091 }
11092 }
11093 break;
11094
11095 case HA_ERR_RECORD_DELETED:
11096 // get next
11097 continue;
11098
11099 case HA_ERR_KEY_NOT_FOUND:
11100 /* If the slave exec mode is idempotent or the error is
11101 skipped error, then don't break */
11102 if (handle_idempotent_and_ignored_errors(rli, &error))
11103 goto close_table;
11104 idempotent_errors++;
11105 continue;
11106
11107 case HA_ERR_END_OF_FILE:
11108 default:
11109 // exception (hash is not empty and we have reached EOF or
11110 // other error happened)
11111 goto close_table;
11112 }
11113 }
11114 /**
11115 if the slave_exec_mode is set to Idempotent, we cannot expect the hash to
11116 be empty. In such cases we count the number of idempotent errors and check
11117 if it is equal to or greater than the number of rows left in the hash.
11118 */
11119 while (((idempotent_errors < m_hash.size()) && !m_hash.is_empty()) &&
11120 (!error || (error == HA_ERR_RECORD_DELETED)));
11121
11122 close_table:
11123 if (error == HA_ERR_RECORD_DELETED)
11124 error= 0;
11125
11126 if (error)
11127 {
11128 table->file->print_error(error, MYF(0));
11129 DBUG_PRINT("info", ("Failed to get next record"
11130 " (ha_rnd_next returns %d)",error));
11131 /*
11132 we are already with errors. Keep the error code and
11133 try to close the scan anyway.
11134 */
11135 (void) close_record_scan();
11136 }
11137 else
11138 error= close_record_scan();
11139
11140 DBUG_ASSERT((m_hash.is_empty() && !error) ||
11141 (!m_hash.is_empty() &&
11142 ((error) || (idempotent_errors >= m_hash.size()))));
11143
11144 err:
11145
11146 if ((m_hash.is_empty() && !error) || (idempotent_errors >= m_hash.size()))
11147 {
11148 /**
11149 Reset the last positions, because the positions are lost while
11150 handling entries in the hash.
11151 */
11152 m_curr_row= saved_last_m_curr_row;
11153 m_curr_row_end= saved_last_m_curr_row_end;
11154 }
11155
11156 DBUG_RETURN(error);
11157 }
11158
do_hash_scan_and_update(Relay_log_info const * rli)11159 int Rows_log_event::do_hash_scan_and_update(Relay_log_info const *rli)
11160 {
11161 DBUG_ENTER("Rows_log_event::do_hash_scan_and_update");
11162 DBUG_ASSERT(m_table && m_table->in_use != NULL);
11163
11164 // HASHING PART
11165
11166 /* unpack the BI (and AI, if it exists) and add it to the hash map. */
11167 if (int error= this->do_hash_row(rli))
11168 DBUG_RETURN(error);
11169
11170 /* We have not yet hashed all rows in the buffer. Do not proceed to the SCAN part. */
11171 if (m_curr_row_end < m_rows_end)
11172 DBUG_RETURN (0);
11173
11174 DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11175 DBUG_ASSERT(m_curr_row_end == m_rows_end);
11176
11177 // SCANNING & UPDATE PART
11178
11179 DBUG_RETURN(this->do_scan_and_update(rli));
11180 }
11181
do_table_scan_and_update(Relay_log_info const * rli)11182 int Rows_log_event::do_table_scan_and_update(Relay_log_info const *rli)
11183 {
11184 int error= 0;
11185 const uchar* saved_m_curr_row= m_curr_row;
11186 TABLE* table= m_table;
11187
11188 DBUG_ENTER("Rows_log_event::do_table_scan_and_update");
11189 DBUG_ASSERT(m_curr_row != m_rows_end);
11190 DBUG_PRINT("info",("locating record using table scan (ha_rnd_next)"));
11191
11192 saved_m_curr_row= m_curr_row;
11193
11194 /** unpack the before image */
11195 prepare_record(table, &m_cols, FALSE);
11196 if (!(error= unpack_current_row(rli, &m_cols)))
11197 {
11198 // Temporary fix to find out why it fails [/Matz]
11199 memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
11200
11201 /** save a copy so that we can compare against it later */
11202 store_record(m_table, record[1]);
11203
11204 int restart_count= 0; // Number of times scanning has restarted from top
11205
11206 if ((error= m_table->file->ha_rnd_init(1)))
11207 {
11208 DBUG_PRINT("info",("error initializing table scan"
11209 " (ha_rnd_init returns %d)",error));
11210 goto end;
11211 }
11212
11213 /* Continue until we find the right record or have made a full loop */
11214 do
11215 {
11216 restart_ha_rnd_next:
11217 error= m_table->file->ha_rnd_next(m_table->record[0]);
11218 if (error)
11219 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11220 switch (error) {
11221 case HA_ERR_END_OF_FILE:
11222 // restart scan from top
11223 if (++restart_count < 2)
11224 {
11225 if ((error= m_table->file->ha_rnd_init(1)))
11226 goto end;
11227 goto restart_ha_rnd_next;
11228 }
11229 break;
11230
11231 case HA_ERR_RECORD_DELETED:
11232 // fetch next
11233 goto restart_ha_rnd_next;
11234 case 0:
11235 // we're good, check if record matches
11236 break;
11237
11238 default:
11239 // exception
11240 goto end;
11241 }
11242 }
11243 while (restart_count < 2 && record_compare(m_table, &m_cols));
11244 }
11245
11246 end:
11247
11248 DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
11249
11250 /* either we report error or apply the changes */
11251 if (error && error != HA_ERR_RECORD_DELETED)
11252 {
11253 DBUG_PRINT("info", ("Failed to get next record"
11254 " (ha_rnd_next returns %d)",error));
11255 m_table->file->print_error(error, MYF(0));
11256 }
11257 else
11258 error= do_apply_row(rli);
11259
11260
11261 if (!error)
11262 error= close_record_scan();
11263 else
11264 /*
11265 we are already with errors. Keep the error code and
11266 try to close the scan anyway.
11267 */
11268 (void) close_record_scan();
11269
11270 if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11271 (saved_m_curr_row == m_curr_row)) // we need to unpack the AI
11272 {
11273 m_curr_row= m_curr_row_end;
11274 unpack_current_row(rli, &m_cols);
11275 }
11276
11277 table->default_column_bitmaps();
11278 DBUG_RETURN(error);
11279 }
11280
do_apply_event(Relay_log_info const * rli)11281 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
11282 {
11283 DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
11284 TABLE *table= NULL;
11285 int error= 0;
11286
11287 if (opt_bin_log)
11288 {
11289 enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
11290 if (state == GTID_STATEMENT_CANCEL)
11291 // error has already been printed; don't print anything more here
11292 DBUG_RETURN(-1);
11293 else if (state == GTID_STATEMENT_SKIP)
11294 DBUG_RETURN(0);
11295 }
11296
11297 /*
11298 'thd' has been set by exec_relay_log_event(), just before calling
11299 do_apply_event(). We still check here to prevent future coding
11300 errors.
11301 */
11302 DBUG_ASSERT(rli->info_thd == thd);
11303
11304 /*
11305 If there is no locks taken, this is the first binrow event seen
11306 after the table map events. We should then lock all the tables
11307 used in the transaction and proceed with execution of the actual
11308 event.
11309 */
11310 if (!thd->lock)
11311 {
11312 /*
11313 Lock_tables() reads the contents of thd->lex, so they must be
11314 initialized.
11315
11316 We also call the mysql_reset_thd_for_next_command(), since this
11317 is the logical start of the next "statement". Note that this
11318 call might reset the value of current_stmt_binlog_format, so
11319 we need to do any changes to that value after this function.
11320 */
11321 lex_start(thd);
11322 mysql_reset_thd_for_next_command(thd);
11323 /*
11324 The current statement is just about to begin and
11325 has not yet modified anything. Note, all.modified is reset
11326 by mysql_reset_thd_for_next_command.
11327 */
11328 thd->transaction.stmt.reset_unsafe_rollback_flags();
11329 /*
11330 This is a row injection, so we flag the "statement" as
11331 such. Note that this code is called both when the slave does row
11332 injections and when the BINLOG statement is used to do row
11333 injections.
11334 */
11335 thd->lex->set_stmt_row_injection();
11336
11337 /*
11338 There are a few flags that are replicated with each row event.
11339 Make sure to set/clear them before executing the main body of
11340 the event.
11341 */
11342 if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
11343 thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
11344 else
11345 thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
11346
11347 if (get_flags(RELAXED_UNIQUE_CHECKS_F))
11348 thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
11349 else
11350 thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
11351
11352 thd->binlog_row_event_extra_data = m_extra_row_data;
11353
11354 /* A small test to verify that objects have consistent types */
11355 DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
11356 DBUG_EXECUTE_IF("rows_log_event_before_open_table",
11357 {
11358 const char action[] = "now SIGNAL before_open_table WAIT_FOR go_ahead_sql";
11359 DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(action)));
11360 };);
11361 if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
11362 {
11363 #ifdef WITH_WSREP
11364 if (WSREP(thd))
11365 {
11366 WSREP_WARN("BF applier failed to open_and_lock_tables: %u, fatal: %d "
11367 "wsrep = (exec_mode: %d conflict_state: %d seqno: %lld)",
11368 thd->get_stmt_da()->sql_errno(),
11369 thd->is_fatal_error,
11370 thd->wsrep_exec_mode,
11371 thd->wsrep_conflict_state,
11372 (long long)wsrep_thd_trx_seqno(thd));
11373 }
11374 #endif
11375 if (thd->is_error())
11376 {
11377 uint actual_error= thd->get_stmt_da()->sql_errno();
11378 if (ignored_error_code(actual_error))
11379 {
11380 if (log_warnings > 1)
11381 rli->report(WARNING_LEVEL, actual_error,
11382 "Error executing row event: '%s'",
11383 thd->get_stmt_da()->message());
11384 thd->get_stmt_da()->clear_warning_info(thd->query_id);
11385 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11386 error= 0;
11387 goto end;
11388 }
11389 else
11390 {
11391 rli->report(ERROR_LEVEL, actual_error,
11392 "Error executing row event: '%s'",
11393 thd->get_stmt_da()->message());
11394 thd->is_slave_error= 1;
11395 }
11396 }
11397 DBUG_RETURN(1);
11398 }
11399 /*
11400 When the open and locking succeeded, we check all tables to
11401 ensure that they still have the correct type.
11402 */
11403
11404 {
11405 DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
11406 rli->tables_to_lock));
11407
11408 /**
11409 When using RBR and MyISAM MERGE tables the base tables that make
11410 up the MERGE table can be appended to the list of tables to lock.
11411
11412 Thus, we just check compatibility for those that tables that have
11413 a correspondent table map event (ie, those that are actually going
11414 to be accessed while applying the event). That's why the loop stops
11415 at rli->tables_to_lock_count .
11416
11417 NOTE: The base tables are added here are removed when
11418 close_thread_tables is called.
11419 */
11420 TABLE_LIST *table_list_ptr= rli->tables_to_lock;
11421 for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count);
11422 table_list_ptr= table_list_ptr->next_global, i++)
11423 {
11424 /*
11425 Below if condition takes care of skipping base tables that
11426 make up the MERGE table (which are added by open_tables()
11427 call). They are added next to the merge table in the list.
11428 For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
11429 are base tables for merge table 't3'), open_tables will modify
11430 the list by adding t1 and t2 again immediately after t3 in the
11431 list (*not at the end of the list*). New table_to_lock list will
11432 look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
11433 objects added by open_tables() call). There is no flag(or logic) in
11434 open_tables() that can skip adding these base tables to the list.
11435 So the logic here should take care of skipping them.
11436
11437 tables_to_lock_count logic will take care of skipping base tables
11438 that are added at the end of the list.
11439 For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
11440 the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
11441 because tables_to_lock_count logic in this for loop.
11442 */
11443 if (table_list_ptr->parent_l)
11444 continue;
11445 /*
11446 We can use a down cast here since we know that every table added
11447 to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
11448 skipped above).
11449 */
11450 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
11451 DBUG_ASSERT(ptr->m_tabledef_valid);
11452 TABLE *conv_table;
11453 if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
11454 ptr->table, &conv_table))
11455 {
11456 DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
11457 ptr->table->s->db.str,
11458 ptr->table->s->table_name.str));
11459 if (thd->is_slave_error)
11460 {
11461 const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
11462 DBUG_RETURN(ERR_BAD_TABLE_DEF);
11463 }
11464 else
11465 {
11466 thd->get_stmt_da()->clear_warning_info(thd->query_id);
11467 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11468 error= 0;
11469 goto end;
11470 }
11471 }
11472 DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
11473 " - conv_table: %p",
11474 ptr->table->s->db.str,
11475 ptr->table->s->table_name.str, conv_table));
11476 ptr->m_conv_table= conv_table;
11477 }
11478 }
11479
11480 /*
11481 ... and then we add all the tables to the table map and but keep
11482 them in the tables to lock list.
11483
11484 We also invalidate the query cache for all the tables, since
11485 they will now be changed.
11486
11487 TODO [/Matz]: Maybe the query cache should not be invalidated
11488 here? It might be that a table is not changed, even though it
11489 was locked for the statement. We do know that each
11490 Rows_log_event contain at least one row, so after processing one
11491 Rows_log_event, we can invalidate the query cache for the
11492 associated table.
11493 */
11494 TABLE_LIST *ptr= rli->tables_to_lock;
11495 for (uint i=0 ; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
11496 {
11497 /*
11498 Please see comment in above 'for' loop to know the reason
11499 for this if condition
11500 */
11501 if (ptr->parent_l)
11502 continue;
11503 const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
11504 }
11505
11506 #ifdef HAVE_QUERY_CACHE
11507 #ifdef WITH_WSREP
11508 /*
11509 Moved invalidation right before the call to rows_event_stmt_cleanup(),
11510 to avoid query cache being polluted with stale entries,
11511 */
11512 if (! (WSREP(thd) && (thd->wsrep_exec_mode == REPL_RECV)))
11513 {
11514 #endif /* WITH_WSREP */
11515 query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11516 #ifdef WITH_WSREP
11517 }
11518 #endif /* WITH_WSREP */
11519 #endif
11520 }
11521
11522 table=
11523 m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
11524
11525 DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %llu", (ulong) m_table,
11526 m_table_id.id()));
11527
11528 /*
11529 A row event comprising of a P_S table
11530 - should not be replicated (i.e executed) by the slave SQL thread.
11531 - should not be executed by the client in the form BINLOG '...' stmts.
11532 */
11533 if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
11534 table= NULL;
11535
11536 if (table)
11537 {
11538 /*
11539 table == NULL means that this table should not be replicated
11540 (this was set up by Table_map_log_event::do_apply_event()
11541 which tested replicate-* rules).
11542 */
11543
11544 /*
11545 It's not needed to set_time() but
11546 1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11547 much slave is behind
11548 2) it will be needed when we allow replication from a table with no
11549 TIMESTAMP column to a table with one.
11550 So we call set_time(), like in SBR. Presently it changes nothing.
11551 */
11552 thd->set_time(&when);
11553
11554 thd->binlog_row_event_extra_data = m_extra_row_data;
11555
11556 /*
11557 Now we are in a statement and will stay in a statement until we
11558 see a STMT_END_F.
11559
11560 We set this flag here, before actually applying any rows, in
11561 case the SQL thread is stopped and we need to detect that we're
11562 inside a statement and halting abruptly might cause problems
11563 when restarting.
11564 */
11565 const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
11566
11567 if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11568 set_flags(COMPLETE_ROWS_F);
11569
11570 /*
11571 Set tables write and read sets.
11572
11573 Read_set contains all slave columns (in case we are going to fetch
11574 a complete record from slave)
11575
11576 Write_set equals the m_cols bitmap sent from master but it can be
11577 longer if slave has extra columns.
11578 */
11579
11580 DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11581
11582 bitmap_set_all(table->read_set);
11583 if (get_general_type_code() == DELETE_ROWS_EVENT ||
11584 get_general_type_code() == UPDATE_ROWS_EVENT)
11585 bitmap_intersect(table->read_set,&m_cols);
11586
11587 bitmap_set_all(table->write_set);
11588
11589 /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11590 MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
11591 &m_cols_ai : &m_cols);
11592 bitmap_intersect(table->write_set, after_image);
11593
11594 this->slave_exec_mode= slave_exec_mode_options; // fix the mode
11595
11596 // Do event specific preparations
11597 error= do_before_row_operations(rli);
11598
11599 /*
11600 Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11601 Don't allow generation of auto_increment value when processing
11602 rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
11603 to this rule happens when the auto_inc column exists on some
11604 extra columns on the slave. In that case, do not force
11605 MODE_NO_AUTO_VALUE_ON_ZERO.
11606 */
11607 ulong saved_sql_mode= thd->variables.sql_mode;
11608 if (!is_auto_inc_in_extra_columns())
11609 thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11610
11611 // row processing loop
11612
11613 /*
11614 set the initial time of this ROWS statement if it was not done
11615 before in some other ROWS event.
11616 */
11617 const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
11618
11619 const uchar *saved_m_curr_row= m_curr_row;
11620
11621 int (Rows_log_event::*do_apply_row_ptr)(Relay_log_info const *)= NULL;
11622
11623 /**
11624 Skip update rows events that don't have data for this slave's
11625 table.
11626 */
11627 if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11628 !is_any_column_signaled_for_table(table, &m_cols_ai))
11629 goto AFTER_MAIN_EXEC_ROW_LOOP;
11630
11631 /**
11632 If there are no columns marked in the read_set for this table,
11633 that means that we cannot lookup any row using the available BI
11634 in the binarr log. Thence, we immediatly raise an error:
11635 HA_ERR_END_OF_FILE.
11636 */
11637
11638 if ((m_rows_lookup_algorithm != ROW_LOOKUP_NOT_NEEDED) &&
11639 !is_any_column_signaled_for_table(table, &m_cols))
11640 {
11641 error= HA_ERR_END_OF_FILE;
11642 goto AFTER_MAIN_EXEC_ROW_LOOP;
11643 }
11644 switch (m_rows_lookup_algorithm)
11645 {
11646 case ROW_LOOKUP_HASH_SCAN:
11647 do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11648 break;
11649
11650 case ROW_LOOKUP_INDEX_SCAN:
11651 do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11652 break;
11653
11654 case ROW_LOOKUP_TABLE_SCAN:
11655 do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11656 break;
11657
11658 case ROW_LOOKUP_NOT_NEEDED:
11659 DBUG_ASSERT(get_general_type_code() == WRITE_ROWS_EVENT);
11660
11661 /* No need to scan for rows, just apply it */
11662 do_apply_row_ptr= &Rows_log_event::do_apply_row;
11663 break;
11664
11665 default:
11666 DBUG_ASSERT(0);
11667 error= 1;
11668 goto AFTER_MAIN_EXEC_ROW_LOOP;
11669 break;
11670 }
11671
11672 do {
11673
11674 error= (this->*do_apply_row_ptr)(rli);
11675
11676 if (handle_idempotent_and_ignored_errors(rli, &error))
11677 break;
11678
11679 /* this advances m_curr_row */
11680 do_post_row_operations(rli, error);
11681
11682 } while (!error && (m_curr_row != m_rows_end));
11683
11684 AFTER_MAIN_EXEC_ROW_LOOP:
11685
11686 if (saved_m_curr_row != m_curr_row && !table->file->has_transactions())
11687 {
11688 /*
11689 Usually, the trans_commit_stmt() propagates unsafe_rollback_flags
11690 from statement to transaction level. However, we cannot rely on
11691 this when row format is in use as several events can be processed
11692 before calling this function. This happens because it is called
11693 only when the latest event generated by a statement is processed.
11694
11695 There are however upper level functions that execute per event
11696 and check transaction's status. So if the unsafe_rollback_flags
11697 are not propagated here, this can lead to errors.
11698
11699 For example, a transaction that updates non-transactional tables
11700 may be stopped in the middle thus leading to inconsistencies
11701 after a restart.
11702 */
11703 thd->transaction.stmt.mark_modified_non_trans_table();
11704 thd->transaction.merge_unsafe_rollback_flags();
11705 }
11706
11707 /*
11708 Restore the sql_mode after the rows event is processed.
11709 */
11710 thd->variables.sql_mode= saved_sql_mode;
11711
11712 {/*
11713 The following failure injecion works in cooperation with tests
11714 setting @@global.debug= 'd,stop_slave_middle_group'.
11715 The sql thread receives the killed status and will proceed
11716 to shutdown trying to finish incomplete events group.
11717 */
11718 DBUG_EXECUTE_IF("stop_slave_middle_group",
11719 if (thd->transaction.all.cannot_safely_rollback())
11720 const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11721 }
11722
11723 if ((error= do_after_row_operations(rli, error)) &&
11724 ignored_error_code(convert_handler_error(error, thd, table)))
11725 {
11726
11727 if (log_warnings > 1)
11728 slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
11729 get_type_str(),
11730 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11731 (ulong) log_pos);
11732 thd->get_stmt_da()->clear_warning_info(thd->query_id);
11733 clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11734 error= 0;
11735 }
11736 } // if (table)
11737
11738 if (error)
11739 {
11740 slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
11741 get_type_str(),
11742 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11743 (ulong) log_pos);
11744 /*
11745 @todo We should probably not call
11746 reset_current_stmt_binlog_format_row() from here.
11747
11748 Note: this applies to log_event_old.cc too.
11749 /Sven
11750 */
11751 thd->reset_current_stmt_binlog_format_row();
11752 thd->is_slave_error= 1;
11753 DBUG_RETURN(error);
11754 }
11755 end:
11756 if (get_flags(STMT_END_F))
11757 {
11758
11759 #if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
11760 if (WSREP(thd) && thd->wsrep_exec_mode == REPL_RECV)
11761 {
11762 query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11763 }
11764 #endif /* WITH_WSREP && HAVE_QUERY_CACHE */
11765
11766 if((error= rows_event_stmt_cleanup(rli, thd)))
11767 {
11768 if (table)
11769 slave_rows_error_report(ERROR_LEVEL,
11770 thd->is_error() ? 0 : error,
11771 rli, thd, table,
11772 get_type_str(),
11773 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11774 (ulong) log_pos);
11775 else
11776 {
11777 rli->report(ERROR_LEVEL,
11778 thd->is_error() ? thd->get_stmt_da()->sql_errno() : error,
11779 "Error in cleaning up after an event of type:%s; %s; the group"
11780 " log file/position: %s %lu", get_type_str(),
11781 thd->is_error() ? thd->get_stmt_da()->message() : "unexpected error",
11782 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11783 (ulong) log_pos);
11784 }
11785 }
11786 /* We are at end of the statement (STMT_END_F flag), lets clean
11787 the memory which was used from thd's mem_root now.
11788 This needs to be done only if we are here in SQL thread context.
11789 In other flow ( in case of a regular thread which can happen
11790 when the thread is applying BINLOG'...' row event) we should
11791 *not* try to free the memory here. It will be done latter
11792 in dispatch_command() after command execution is completed.
11793 */
11794 if (thd->slave_thread)
11795 free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
11796 }
11797 DBUG_RETURN(error);
11798 }
11799
11800 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)11801 Rows_log_event::do_shall_skip(Relay_log_info *rli)
11802 {
11803 /*
11804 If the slave skip counter is 1 and this event does not end a
11805 statement, then we should not start executing on the next event.
11806 Otherwise, we defer the decision to the normal skipping logic.
11807 */
11808 if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11809 return Log_event::EVENT_SKIP_IGNORE;
11810 else
11811 return Log_event::do_shall_skip(rli);
11812 }
11813
11814 /**
11815 The function is called at Rows_log_event statement commit time,
11816 normally from Rows_log_event::do_update_pos() and possibly from
11817 Query_log_event::do_apply_event() of the COMMIT.
11818 The function commits the last statement for engines, binlog and
11819 releases resources have been allocated for the statement.
11820
11821 @retval 0 Ok.
11822 @retval non-zero Error at the commit.
11823 */
11824
rows_event_stmt_cleanup(Relay_log_info const * rli,THD * thd)11825 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
11826 {
11827 DBUG_EXECUTE_IF("simulate_rows_event_cleanup_failure",
11828 {
11829 my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
11830 return (1);
11831 });
11832 int error;
11833 {
11834 /*
11835 This is the end of a statement or transaction, so close (and
11836 unlock) the tables we opened when processing the
11837 Table_map_log_event starting the statement.
11838
11839 OBSERVER. This will clear *all* mappings, not only those that
11840 are open for the table. There is not good handle for on-close
11841 actions for tables.
11842
11843 NOTE. Even if we have no table ('table' == 0) we still need to be
11844 here, so that we increase the group relay log position. If we didn't, we
11845 could have a group relay log position which lags behind "forever"
11846 (assume the last master's transaction is ignored by the slave because of
11847 replicate-ignore rules).
11848 */
11849 error= thd->binlog_flush_pending_rows_event(TRUE);
11850
11851 /*
11852 If this event is not in a transaction, the call below will, if some
11853 transactional storage engines are involved, commit the statement into
11854 them and flush the pending event to binlog.
11855 If this event is in a transaction, the call will do nothing, but a
11856 Xid_log_event will come next which will, if some transactional engines
11857 are involved, commit the transaction and flush the pending event to the
11858 binlog.
11859 If there was a deadlock the transaction should have been rolled back
11860 already. So there should be no need to rollback the transaction.
11861 */
11862 DBUG_ASSERT(! thd->transaction_rollback_request);
11863 error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11864
11865 /*
11866 Now what if this is not a transactional engine? we still need to
11867 flush the pending event to the binlog; we did it with
11868 thd->binlog_flush_pending_rows_event(). Note that we imitate
11869 what is done for real queries: a call to
11870 ha_autocommit_or_rollback() (sometimes only if involves a
11871 transactional engine), and a call to be sure to have the pending
11872 event flushed.
11873 */
11874
11875 /*
11876 @todo We should probably not call
11877 reset_current_stmt_binlog_format_row() from here.
11878
11879 Note: this applies to log_event_old.cc too
11880
11881 Btw, the previous comment about transactional engines does not
11882 seem related to anything that happens here.
11883 /Sven
11884 */
11885 thd->reset_current_stmt_binlog_format_row();
11886
11887 const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
11888
11889 /*
11890 Clean sql_command value
11891 */
11892 thd->lex->sql_command= SQLCOM_END;
11893
11894 }
11895 return error;
11896 }
11897
11898 /**
11899 The method either increments the relay log position or
11900 commits the current statement and increments the master group
11901 possition if the event is STMT_END_F flagged and
11902 the statement corresponds to the autocommit query (i.e replicated
11903 without wrapping in BEGIN/COMMIT)
11904
11905 @retval 0 Success
11906 @retval non-zero Error in the statement commit
11907 */
11908 int
do_update_pos(Relay_log_info * rli)11909 Rows_log_event::do_update_pos(Relay_log_info *rli)
11910 {
11911 DBUG_ENTER("Rows_log_event::do_update_pos");
11912 int error= 0;
11913
11914 DBUG_PRINT("info", ("flags: %s",
11915 get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11916
11917 /* Worker does not execute binlog update position logics */
11918 DBUG_ASSERT(!is_mts_worker(rli->info_thd));
11919
11920 if (get_flags(STMT_END_F))
11921 {
11922 /*
11923 Indicate that a statement is finished.
11924 Step the group log position if we are not in a transaction,
11925 otherwise increase the event log position.
11926 */
11927 error= rli->stmt_done(log_pos);
11928 }
11929 else
11930 {
11931 rli->inc_event_relay_log_pos();
11932 }
11933
11934 DBUG_RETURN(error);
11935 }
11936
11937 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11938
11939 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)11940 bool Rows_log_event::write_data_header(IO_CACHE *file)
11941 {
11942 uchar buf[ROWS_HEADER_LEN_V2]; // No need to init the buffer
11943 DBUG_ASSERT(m_table_id.is_valid());
11944 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11945 {
11946 int4store(buf + 0, (ulong) m_table_id.id());
11947 int2store(buf + 4, m_flags);
11948 return (wrapper_my_b_safe_write(file, buf, 6));
11949 });
11950 int6store(buf + RW_MAPID_OFFSET, m_table_id.id());
11951 int2store(buf + RW_FLAGS_OFFSET, m_flags);
11952 int rc = 0;
11953 if (likely(!log_bin_use_v1_row_events))
11954 {
11955 /*
11956 v2 event, with variable header portion.
11957 Determine length of variable header payload
11958 */
11959 uint16 vhlen= 2;
11960 uint16 vhpayloadlen= 0;
11961 uint16 extra_data_len= 0;
11962 if (m_extra_row_data)
11963 {
11964 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
11965 vhpayloadlen= RW_V_TAG_LEN + extra_data_len;
11966 }
11967
11968 /* Var-size header len includes len itself */
11969 int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);
11970 rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);
11971
11972 /* Write var-sized payload, if any */
11973 if ((vhpayloadlen > 0) &&
11974 (rc == 0))
11975 {
11976 /* Add tag and extra row info */
11977 uchar type_code= RW_V_EXTRAINFO_TAG;
11978 rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);
11979 if (rc==0)
11980 rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
11981 }
11982 }
11983 else
11984 {
11985 rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);
11986 }
11987
11988 return (rc != 0);
11989 }
11990
write_data_body(IO_CACHE * file)11991 bool Rows_log_event::write_data_body(IO_CACHE*file)
11992 {
11993 /*
11994 Note that this should be the number of *bits*, not the number of
11995 bytes.
11996 */
11997 uchar sbuf[sizeof(m_width) + 1];
11998 my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
11999 bool res= false;
12000 uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
12001 DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
12002
12003 DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
12004 res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
12005
12006 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
12007 res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
12008 no_bytes_in_map(&m_cols));
12009 /*
12010 TODO[refactor write]: Remove the "down cast" here (and elsewhere).
12011 */
12012 if (get_general_type_code() == UPDATE_ROWS_EVENT)
12013 {
12014 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
12015 no_bytes_in_map(&m_cols_ai));
12016 res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
12017 no_bytes_in_map(&m_cols_ai));
12018 }
12019 DBUG_DUMP("rows", m_rows_buf, data_size);
12020 res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
12021
12022 return res;
12023
12024 }
12025 #endif
12026
12027 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12028 int Rows_log_event::pack_info(Protocol *protocol)
12029 {
12030 char buf[256];
12031 char const *const flagstr=
12032 get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
12033 size_t bytes= my_snprintf(buf, sizeof(buf),
12034 "table_id: %llu%s", m_table_id.id(), flagstr);
12035 protocol->store(buf, bytes, &my_charset_bin);
12036 return 0;
12037 }
12038 #endif
12039
12040 #ifdef MYSQL_CLIENT
print_helper(FILE * file,PRINT_EVENT_INFO * print_event_info,char const * const name)12041 void Rows_log_event::print_helper(FILE *file,
12042 PRINT_EVENT_INFO *print_event_info,
12043 char const *const name)
12044 {
12045 IO_CACHE *const head= &print_event_info->head_cache;
12046 IO_CACHE *const body= &print_event_info->body_cache;
12047 if (!print_event_info->short_form)
12048 {
12049 bool const last_stmt_event= get_flags(STMT_END_F);
12050 print_header(head, print_event_info, !last_stmt_event);
12051 my_b_printf(head, "\t%s: table id %llu%s\n",
12052 name, m_table_id.id(),
12053 last_stmt_event ? " flags: STMT_END_F" : "");
12054 print_base64(body, print_event_info, !last_stmt_event);
12055 }
12056 }
12057 #endif
12058
12059 /**************************************************************************
12060 Table_map_log_event member functions and support functions
12061 **************************************************************************/
12062
12063 /**
12064 @page How replication of field metadata works.
12065
12066 When a table map is created, the master first calls
12067 Table_map_log_event::save_field_metadata() which calculates how many
12068 values will be in the field metadata. Only those fields that require the
12069 extra data are added. The method also loops through all of the fields in
12070 the table calling the method Field::save_field_metadata() which returns the
12071 values for the field that will be saved in the metadata and replicated to
12072 the slave. Once all fields have been processed, the table map is written to
12073 the binlog adding the size of the field metadata and the field metadata to
12074 the end of the body of the table map.
12075
12076 When a table map is read on the slave, the field metadata is read from the
12077 table map and passed to the table_def class constructor which saves the
12078 field metadata from the table map into an array based on the type of the
12079 field. Field metadata values not present (those fields that do not use extra
12080 data) in the table map are initialized as zero (0). The array size is the
12081 same as the columns for the table on the slave.
12082
12083 Additionally, values saved for field metadata on the master are saved as a
12084 string of bytes (uchar) in the binlog. A field may require 1 or more bytes
12085 to store the information. In cases where values require multiple bytes
12086 (e.g. values > 255), the endian-safe methods are used to properly encode
12087 the values on the master and decode them on the slave. When the field
12088 metadata values are captured on the slave, they are stored in an array of
12089 type uint16. This allows the least number of casts to prevent casting bugs
12090 when the field metadata is used in comparisons of field attributes. When
12091 the field metadata is used for calculating addresses in pointer math, the
12092 type used is uint32.
12093 */
12094
12095 #if !defined(MYSQL_CLIENT)
12096 /**
12097 Save the field metadata based on the real_type of the field.
12098 The metadata saved depends on the type of the field. Some fields
12099 store a single byte for pack_length() while others store two bytes
12100 for field_length (max length).
12101
12102 @retval 0 Ok.
12103
12104 @todo
12105 We may want to consider changing the encoding of the information.
12106 Currently, the code attempts to minimize the number of bytes written to
12107 the tablemap. There are at least two other alternatives; 1) using
12108 net_store_length() to store the data allowing it to choose the number of
12109 bytes that are appropriate thereby making the code much easier to
12110 maintain (only 1 place to change the encoding), or 2) use a fixed number
12111 of bytes for each field. The problem with option 1 is that net_store_length()
12112 will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
12113 for fields like CHAR which can be no larger than 255 characters, the method
12114 will use 3 bytes when the value is > 250. Further, every value that is
12115 encoded using 2 parts (e.g., pack_length, field_length) will be numerically
12116 > 250 therefore will use 3 bytes for eah value. The problem with option 2
12117 is less wasteful for space but does waste 1 byte for every field that does
12118 not encode 2 parts.
12119 */
save_field_metadata()12120 int Table_map_log_event::save_field_metadata()
12121 {
12122 DBUG_ENTER("Table_map_log_event::save_field_metadata");
12123 int index= 0;
12124 for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
12125 {
12126 DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
12127 index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
12128 }
12129 DBUG_RETURN(index);
12130 }
12131 #endif /* !defined(MYSQL_CLIENT) */
12132
12133 /*
12134 Constructor used to build an event for writing to the binary log.
12135 Mats says tbl->s lives longer than this event so it's ok to copy pointers
12136 (tbl->s->db etc) and not pointer content.
12137 */
12138 #if !defined(MYSQL_CLIENT)
Table_map_log_event(THD * thd,TABLE * tbl,const Table_id & tid,bool using_trans)12139 Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl,
12140 const Table_id& tid,
12141 bool using_trans)
12142 : Log_event(thd, 0,
12143 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
12144 Log_event::EVENT_STMT_CACHE,
12145 Log_event::EVENT_NORMAL_LOGGING),
12146 m_table(tbl),
12147 m_dbnam(tbl->s->db.str),
12148 m_dblen(m_dbnam ? tbl->s->db.length : 0),
12149 m_tblnam(tbl->s->table_name.str),
12150 m_tbllen(tbl->s->table_name.length),
12151 m_colcnt(tbl->s->fields),
12152 m_memory(NULL),
12153 m_table_id(tid),
12154 m_flags(TM_BIT_LEN_EXACT_F),
12155 m_data_size(0),
12156 m_field_metadata(0),
12157 m_field_metadata_size(0),
12158 m_null_bits(0),
12159 m_meta_memory(NULL)
12160 {
12161 uchar cbuf[sizeof(m_colcnt) + 1];
12162 uchar *cbuf_end;
12163 DBUG_ASSERT(m_table_id.is_valid());
12164 /*
12165 In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
12166 table.cc / alloc_table_share():
12167 Use the fact the key is db/0/table_name/0
12168 As we rely on this let's assert it.
12169 */
12170 DBUG_ASSERT((tbl->s->db.str == 0) ||
12171 (tbl->s->db.str[tbl->s->db.length] == 0));
12172 DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
12173
12174
12175 m_data_size= TABLE_MAP_HEADER_LEN;
12176 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
12177 m_data_size+= m_dblen + 2; // Include length and terminating \0
12178 m_data_size+= m_tbllen + 2; // Include length and terminating \0
12179 cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12180 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12181 m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
12182
12183 /* If malloc fails, caught in is_valid() */
12184 if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
12185 {
12186 m_coltype= reinterpret_cast<uchar*>(m_memory);
12187 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12188 m_coltype[i]= m_table->field[i]->binlog_type();
12189 }
12190
12191 /*
12192 Calculate a bitmap for the results of maybe_null() for all columns.
12193 The bitmap is used to determine when there is a column from the master
12194 that is not on the slave and is null and thus not in the row data during
12195 replication.
12196 */
12197 uint num_null_bytes= (m_table->s->fields + 7) / 8;
12198 m_data_size+= num_null_bytes;
12199 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12200 &m_null_bits, num_null_bytes,
12201 &m_field_metadata, (m_colcnt * 2),
12202 NULL);
12203
12204 memset(m_field_metadata, 0, (m_colcnt * 2));
12205
12206 /*
12207 Create an array for the field metadata and store it.
12208 */
12209 m_field_metadata_size= save_field_metadata();
12210 DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
12211
12212 /*
12213 Now set the size of the data to the size of the field metadata array
12214 plus one or three bytes (see pack.c:net_store_length) for number of
12215 elements in the field metadata array.
12216 */
12217 if (m_field_metadata_size < 251)
12218 m_data_size+= m_field_metadata_size + 1;
12219 else
12220 m_data_size+= m_field_metadata_size + 3;
12221
12222 memset(m_null_bits, 0, num_null_bytes);
12223 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12224 if (m_table->field[i]->maybe_null())
12225 m_null_bits[(i / 8)]+= 1 << (i % 8);
12226 /*
12227 Marking event to require sequential execution in MTS
12228 if the query might have updated FK-referenced db.
12229 Unlike Query_log_event where this fact is encoded through
12230 the accessed db list in the Table_map case m_flags is exploited.
12231 */
12232 uchar dbs= thd->get_binlog_accessed_db_names() ?
12233 thd->get_binlog_accessed_db_names()->elements : 0;
12234 if (dbs == 1)
12235 {
12236 char *db_name= thd->get_binlog_accessed_db_names()->head();
12237 if (!strcmp(db_name, ""))
12238 m_flags |= TM_REFERRED_FK_DB_F;
12239 }
12240 }
12241 #endif /* !defined(MYSQL_CLIENT) */
12242
12243 /*
12244 Constructor used by slave to read the event from the binary log.
12245 */
12246 #if defined(HAVE_REPLICATION)
Table_map_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12247 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
12248 const Format_description_log_event
12249 *description_event)
12250
12251 : Log_event(buf, description_event),
12252 #ifndef MYSQL_CLIENT
12253 m_table(NULL),
12254 #endif
12255 m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
12256 m_colcnt(0), m_coltype(0),
12257 m_memory(NULL), m_table_id(ULONGLONG_MAX), m_flags(0),
12258 m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
12259 m_null_bits(0), m_meta_memory(NULL)
12260 {
12261 unsigned int bytes_read= 0;
12262 DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
12263
12264 uint8 common_header_len= description_event->common_header_len;
12265 uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
12266 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
12267 event_len, common_header_len, post_header_len));
12268
12269 /*
12270 Don't print debug messages when running valgrind since they can
12271 trigger false warnings.
12272 */
12273 #ifndef HAVE_purify
12274 DBUG_DUMP("event buffer", (uchar*) buf, event_len);
12275 #endif
12276
12277 /* Read the post-header */
12278 const char *post_start= buf + common_header_len;
12279
12280 post_start+= TM_MAPID_OFFSET;
12281 if (post_header_len == 6)
12282 {
12283 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
12284 m_table_id= uint4korr(post_start);
12285 post_start+= 4;
12286 }
12287 else
12288 {
12289 DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
12290 m_table_id= uint6korr(post_start);
12291 post_start+= TM_FLAGS_OFFSET;
12292 }
12293
12294 m_flags= uint2korr(post_start);
12295
12296 /* Read the variable part of the event */
12297 const char *const vpart= buf + common_header_len + post_header_len;
12298
12299 /* Extract the length of the various parts from the buffer */
12300 uchar const *const ptr_dblen= (uchar const*)vpart + 0;
12301 m_dblen= *(uchar*) ptr_dblen;
12302
12303 /* Length of database name + counter + terminating null */
12304 uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
12305 m_tbllen= *(uchar*) ptr_tbllen;
12306
12307 /* Length of table name + counter + terminating null */
12308 uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
12309 uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
12310 m_colcnt= net_field_length(&ptr_after_colcnt);
12311
12312 DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
12313 (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
12314 (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
12315 m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
12316
12317 bytes_read= (unsigned int) (ptr_after_colcnt - (unsigned char *)buf);
12318 /* Avoid reading out of buffer */
12319 if (event_len <= bytes_read || event_len - bytes_read < m_colcnt)
12320 {
12321 m_coltype= NULL;
12322 m_memory= NULL;
12323 DBUG_VOID_RETURN;
12324 }
12325
12326 /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
12327 m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12328 &m_dbnam, (uint) m_dblen + 1,
12329 &m_tblnam, (uint) m_tbllen + 1,
12330 &m_coltype, (uint) m_colcnt,
12331 NullS);
12332
12333 if (m_memory)
12334 {
12335 /* Copy the different parts into their memory */
12336 strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
12337 strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
12338 memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
12339
12340 ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
12341 bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
12342 DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
12343 if (bytes_read < event_len)
12344 {
12345 m_field_metadata_size= net_field_length(&ptr_after_colcnt);
12346 if (m_field_metadata_size <= (m_colcnt * 2))
12347 {
12348 uint num_null_bytes= (m_colcnt + 7) / 8;
12349 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12350 &m_null_bits, num_null_bytes,
12351 &m_field_metadata, m_field_metadata_size,
12352 NULL);
12353 memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
12354 ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
12355 memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
12356 }
12357 else
12358 {
12359 m_coltype= NULL;
12360 my_free(m_memory);
12361 m_memory= NULL;
12362 DBUG_VOID_RETURN;
12363 }
12364 }
12365 }
12366
12367 DBUG_VOID_RETURN;
12368 }
12369 #endif
12370
~Table_map_log_event()12371 Table_map_log_event::~Table_map_log_event()
12372 {
12373 if (m_meta_memory != NULL)
12374 my_free(m_meta_memory);
12375 if (m_memory != NULL)
12376 my_free(m_memory);
12377 }
12378
12379 /*
12380 Return value is an error code, one of:
12381
12382 -1 Failure to open table [from open_tables()]
12383 0 Success
12384 1 No room for more tables [from set_table()]
12385 2 Out of memory [from set_table()]
12386 3 Wrong table definition
12387 4 Daisy-chaining RBR with SBR not possible
12388 */
12389
12390 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12391
12392 enum enum_tbl_map_status
12393 {
12394 /* no duplicate identifier found */
12395 OK_TO_PROCESS= 0,
12396
12397 /* this table map must be filtered out */
12398 FILTERED_OUT= 1,
12399
12400 /* identifier mapping table with different properties */
12401 SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
12402
12403 /* a duplicate identifier was found mapping the same table */
12404 SAME_ID_MAPPING_SAME_TABLE= 3
12405 };
12406
12407 /*
12408 Checks if this table map event should be processed or not. First
12409 it checks the filtering rules, and then looks for duplicate identifiers
12410 in the existing list of rli->tables_to_lock.
12411
12412 It checks that there hasn't been any corruption by verifying that there
12413 are no duplicate entries with different properties.
12414
12415 In some cases, some binary logs could get corrupted, showing several
12416 tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
12417 early sanity check for such cases and avoid that the server crashes
12418 later.
12419
12420 In some corner cases, the master logs duplicate table map events, i.e.,
12421 same id, same database name, same table name (see: BUG#37137). This is
12422 different from the above as it's the same table that is mapped again
12423 to the same identifier. Thus we cannot just check for same ids and
12424 assume that the event is corrupted we need to check every property.
12425
12426 NOTE: in the event that BUG#37137 ever gets fixed, this extra check
12427 will still be valid because we would need to support old binary
12428 logs anyway.
12429
12430 @param rli The relay log info reference.
12431 @param table_list A list element containing the table to check against.
12432 @return OK_TO_PROCESS
12433 if there was no identifier already in rli->tables_to_lock
12434
12435 FILTERED_OUT
12436 if the event is filtered according to the filtering rules
12437
12438 SAME_ID_MAPPING_DIFFERENT_TABLE
12439 if the same identifier already maps a different table in
12440 rli->tables_to_lock
12441
12442 SAME_ID_MAPPING_SAME_TABLE
12443 if the same identifier already maps the same table in
12444 rli->tables_to_lock.
12445 */
12446 static enum_tbl_map_status
check_table_map(Relay_log_info const * rli,RPL_TABLE_LIST * table_list)12447 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
12448 {
12449 DBUG_ENTER("check_table_map");
12450 enum_tbl_map_status res= OK_TO_PROCESS;
12451
12452 #ifdef WITH_WSREP
12453 if ((rli->info_thd->slave_thread /* filtering is for slave only */ ||
12454 (WSREP(rli->info_thd) && rli->info_thd->wsrep_applier)) &&
12455 #else
12456 if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
12457 #endif /* WITH_WSREP */
12458 (!rpl_filter->db_ok(table_list->db) ||
12459 (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
12460 res= FILTERED_OUT;
12461 else
12462 {
12463 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
12464 for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
12465 ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
12466 {
12467 if (ptr->table_id == table_list->table_id)
12468 {
12469
12470 if (strcmp(ptr->db, table_list->db) ||
12471 strcmp(ptr->alias, table_list->table_name) ||
12472 ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
12473 res= SAME_ID_MAPPING_DIFFERENT_TABLE;
12474 else
12475 res= SAME_ID_MAPPING_SAME_TABLE;
12476
12477 break;
12478 }
12479 }
12480 }
12481
12482 DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
12483
12484 DBUG_RETURN(res);
12485 }
12486
do_apply_event(Relay_log_info const * rli)12487 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
12488 {
12489 RPL_TABLE_LIST *table_list;
12490 char *db_mem, *tname_mem, *ptr;
12491 size_t dummy_len;
12492 void *memory;
12493 DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
12494 DBUG_ASSERT(rli->info_thd == thd);
12495
12496 /* Step the query id to mark what columns that are actually used. */
12497 thd->set_query_id(next_query_id());
12498
12499 if (!(memory= my_multi_malloc(MYF(MY_WME),
12500 &table_list, (uint) sizeof(RPL_TABLE_LIST),
12501 &db_mem, (uint) NAME_LEN + 1,
12502 &tname_mem, (uint) NAME_LEN + 1,
12503 NullS)))
12504 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
12505
12506 strmov(db_mem, m_dbnam);
12507 strmov(tname_mem, m_tblnam);
12508
12509 if (lower_case_table_names == 1)
12510 {
12511 my_casedn_str(system_charset_info, db_mem);
12512 my_casedn_str(system_charset_info, tname_mem);
12513 }
12514
12515 /* rewrite rules changed the database */
12516 if (((ptr= (char*) rpl_filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem))
12517 strmov(db_mem, ptr);
12518
12519 table_list->init_one_table(db_mem, strlen(db_mem),
12520 tname_mem, strlen(tname_mem),
12521 tname_mem, TL_WRITE);
12522
12523 table_list->table_id=
12524 DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id.id());
12525 table_list->updating= 1;
12526 table_list->required_type= FRMTYPE_TABLE;
12527 DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name,
12528 table_list->table_id.id()));
12529
12530 enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
12531 if (tblmap_status == OK_TO_PROCESS)
12532 {
12533 DBUG_ASSERT(thd->lex->query_tables != table_list);
12534
12535 /*
12536 Use placement new to construct the table_def instance in the
12537 memory allocated for it inside table_list.
12538
12539 The memory allocated by the table_def structure (i.e., not the
12540 memory allocated *for* the table_def structure) is released
12541 inside Relay_log_info::clear_tables_to_lock() by calling the
12542 table_def destructor explicitly.
12543 */
12544 new (&table_list->m_tabledef)
12545 table_def(m_coltype, m_colcnt,
12546 m_field_metadata, m_field_metadata_size,
12547 m_null_bits, m_flags);
12548 table_list->m_tabledef_valid= TRUE;
12549 table_list->m_conv_table= NULL;
12550 table_list->open_type= OT_BASE_ONLY;
12551
12552 /*
12553 We record in the slave's information that the table should be
12554 locked by linking the table into the list of tables to lock.
12555 */
12556 table_list->next_global= table_list->next_local= rli->tables_to_lock;
12557 const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
12558 const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
12559 /* 'memory' is freed in clear_tables_to_lock */
12560 }
12561 else // FILTERED_OUT, SAME_ID_MAPPING_*
12562 {
12563 /*
12564 If mapped already but with different properties, we raise an
12565 error.
12566 If mapped already but with same properties we skip the event.
12567 If filtered out we skip the event.
12568
12569 In all three cases, we need to free the memory previously
12570 allocated.
12571 */
12572 if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
12573 {
12574 /*
12575 Something bad has happened. We need to stop the slave as strange things
12576 could happen if we proceed: slave crash, wrong table being updated, ...
12577 As a consequence we push an error in this case.
12578 */
12579
12580 char buf[256];
12581
12582 my_snprintf(buf, sizeof(buf),
12583 "Found table map event mapping table id %llu which "
12584 "was already mapped but with different settings.",
12585 table_list->table_id.id());
12586
12587 if (thd->slave_thread)
12588 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
12589 ER(ER_SLAVE_FATAL_ERROR), buf);
12590 else
12591 /*
12592 For the cases in which a 'BINLOG' statement is set to
12593 execute in a user session
12594 */
12595 my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
12596 MYF(0), buf);
12597 }
12598
12599 my_free(memory);
12600 }
12601
12602 DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12603 }
12604
12605 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)12606 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
12607 {
12608 /*
12609 If the slave skip counter is 1, then we should not start executing
12610 on the next event.
12611 */
12612 return continue_group(rli);
12613 }
12614
do_update_pos(Relay_log_info * rli)12615 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
12616 {
12617 rli->inc_event_relay_log_pos();
12618 return 0;
12619 }
12620
12621 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12622
12623 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)12624 bool Table_map_log_event::write_data_header(IO_CACHE *file)
12625 {
12626 DBUG_ASSERT(m_table_id.is_valid());
12627 uchar buf[TABLE_MAP_HEADER_LEN];
12628 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12629 {
12630 int4store(buf + 0, m_table_id.id());
12631 int2store(buf + 4, m_flags);
12632 return (wrapper_my_b_safe_write(file, buf, 6));
12633 });
12634 int6store(buf + TM_MAPID_OFFSET, m_table_id.id());
12635 int2store(buf + TM_FLAGS_OFFSET, m_flags);
12636 return (wrapper_my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
12637 }
12638
write_data_body(IO_CACHE * file)12639 bool Table_map_log_event::write_data_body(IO_CACHE *file)
12640 {
12641 DBUG_ASSERT(m_dbnam != NULL);
12642 DBUG_ASSERT(m_tblnam != NULL);
12643 /* We use only one byte per length for storage in event: */
12644 DBUG_ASSERT(m_dblen < 128);
12645 DBUG_ASSERT(m_tbllen < 128);
12646
12647 uchar const dbuf[]= { (uchar) m_dblen };
12648 uchar const tbuf[]= { (uchar) m_tbllen };
12649
12650 uchar cbuf[sizeof(m_colcnt) + 1];
12651 uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12652 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12653
12654 /*
12655 Store the size of the field metadata.
12656 */
12657 uchar mbuf[sizeof(m_field_metadata_size)];
12658 uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12659
12660 return (wrapper_my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
12661 wrapper_my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
12662 wrapper_my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
12663 wrapper_my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
12664 wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
12665 wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
12666 wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
12667 wrapper_my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
12668 wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
12669 }
12670 #endif
12671
12672 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12673
12674 /*
12675 Print some useful information for the SHOW BINARY LOG information
12676 field.
12677 */
12678
12679 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12680 int Table_map_log_event::pack_info(Protocol *protocol)
12681 {
12682 char buf[256];
12683 size_t bytes= my_snprintf(buf, sizeof(buf),
12684 "table_id: %llu (%s.%s)",
12685 m_table_id.id(), m_dbnam, m_tblnam);
12686 protocol->store(buf, bytes, &my_charset_bin);
12687 return 0;
12688 }
12689 #endif
12690
12691
12692 #endif
12693
12694
12695 #ifdef MYSQL_CLIENT
print(FILE *,PRINT_EVENT_INFO * print_event_info)12696 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
12697 {
12698 if (!print_event_info->short_form)
12699 {
12700 print_header(&print_event_info->head_cache, print_event_info, TRUE);
12701 my_b_printf(&print_event_info->head_cache,
12702 "\tTable_map: `%s`.`%s` mapped to number %llu\n",
12703 m_dbnam, m_tblnam, m_table_id.id());
12704 print_base64(&print_event_info->body_cache, print_event_info, TRUE);
12705 }
12706 }
12707 #endif
12708
12709 /**************************************************************************
12710 Write_rows_log_event member functions
12711 **************************************************************************/
12712
12713 /*
12714 Constructor used to build an event for writing to the binary log.
12715 */
12716 #if !defined(MYSQL_CLIENT)
Write_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid_arg,bool is_transactional,const uchar * extra_row_info)12717 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12718 const Table_id& tid_arg,
12719 bool is_transactional,
12720 const uchar* extra_row_info)
12721 : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
12722 log_bin_use_v1_row_events?
12723 WRITE_ROWS_EVENT_V1:
12724 WRITE_ROWS_EVENT,
12725 extra_row_info)
12726 {
12727 }
12728 #endif
12729
12730 /*
12731 Constructor used by slave to read the event from the binary log.
12732 */
12733 #ifdef HAVE_REPLICATION
Write_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12734 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12735 const Format_description_log_event
12736 *description_event)
12737 : Rows_log_event(buf, event_len, description_event)
12738 {
12739 }
12740 #endif
12741
12742 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12743 int
do_before_row_operations(const Slave_reporting_capability * const)12744 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12745 {
12746 int error= 0;
12747
12748 /*
12749 Increment the global status insert count variable
12750 */
12751 if (get_flags(STMT_END_F))
12752 status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
12753
12754 /*
12755 Let storage engines treat this event as an INSERT command.
12756
12757 Set 'sql_command' as SQLCOM_INSERT after the tables are locked.
12758 When locking the tables, it should be SQLCOM_END.
12759 THD::decide_binlog_format which is called from "lock tables"
12760 assumes that row_events will have 'sql_command' as SQLCOM_END.
12761 */
12762 thd->lex->sql_command= SQLCOM_INSERT;
12763
12764 /**
12765 todo: to introduce a property for the event (handler?) which forces
12766 applying the event in the replace (idempotent) fashion.
12767 */
12768 if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12769 (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
12770 {
12771 /*
12772 We are using REPLACE semantics and not INSERT IGNORE semantics
12773 when writing rows, that is: new rows replace old rows. We need to
12774 inform the storage engine that it should use this behaviour.
12775 */
12776
12777 /* Tell the storage engine that we are using REPLACE semantics. */
12778 thd->lex->duplicates= DUP_REPLACE;
12779
12780 /*
12781 Pretend we're executing a REPLACE command: this is needed for
12782 InnoDB and NDB Cluster since they are not (properly) checking the
12783 lex->duplicates flag.
12784 */
12785 thd->lex->sql_command= SQLCOM_REPLACE;
12786 /*
12787 Do not raise the error flag in case of hitting to an unique attribute
12788 */
12789 m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12790 /*
12791 NDB specific: update from ndb master wrapped as Write_rows
12792 so that the event should be applied to replace slave's row
12793 */
12794 m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12795 /*
12796 NDB specific: if update from ndb master wrapped as Write_rows
12797 does not find the row it's assumed idempotent binlog applying
12798 is taking place; don't raise the error.
12799 */
12800 m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12801 /*
12802 TODO: the cluster team (Tomas?) says that it's better if the engine knows
12803 how many rows are going to be inserted, then it can allocate needed memory
12804 from the start.
12805 */
12806 }
12807
12808
12809 /* Honor next number column if present */
12810 m_table->next_number_field= m_table->found_next_number_field;
12811 /*
12812 * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12813 * sequence numbers for auto_increment fields if the values of them are 0.
12814 * If generateing a sequence number is decided by the values of
12815 * table->auto_increment_field_not_null and SQL_MODE(if includes
12816 * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12817 * SQL_MODE of slave sql thread is always consistency with master's.
12818 * In RBR, auto_increment fields never are NULL, except if the auto_inc
12819 * column exists only on the slave side (i.e., in an extra column
12820 * on the slave's table).
12821 */
12822 if (!is_auto_inc_in_extra_columns())
12823 m_table->auto_increment_field_not_null= TRUE;
12824 else
12825 {
12826 /*
12827 Here we have checked that there is an extra field
12828 on this server's table that has an auto_inc column.
12829
12830 Mark that the auto_increment field is null and mark
12831 the read and write set bits.
12832
12833 (There can only be one AUTO_INC column, it is always
12834 indexed and it cannot have a DEFAULT value).
12835 */
12836 m_table->auto_increment_field_not_null= FALSE;
12837 m_table->mark_auto_increment_column();
12838 }
12839
12840 /**
12841 Sets it to ROW_LOOKUP_NOT_NEEDED.
12842 */
12843 decide_row_lookup_algorithm_and_key();
12844 DBUG_ASSERT(m_rows_lookup_algorithm==ROW_LOOKUP_NOT_NEEDED);
12845
12846 return error;
12847 }
12848
12849 int
do_after_row_operations(const Slave_reporting_capability * const,int error)12850 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12851 int error)
12852 {
12853 int local_error= 0;
12854
12855 /**
12856 Clear the write_set bit for auto_inc field that only
12857 existed on the destination table as an extra column.
12858 */
12859 if (is_auto_inc_in_extra_columns())
12860 {
12861 bitmap_clear_bit(m_table->write_set, m_table->next_number_field->field_index);
12862 bitmap_clear_bit( m_table->read_set, m_table->next_number_field->field_index);
12863
12864 if (get_flags(STMT_END_F))
12865 m_table->file->ha_release_auto_increment();
12866 }
12867 m_table->next_number_field=0;
12868 m_table->auto_increment_field_not_null= FALSE;
12869 if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12870 m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
12871 {
12872 m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
12873 m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
12874 /*
12875 resetting the extra with
12876 table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
12877 fires bug#27077
12878 explanation: file->reset() performs this duty
12879 ultimately. Still todo: fix
12880 */
12881 }
12882 if ((local_error= m_table->file->ha_end_bulk_insert()))
12883 {
12884 m_table->file->print_error(local_error, MYF(0));
12885 }
12886
12887 m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
12888
12889 return error? error : local_error;
12890 }
12891
12892 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12893
12894 /*
12895 Check if there are more UNIQUE keys after the given key.
12896 */
12897 static int
last_uniq_key(TABLE * table,uint keyno)12898 last_uniq_key(TABLE *table, uint keyno)
12899 {
12900 while (++keyno < table->s->keys)
12901 if (table->key_info[keyno].flags & HA_NOSAME)
12902 return 0;
12903 return 1;
12904 }
12905
12906 /**
12907 Check if an error is a duplicate key error.
12908
12909 This function is used to check if an error code is one of the
12910 duplicate key error, i.e., and error code for which it is sensible
12911 to do a <code>get_dup_key()</code> to retrieve the duplicate key.
12912
12913 @param errcode The error code to check.
12914
12915 @return <code>true</code> if the error code is such that
12916 <code>get_dup_key()</code> will return true, <code>false</code>
12917 otherwise.
12918 */
12919 bool
is_duplicate_key_error(int errcode)12920 is_duplicate_key_error(int errcode)
12921 {
12922 switch (errcode)
12923 {
12924 case HA_ERR_FOUND_DUPP_KEY:
12925 case HA_ERR_FOUND_DUPP_UNIQUE:
12926 return true;
12927 }
12928 return false;
12929 }
12930
12931 /**
12932 Write the current row into event's table.
12933
12934 The row is located in the row buffer, pointed by @c m_curr_row member.
12935 Number of columns of the row is stored in @c m_width member (it can be
12936 different from the number of columns in the table to which we insert).
12937 Bitmap @c m_cols indicates which columns are present in the row. It is assumed
12938 that event's table is already open and pointed by @c m_table.
12939
12940 If the same record already exists in the table it can be either overwritten
12941 or an error is reported depending on the value of @c overwrite flag
12942 (error reporting not yet implemented). Note that the matching record can be
12943 different from the row we insert if we use primary keys to identify records in
12944 the table.
12945
12946 The row to be inserted can contain values only for selected columns. The
12947 missing columns are filled with default values using @c prepare_record()
12948 function. If a matching record is found in the table and @c overwritte is
12949 true, the missing columns are taken from it.
12950
12951 @param rli Relay log info (needed for row unpacking).
12952 @param overwrite
12953 Shall we overwrite if the row already exists or signal
12954 error (currently ignored).
12955
12956 @returns Error code on failure, 0 on success.
12957
12958 This method, if successful, sets @c m_curr_row_end pointer to point at the
12959 next row in the rows buffer. This is done when unpacking the row to be
12960 inserted.
12961
12962 @note If a matching record is found, it is either updated using
12963 @c ha_update_row() or first deleted and then new record written.
12964 */
12965
12966 int
write_row(const Relay_log_info * const rli,const bool overwrite)12967 Write_rows_log_event::write_row(const Relay_log_info *const rli,
12968 const bool overwrite)
12969 {
12970 DBUG_ENTER("write_row");
12971 DBUG_ASSERT(m_table != NULL && thd != NULL);
12972
12973 TABLE *table= m_table; // pointer to event's table
12974 int error;
12975 int UNINIT_VAR(keynum);
12976 auto_afree_ptr<char> key(NULL);
12977
12978 prepare_record(table, &m_cols,
12979 table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
12980
12981 /* unpack row into table->record[0] */
12982 if ((error= unpack_current_row(rli, &m_cols)))
12983 DBUG_RETURN(error);
12984
12985 /*
12986 When m_curr_row == m_curr_row_end, it means a row that contains nothing,
12987 so all the pointers shall be pointing to the same address, or else
12988 we have corrupt data and shall throw the error.
12989 */
12990 DBUG_PRINT("debug",("m_rows_buf= %p, m_rows_cur= %p, m_rows_end= %p",
12991 m_rows_buf, m_rows_cur, m_rows_end));
12992 DBUG_PRINT("debug",("m_curr_row= %p, m_curr_row_end= %p",
12993 m_curr_row, m_curr_row_end));
12994 if (m_curr_row == m_curr_row_end &&
12995 !((m_rows_buf == m_rows_cur) && (m_rows_cur == m_rows_end)))
12996 {
12997 my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
12998 DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
12999 }
13000
13001 if (m_curr_row == m_rows_buf)
13002 {
13003 /* this is the first row to be inserted, we estimate the rows with
13004 the size of the first row and use that value to initialize
13005 storage engine for bulk insertion */
13006 DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
13007 ulong estimated_rows= 0;
13008 if (m_curr_row < m_curr_row_end)
13009 estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
13010 else if (m_curr_row == m_curr_row_end)
13011 estimated_rows= 1;
13012
13013 m_table->file->ha_start_bulk_insert(estimated_rows);
13014 }
13015
13016 /*
13017 Explicitly set the auto_inc to null to make sure that
13018 it gets an auto_generated value.
13019 */
13020 if (is_auto_inc_in_extra_columns())
13021 m_table->next_number_field->set_null();
13022
13023 #ifndef DBUG_OFF
13024 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13025 DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
13026 DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
13027 #endif
13028
13029 /*
13030 Try to write record. If a corresponding record already exists in the table,
13031 we try to change it using ha_update_row() if possible. Otherwise we delete
13032 it and repeat the whole process again.
13033
13034 TODO: Add safety measures against infinite looping.
13035 */
13036
13037 m_table->mark_columns_per_binlog_row_image();
13038
13039 while ((error= table->file->ha_write_row(table->record[0])))
13040 {
13041 if (error == HA_ERR_LOCK_DEADLOCK ||
13042 error == HA_ERR_LOCK_WAIT_TIMEOUT ||
13043 (keynum= table->file->get_dup_key(error)) < 0 ||
13044 !overwrite)
13045 {
13046 DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
13047 /*
13048 Deadlock, waiting for lock or just an error from the handler
13049 such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
13050 Retrieval of the duplicate key number may fail
13051 - either because the error was not "duplicate key" error
13052 - or because the information which key is not available
13053 */
13054 table->file->print_error(error, MYF(0));
13055 goto error;
13056 }
13057 /*
13058 We need to retrieve the old row into record[1] to be able to
13059 either update or delete the offending record. We either:
13060
13061 - use ha_rnd_pos() with a row-id (available as dupp_row) to the
13062 offending row, if that is possible (MyISAM and Blackhole), or else
13063
13064 - use ha_index_read_idx_map() with the key that is duplicated, to
13065 retrieve the offending row.
13066 */
13067 if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
13068 {
13069 DBUG_PRINT("info",("Locating offending record using ha_rnd_pos()"));
13070
13071 if (table->file->inited && (error= table->file->ha_index_end()))
13072 {
13073 table->file->print_error(error, MYF(0));
13074 goto error;
13075 }
13076 if ((error= table->file->ha_rnd_init(FALSE)))
13077 {
13078 table->file->print_error(error, MYF(0));
13079 goto error;
13080 }
13081
13082 error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
13083
13084 table->file->ha_rnd_end();
13085 if (error)
13086 {
13087 DBUG_PRINT("info",("ha_rnd_pos() returns error %d",error));
13088 if (error == HA_ERR_RECORD_DELETED)
13089 error= HA_ERR_KEY_NOT_FOUND;
13090 table->file->print_error(error, MYF(0));
13091 goto error;
13092 }
13093 }
13094 else
13095 {
13096 DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
13097
13098 if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
13099 {
13100 DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
13101 error= my_errno;
13102 goto error;
13103 }
13104
13105 if (key.get() == NULL)
13106 {
13107 key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
13108 if (key.get() == NULL)
13109 {
13110 DBUG_PRINT("info",("Can't allocate key buffer"));
13111 error= ENOMEM;
13112 goto error;
13113 }
13114 }
13115
13116 key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
13117 0);
13118 error= table->file->ha_index_read_idx_map(table->record[1], keynum,
13119 (const uchar*)key.get(),
13120 HA_WHOLE_KEY,
13121 HA_READ_KEY_EXACT);
13122 if (error)
13123 {
13124 DBUG_PRINT("info",("ha_index_read_idx_map() returns %s", HA_ERR(error)));
13125 if (error == HA_ERR_RECORD_DELETED)
13126 error= HA_ERR_KEY_NOT_FOUND;
13127 table->file->print_error(error, MYF(0));
13128 goto error;
13129 }
13130 }
13131
13132 /*
13133 Now, record[1] should contain the offending row. That
13134 will enable us to update it or, alternatively, delete it (so
13135 that we can insert the new row afterwards).
13136 */
13137
13138 /*
13139 If row is incomplete we will use the record found to fill
13140 missing columns.
13141 */
13142 if (!get_flags(COMPLETE_ROWS_F))
13143 {
13144 restore_record(table,record[1]);
13145 error= unpack_current_row(rli, &m_cols);
13146 }
13147
13148 #ifndef DBUG_OFF
13149 DBUG_PRINT("debug",("preparing for update: before and after image"));
13150 DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
13151 DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
13152 #endif
13153
13154 /*
13155 REPLACE is defined as either INSERT or DELETE + INSERT. If
13156 possible, we can replace it with an UPDATE, but that will not
13157 work on InnoDB if FOREIGN KEY checks are necessary.
13158
13159 I (Matz) am not sure of the reason for the last_uniq_key()
13160 check as, but I'm guessing that it's something along the
13161 following lines.
13162
13163 Suppose that we got the duplicate key to be a key that is not
13164 the last unique key for the table and we perform an update:
13165 then there might be another key for which the unique check will
13166 fail, so we're better off just deleting the row and inserting
13167 the correct row.
13168 */
13169 if (last_uniq_key(table, keynum) &&
13170 !table->file->referenced_by_foreign_key())
13171 {
13172 DBUG_PRINT("info",("Updating row using ha_update_row()"));
13173 error=table->file->ha_update_row(table->record[1],
13174 table->record[0]);
13175 switch (error) {
13176
13177 case HA_ERR_RECORD_IS_THE_SAME:
13178 DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
13179 " ha_update_row()"));
13180 error= 0;
13181
13182 case 0:
13183 break;
13184
13185 default:
13186 DBUG_PRINT("info",("ha_update_row() returns error %d",error));
13187 table->file->print_error(error, MYF(0));
13188 }
13189
13190 goto error;
13191 }
13192 else
13193 {
13194 DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
13195 if ((error= table->file->ha_delete_row(table->record[1])))
13196 {
13197 DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
13198 table->file->print_error(error, MYF(0));
13199 goto error;
13200 }
13201 /* Will retry ha_write_row() with the offending row removed. */
13202 }
13203 }
13204
13205 error:
13206 m_table->default_column_bitmaps();
13207 DBUG_RETURN(error);
13208 }
13209
13210 #endif
13211
13212 int
do_exec_row(const Relay_log_info * const rli)13213 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13214 {
13215 DBUG_ASSERT(m_table != NULL);
13216 #ifdef WITH_WSREP
13217 #ifdef WSREP_PROC_INFO
13218 char info[64];
13219 info[sizeof(info) - 1] = '\0';
13220 snprintf(info, sizeof(info) - 1, "Write_rows_log_event::write_row(%lld)",
13221 (long long) wsrep_thd_trx_seqno(thd));
13222 const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL;
13223 #else
13224 const char* tmp = (WSREP(thd)) ?
13225 thd_proc_info(thd,"Write_rows_log_event::write_row()") : NULL;
13226 #endif /* WSREP_PROC_INFO */
13227 #endif /* WITH_WSREP */
13228 int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
13229
13230 #ifdef WITH_WSREP
13231 if (WSREP(thd)) thd_proc_info(thd, tmp);
13232 #endif /* WITH_WSREP */
13233 if (error && !thd->is_error())
13234 {
13235 DBUG_ASSERT(0);
13236 my_error(ER_UNKNOWN_ERROR, MYF(0));
13237 }
13238
13239 return error;
13240 }
13241
13242 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13243
13244 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13245 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
13246 {
13247 DBUG_EXECUTE_IF("simulate_cache_read_error",
13248 {DBUG_SET("+d,simulate_my_b_fill_error");});
13249 Rows_log_event::print_helper(file, print_event_info, "Write_rows");
13250 }
13251 #endif
13252
13253 /**************************************************************************
13254 Delete_rows_log_event member functions
13255 **************************************************************************/
13256
13257 /*
13258 Constructor used to build an event for writing to the binary log.
13259 */
13260
13261 #ifndef MYSQL_CLIENT
Delete_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13262 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13263 const Table_id& tid,
13264 bool is_transactional,
13265 const uchar* extra_row_info)
13266 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13267 log_bin_use_v1_row_events?
13268 DELETE_ROWS_EVENT_V1:
13269 DELETE_ROWS_EVENT,
13270 extra_row_info)
13271 {
13272 }
13273 #endif /* #if !defined(MYSQL_CLIENT) */
13274
13275 /*
13276 Constructor used by slave to read the event from the binary log.
13277 */
13278 #ifdef HAVE_REPLICATION
Delete_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13279 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
13280 const Format_description_log_event
13281 *description_event)
13282 : Rows_log_event(buf, event_len, description_event)
13283 {
13284 }
13285 #endif
13286
13287 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13288
13289 int
do_before_row_operations(const Slave_reporting_capability * const)13290 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13291 {
13292 int error= 0;
13293 DBUG_ENTER("Delete_rows_log_event::do_before_row_operations");
13294 /*
13295 Increment the global status delete count variable
13296 */
13297 if (get_flags(STMT_END_F))
13298 status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
13299
13300 /*
13301 Let storage engines treat this event as a DELETE command.
13302
13303 Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13304 When locking the tables, it should be SQLCOM_END.
13305 THD::decide_binlog_format which is called from "lock tables"
13306 assumes that row_events will have 'sql_command' as SQLCOM_END.
13307 */
13308 thd->lex->sql_command= SQLCOM_DELETE;
13309
13310 error= row_operations_scan_and_key_setup();
13311 DBUG_RETURN(error);
13312
13313 }
13314
13315 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13316 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13317 int error)
13318 {
13319 DBUG_ENTER("Delete_rows_log_event::do_after_row_operations");
13320 error= row_operations_scan_and_key_teardown(error);
13321 DBUG_RETURN(error);
13322 }
13323
do_exec_row(const Relay_log_info * const rli)13324 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13325 {
13326 int error;
13327 DBUG_ASSERT(m_table != NULL);
13328 /* m_table->record[0] contains the BI */
13329 m_table->mark_columns_per_binlog_row_image();
13330 error= m_table->file->ha_delete_row(m_table->record[0]);
13331 m_table->default_column_bitmaps();
13332 return error;
13333 }
13334
13335 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13336
13337 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13338 void Delete_rows_log_event::print(FILE *file,
13339 PRINT_EVENT_INFO* print_event_info)
13340 {
13341 Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
13342 }
13343 #endif
13344
13345
13346 /**************************************************************************
13347 Update_rows_log_event member functions
13348 **************************************************************************/
13349
13350 /*
13351 Constructor used to build an event for writing to the binary log.
13352 */
13353 #if !defined(MYSQL_CLIENT)
Update_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13354 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13355 const Table_id& tid,
13356 bool is_transactional,
13357 const uchar* extra_row_info)
13358 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13359 log_bin_use_v1_row_events?
13360 UPDATE_ROWS_EVENT_V1:
13361 UPDATE_ROWS_EVENT,
13362 extra_row_info)
13363 {
13364 init(tbl_arg->write_set);
13365 }
13366
init(MY_BITMAP const * cols)13367 void Update_rows_log_event::init(MY_BITMAP const *cols)
13368 {
13369 /* if bitmap_init fails, caught in is_valid() */
13370 if (likely(!bitmap_init(&m_cols_ai,
13371 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
13372 m_width,
13373 false)))
13374 {
13375 /* Cols can be zero if this is a dummy binrows event */
13376 if (likely(cols != NULL))
13377 {
13378 memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
13379 create_last_word_mask(&m_cols_ai);
13380 }
13381 }
13382 }
13383 #endif /* !defined(MYSQL_CLIENT) */
13384
13385
~Update_rows_log_event()13386 Update_rows_log_event::~Update_rows_log_event()
13387 {
13388 if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
13389 m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
13390 bitmap_free(&m_cols_ai); // To pair with bitmap_init().
13391 }
13392
13393
13394 /*
13395 Constructor used by slave to read the event from the binary log.
13396 */
13397 #ifdef HAVE_REPLICATION
Update_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13398 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
13399 const
13400 Format_description_log_event
13401 *description_event)
13402 : Rows_log_event(buf, event_len, description_event)
13403 {
13404 }
13405 #endif
13406
13407 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13408
13409 int
do_before_row_operations(const Slave_reporting_capability * const)13410 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13411 {
13412 int error= 0;
13413 DBUG_ENTER("Update_rows_log_event::do_before_row_operations");
13414 /*
13415 Increment the global status update count variable
13416 */
13417 if (get_flags(STMT_END_F))
13418 status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
13419
13420 /*
13421 Let storage engines treat this event as an UPDATE command.
13422
13423 Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13424 When locking the tables, it should be SQLCOM_END.
13425 THD::decide_binlog_format which is called from "lock tables"
13426 assumes that row_events will have 'sql_command' as SQLCOM_END.
13427 */
13428 thd->lex->sql_command= SQLCOM_UPDATE;
13429
13430 error= row_operations_scan_and_key_setup();
13431 DBUG_RETURN(error);
13432
13433 }
13434
13435 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13436 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13437 int error)
13438 {
13439 DBUG_ENTER("Update_rows_log_event::do_after_row_operations");
13440 error= row_operations_scan_and_key_teardown(error);
13441 DBUG_RETURN(error);
13442 }
13443
13444 int
do_exec_row(const Relay_log_info * const rli)13445 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13446 {
13447 DBUG_ASSERT(m_table != NULL);
13448 int error= 0;
13449
13450 /*
13451 This is the situation after locating BI:
13452
13453 ===|=== before image ====|=== after image ===|===
13454 ^ ^
13455 m_curr_row m_curr_row_end
13456
13457 BI found in the table is stored in record[0]. We copy it to record[1]
13458 and unpack AI to record[0].
13459 */
13460
13461 store_record(m_table,record[1]);
13462
13463 m_curr_row= m_curr_row_end;
13464 /* this also updates m_curr_row_end */
13465 if ((error= unpack_current_row(rli, &m_cols_ai)))
13466 return error;
13467
13468 /*
13469 Now we have the right row to update. The old row (the one we're
13470 looking for) is in record[1] and the new row is in record[0].
13471 */
13472 #ifndef HAVE_purify
13473 /*
13474 Don't print debug messages when running valgrind since they can
13475 trigger false warnings.
13476 */
13477 DBUG_PRINT("info",("Updating row in table"));
13478 DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
13479 DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
13480 #endif
13481
13482 // Temporary fix to find out why it fails [/Matz]
13483 memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
13484 memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
13485
13486 m_table->mark_columns_per_binlog_row_image();
13487 error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
13488 if (error == HA_ERR_RECORD_IS_THE_SAME)
13489 error= 0;
13490 m_table->default_column_bitmaps();
13491
13492 return error;
13493 }
13494
13495 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13496
13497 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13498 void Update_rows_log_event::print(FILE *file,
13499 PRINT_EVENT_INFO* print_event_info)
13500 {
13501 Rows_log_event::print_helper(file, print_event_info, "Update_rows");
13502 }
13503 #endif
13504
13505
Incident_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13506 Incident_log_event::Incident_log_event(const char *buf, uint event_len,
13507 const Format_description_log_event *descr_event)
13508 : Log_event(buf, descr_event)
13509 {
13510 DBUG_ENTER("Incident_log_event::Incident_log_event");
13511 uint8 const common_header_len=
13512 descr_event->common_header_len;
13513 uint8 const post_header_len=
13514 descr_event->post_header_len[INCIDENT_EVENT-1];
13515
13516 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13517 event_len, common_header_len, post_header_len));
13518
13519 m_message.str= NULL;
13520 m_message.length= 0;
13521 int incident_number= uint2korr(buf + common_header_len);
13522 if (incident_number >= INCIDENT_COUNT ||
13523 incident_number <= INCIDENT_NONE)
13524 {
13525 // If the incident is not recognized, this binlog event is
13526 // invalid. If we set incident_number to INCIDENT_NONE, the
13527 // invalidity will be detected by is_valid().
13528 m_incident= INCIDENT_NONE;
13529 DBUG_VOID_RETURN;
13530 }
13531 m_incident= static_cast<Incident>(incident_number);
13532 char const *ptr= buf + common_header_len + post_header_len;
13533 char const *const str_end= buf + event_len;
13534 uint8 len= 0; // Assignment to keep compiler happy
13535 const char *str= NULL; // Assignment to keep compiler happy
13536 read_str_at_most_255_bytes(&ptr, str_end, &str, &len);
13537 if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
13538 {
13539 /* Mark this event invalid */
13540 m_incident= INCIDENT_NONE;
13541 DBUG_VOID_RETURN;
13542 }
13543 strmake(m_message.str, str, len);
13544 m_message.length= len;
13545 DBUG_PRINT("info", ("m_incident: %d", m_incident));
13546 DBUG_VOID_RETURN;
13547 }
13548
13549
~Incident_log_event()13550 Incident_log_event::~Incident_log_event()
13551 {
13552 if (m_message.str)
13553 my_free(m_message.str);
13554 }
13555
13556
13557 const char *
description() const13558 Incident_log_event::description() const
13559 {
13560 static const char *const description[]= {
13561 "NOTHING", // Not used
13562 "LOST_EVENTS"
13563 };
13564
13565 DBUG_PRINT("info", ("m_incident: %d", m_incident));
13566
13567 return description[m_incident];
13568 }
13569
13570
13571 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13572 int Incident_log_event::pack_info(Protocol *protocol)
13573 {
13574 char buf[256];
13575 size_t bytes;
13576 if (m_message.length > 0)
13577 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
13578 m_incident, description());
13579 else
13580 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
13581 m_incident, description(), m_message.str);
13582 protocol->store(buf, bytes, &my_charset_bin);
13583 return 0;
13584 }
13585 #endif
13586
13587
13588 #ifdef MYSQL_CLIENT
13589 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13590 Incident_log_event::print(FILE *file,
13591 PRINT_EVENT_INFO *print_event_info)
13592 {
13593 if (print_event_info->short_form)
13594 return;
13595
13596 print_header(&print_event_info->head_cache, print_event_info, FALSE);
13597 my_b_printf(&print_event_info->head_cache,
13598 "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n",
13599 description());
13600 }
13601 #endif
13602
13603 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
13604 int
do_apply_event(Relay_log_info const * rli)13605 Incident_log_event::do_apply_event(Relay_log_info const *rli)
13606 {
13607 DBUG_ENTER("Incident_log_event::do_apply_event");
13608
13609 if (ignored_error_code(ER_SLAVE_INCIDENT))
13610 {
13611 DBUG_PRINT("info", ("Ignoring Incident"));
13612 DBUG_RETURN(0);
13613 }
13614
13615 rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
13616 ER(ER_SLAVE_INCIDENT),
13617 description(),
13618 m_message.length > 0 ? m_message.str : "<none>");
13619 DBUG_RETURN(1);
13620 }
13621 #endif
13622
13623 bool
write_data_header(IO_CACHE * file)13624 Incident_log_event::write_data_header(IO_CACHE *file)
13625 {
13626 DBUG_ENTER("Incident_log_event::write_data_header");
13627 DBUG_PRINT("enter", ("m_incident: %d", m_incident));
13628 uchar buf[sizeof(int16)];
13629 int2store(buf, (int16) m_incident);
13630 #ifndef MYSQL_CLIENT
13631 DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
13632 #else
13633 DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
13634 #endif
13635 }
13636
13637 bool
write_data_body(IO_CACHE * file)13638 Incident_log_event::write_data_body(IO_CACHE *file)
13639 {
13640 uchar tmp[1];
13641 DBUG_ENTER("Incident_log_event::write_data_body");
13642 tmp[0]= (uchar) m_message.length;
13643 crc= my_checksum(crc, (uchar*) tmp, 1);
13644 if (m_message.length > 0)
13645 {
13646 crc= my_checksum(crc, (uchar*) m_message.str, m_message.length);
13647 // todo: report a bug on write_str accepts uint but treats it as uchar
13648 }
13649 DBUG_RETURN(write_str_at_most_255_bytes(file, m_message.str, (uint) m_message.length));
13650 }
13651
13652
Ignorable_log_event(const char * buf,const Format_description_log_event * descr_event)13653 Ignorable_log_event::Ignorable_log_event(const char *buf,
13654 const Format_description_log_event *descr_event)
13655 : Log_event(buf, descr_event)
13656 {
13657 DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
13658 DBUG_VOID_RETURN;
13659 }
13660
~Ignorable_log_event()13661 Ignorable_log_event::~Ignorable_log_event()
13662 {
13663 }
13664
13665 #ifndef MYSQL_CLIENT
13666 /* Pack info for its unrecognized ignorable event */
pack_info(Protocol * protocol)13667 int Ignorable_log_event::pack_info(Protocol *protocol)
13668 {
13669 char buf[256];
13670 size_t bytes;
13671 bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized ignorable event");
13672 protocol->store(buf, bytes, &my_charset_bin);
13673 return 0;
13674 }
13675 #endif
13676
13677 #ifdef MYSQL_CLIENT
13678 /* Print for its unrecognized ignorable event */
13679 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13680 Ignorable_log_event::print(FILE *file,
13681 PRINT_EVENT_INFO *print_event_info)
13682 {
13683 if (print_event_info->short_form)
13684 return;
13685
13686 print_header(&print_event_info->head_cache, print_event_info, FALSE);
13687 my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
13688 my_b_printf(&print_event_info->head_cache,
13689 "# Unrecognized ignorable event\n");
13690 }
13691 #endif
13692
13693
Rows_query_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13694 Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
13695 const Format_description_log_event *descr_event)
13696 : Ignorable_log_event(buf, descr_event)
13697 {
13698 DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
13699 uint8 const common_header_len=
13700 descr_event->common_header_len;
13701 uint8 const post_header_len=
13702 descr_event->post_header_len[ROWS_QUERY_LOG_EVENT-1];
13703
13704 m_rows_query= NULL;
13705
13706 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13707 event_len, common_header_len, post_header_len));
13708
13709 /*
13710 m_rows_query length is stored using only one byte, but that length is
13711 ignored and the complete query is read.
13712 */
13713 unsigned int offset= common_header_len + post_header_len + 1;
13714 /* Avoid reading out of buffer */
13715 if (offset > event_len)
13716 DBUG_VOID_RETURN;
13717
13718 unsigned int len= event_len - offset;
13719 if (!(m_rows_query= (char*) my_malloc(len+1, MYF(MY_WME))))
13720 return;
13721 strmake(m_rows_query, buf + offset, len);
13722 DBUG_PRINT("info", ("m_rows_query: %s", m_rows_query));
13723 DBUG_VOID_RETURN;
13724 }
13725
~Rows_query_log_event()13726 Rows_query_log_event::~Rows_query_log_event()
13727 {
13728 my_free(m_rows_query);
13729 }
13730
13731 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13732 int Rows_query_log_event::pack_info(Protocol *protocol)
13733 {
13734 char *buf;
13735 size_t bytes;
13736 ulong len= sizeof("# ") + (ulong) strlen(m_rows_query);
13737 if (!(buf= (char*) my_malloc(len, MYF(MY_WME))))
13738 return 1;
13739 bytes= my_snprintf(buf, len, "# %s", m_rows_query);
13740 protocol->store(buf, bytes, &my_charset_bin);
13741 my_free(buf);
13742 return 0;
13743 }
13744 #endif
13745
13746 #ifdef MYSQL_CLIENT
13747 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13748 Rows_query_log_event::print(FILE *file,
13749 PRINT_EVENT_INFO *print_event_info)
13750 {
13751 if (!print_event_info->short_form && print_event_info->verbose > 1)
13752 {
13753 IO_CACHE *const head= &print_event_info->head_cache;
13754 IO_CACHE *const body= &print_event_info->body_cache;
13755 char *token= NULL, *saveptr= NULL;
13756 char *rows_query_copy= NULL;
13757 if (!(rows_query_copy= my_strdup(m_rows_query, MYF(MY_WME))))
13758 return;
13759
13760 print_header(head, print_event_info, FALSE);
13761 my_b_printf(head, "\tRows_query\n");
13762 /*
13763 Prefix every line of a multi-line query with '#' to prevent the
13764 statement from being executed when binary log will be processed
13765 using 'mysqlbinlog --verbose --verbose'.
13766 */
13767 for (token= strtok_r(rows_query_copy, "\n", &saveptr); token;
13768 token= strtok_r(NULL, "\n", &saveptr))
13769 my_b_printf(head, "# %s\n", token);
13770 my_free(rows_query_copy);
13771 print_base64(body, print_event_info, true);
13772 }
13773 }
13774 #endif
13775
13776 bool
write_data_body(IO_CACHE * file)13777 Rows_query_log_event::write_data_body(IO_CACHE *file)
13778 {
13779 DBUG_ENTER("Rows_query_log_event::write_data_body");
13780 /*
13781 m_rows_query length will be stored using only one byte, but on read
13782 that length will be ignored and the complete query will be read.
13783 */
13784 DBUG_RETURN(write_str_at_most_255_bytes(file, m_rows_query,
13785 (uint) strlen(m_rows_query)));
13786 }
13787
13788 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13789 int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
13790 {
13791 DBUG_ENTER("Rows_query_log_event::do_apply_event");
13792 DBUG_ASSERT(rli->info_thd == thd);
13793 /* Set query for writing Rows_query log event into binlog later.*/
13794 thd->set_query(m_rows_query, (uint32) strlen(m_rows_query));
13795 thd->set_query_for_display(m_rows_query, strlen(m_rows_query));
13796
13797 DBUG_ASSERT(rli->rows_query_ev == NULL);
13798
13799 const_cast<Relay_log_info*>(rli)->rows_query_ev= this;
13800
13801 DBUG_RETURN(0);
13802 }
13803 #endif
13804
13805
13806 const char *Gtid_log_event::SET_STRING_PREFIX= "SET @@SESSION.GTID_NEXT= '";
13807
13808
Gtid_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)13809 Gtid_log_event::Gtid_log_event(const char *buffer, uint event_len,
13810 const Format_description_log_event *descr_event)
13811 : Log_event(buffer, descr_event)
13812 {
13813 DBUG_ENTER("Gtid_log_event::Gtid_log_event(const char *, uint, const Format_description_log_event *");
13814 uint8 const common_header_len=
13815 descr_event->common_header_len;
13816
13817 #ifndef DBUG_OFF
13818 uint8 const post_header_len=
13819 buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13820 descr_event->post_header_len[ANONYMOUS_GTID_LOG_EVENT - 1] :
13821 descr_event->post_header_len[GTID_LOG_EVENT - 1];
13822 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13823 event_len, common_header_len, post_header_len));
13824 #endif
13825
13826 char const *ptr_buffer= buffer + common_header_len;
13827
13828 spec.type= buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13829 ANONYMOUS_GROUP : GTID_GROUP;
13830
13831 commit_flag= *ptr_buffer != 0;
13832 ptr_buffer+= ENCODED_FLAG_LENGTH;
13833
13834 sid.copy_from((uchar *)ptr_buffer);
13835 ptr_buffer+= ENCODED_SID_LENGTH;
13836
13837 // SIDNO is only generated if needed, in get_sidno().
13838 spec.gtid.sidno= -1;
13839
13840 spec.gtid.gno= uint8korr(ptr_buffer);
13841 ptr_buffer+= ENCODED_GNO_LENGTH;
13842
13843 DBUG_VOID_RETURN;
13844 }
13845
13846 #ifndef MYSQL_CLIENT
Gtid_log_event(THD * thd_arg,bool using_trans,const Gtid_specification * spec_arg)13847 Gtid_log_event::Gtid_log_event(THD* thd_arg, bool using_trans,
13848 const Gtid_specification *spec_arg)
13849 : Log_event(thd_arg, thd_arg->variables.gtid_next.type == ANONYMOUS_GROUP ?
13850 LOG_EVENT_IGNORABLE_F : 0,
13851 using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13852 Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING),
13853 commit_flag(true)
13854 {
13855 DBUG_ENTER("Gtid_log_event::Gtid_log_event(THD *)");
13856 spec= spec_arg ? *spec_arg : thd_arg->variables.gtid_next;
13857 if (spec.type == GTID_GROUP)
13858 {
13859 global_sid_lock->rdlock();
13860 sid= global_sid_map->sidno_to_sid(spec.gtid.sidno);
13861 global_sid_lock->unlock();
13862 }
13863 else
13864 sid.clear();
13865 #ifndef DBUG_OFF
13866 char buf[MAX_SET_STRING_LENGTH + 1];
13867 to_string(buf);
13868 DBUG_PRINT("info", ("%s", buf));
13869 #endif
13870 DBUG_VOID_RETURN;
13871 }
13872 #endif
13873
13874 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13875 int Gtid_log_event::pack_info(Protocol *protocol)
13876 {
13877 char buffer[MAX_SET_STRING_LENGTH + 1];
13878 size_t len= to_string(buffer);
13879 protocol->store(buffer, len, &my_charset_bin);
13880 return 0;
13881 }
13882 #endif
13883
to_string(char * buf) const13884 size_t Gtid_log_event::to_string(char *buf) const
13885 {
13886 char *p= buf;
13887 DBUG_ASSERT(strlen(SET_STRING_PREFIX) == SET_STRING_PREFIX_LENGTH);
13888 strcpy(p, SET_STRING_PREFIX);
13889 p+= SET_STRING_PREFIX_LENGTH;
13890 p+= spec.to_string(&sid, p);
13891 *p++= '\'';
13892 *p= '\0';
13893 return p - buf;
13894 }
13895
13896 #ifdef MYSQL_CLIENT
13897 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13898 Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
13899 {
13900 char buffer[MAX_SET_STRING_LENGTH + 1];
13901 IO_CACHE *const head= &print_event_info->head_cache;
13902 if (!print_event_info->short_form)
13903 {
13904 print_header(head, print_event_info, FALSE);
13905 my_b_printf(head, "\tGTID [commit=%s]\n", commit_flag ? "yes" : "no");
13906 }
13907 to_string(buffer);
13908 my_b_printf(head, "%s%s\n", buffer, print_event_info->delimiter);
13909 }
13910 #endif
13911
13912 #ifdef MYSQL_SERVER
write_data_header(IO_CACHE * file)13913 bool Gtid_log_event::write_data_header(IO_CACHE *file)
13914 {
13915 DBUG_ENTER("Gtid_log_event::write_data_header");
13916 char buffer[POST_HEADER_LENGTH];
13917 char* ptr_buffer= buffer;
13918
13919 *ptr_buffer= commit_flag ? 1 : 0;
13920 ptr_buffer+= ENCODED_FLAG_LENGTH;
13921
13922 #ifndef DBUG_OFF
13923 char buf[rpl_sid::TEXT_LENGTH + 1];
13924 sid.to_string(buf);
13925 DBUG_PRINT("info", ("sid=%s sidno=%d gno=%lld",
13926 buf, spec.gtid.sidno, spec.gtid.gno));
13927 #endif
13928
13929 sid.copy_to((uchar *)ptr_buffer);
13930 ptr_buffer+= ENCODED_SID_LENGTH;
13931
13932 int8store(ptr_buffer, spec.gtid.gno);
13933 ptr_buffer+= ENCODED_GNO_LENGTH;
13934
13935 DBUG_ASSERT(ptr_buffer == (buffer + sizeof(buffer)));
13936 DBUG_RETURN(wrapper_my_b_safe_write(file, (uchar *) buffer, sizeof(buffer)));
13937 }
13938 #endif // MYSQL_SERVER
13939
13940 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13941 int Gtid_log_event::do_apply_event(Relay_log_info const *rli)
13942 {
13943 DBUG_ENTER("Gtid_log_event::do_apply_event");
13944 DBUG_ASSERT(rli->info_thd == thd);
13945
13946 if (get_type_code() == ANONYMOUS_GTID_LOG_EVENT)
13947 {
13948 if (gtid_mode == GTID_MODE_ON)
13949 {
13950 my_error(ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON, MYF(0));
13951 DBUG_RETURN(1);
13952 }
13953 thd->variables.gtid_next.set_anonymous();
13954 /*
13955 We do not need to write the anonymous gtid log event into binary log,
13956 since we should not add new fields to include logical timestamps used
13957 for applying transactions in parallel in the GA version.
13958 */
13959 DBUG_RETURN(0);
13960 }
13961
13962 /* Applying Gtid_log_event should report an error when GTID_MODE is OFF */
13963 if (gtid_mode == GTID_MODE_OFF)
13964 {
13965 my_error(ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF, MYF(0));
13966 DBUG_RETURN(1);
13967 }
13968
13969 rpl_sidno sidno= get_sidno(true);
13970 if (sidno < 0)
13971 DBUG_RETURN(1); // out of memory
13972 if (thd->owned_gtid.sidno)
13973 {
13974 /*
13975 Slave will execute this code if a previous Gtid_log_event was applied
13976 but the GTID wasn't consumed yet (the transaction was not committed
13977 nor rolled back).
13978 On a client session we cannot do consecutive SET GTID_NEXT without
13979 a COMMIT or a ROLLBACK in the middle.
13980 Applying this event without rolling back the current transaction may
13981 lead to problems, as a "BEGIN" event following this GTID will
13982 implicitly commit the "partial transaction" and will consume the
13983 GTID. If this "partial transaction" was left in the relay log by the
13984 IO thread restarting in the middle of a transaction, you could have
13985 the partial transaction being logged with the GTID on the slave,
13986 causing data corruption on replication.
13987 */
13988 if (thd->transaction.all.ha_list)
13989 {
13990 /* This is not an error (XA is safe), just an information */
13991 rli->report(INFORMATION_LEVEL, 0,
13992 "Rolling back unfinished transaction (no COMMIT "
13993 "or ROLLBACK in relay log). A probable cause is partial "
13994 "transaction left on relay log because of restarting IO "
13995 "thread with auto-positioning protocol.");
13996 const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
13997 }
13998 gtid_rollback(thd);
13999 }
14000 thd->variables.gtid_next.set(sidno, spec.gtid.gno);
14001 DBUG_PRINT("info", ("setting gtid_next=%d:%lld",
14002 sidno, spec.gtid.gno));
14003
14004 if (gtid_acquire_ownership_single(thd))
14005 DBUG_RETURN(1);
14006
14007 DBUG_RETURN(0);
14008 }
14009
do_update_pos(Relay_log_info * rli)14010 int Gtid_log_event::do_update_pos(Relay_log_info *rli)
14011 {
14012 /*
14013 This event does not increment group positions. This means
14014 that if there is a failure after it has been processed,
14015 it will be automatically re-executed.
14016 */
14017 rli->inc_event_relay_log_pos();
14018 DBUG_EXECUTE_IF("crash_after_update_pos_gtid",
14019 sql_print_information("Crashing crash_after_update_pos_gtid.");
14020 DBUG_SUICIDE(););
14021 return 0;
14022 }
14023 #endif
14024
Previous_gtids_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)14025 Previous_gtids_log_event::Previous_gtids_log_event(
14026 const char *buffer, uint event_len,
14027 const Format_description_log_event *descr_event)
14028 : Log_event(buffer, descr_event)
14029 {
14030 DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event");
14031 uint8 const common_header_len=
14032 descr_event->common_header_len;
14033 uint8 const post_header_len=
14034 descr_event->post_header_len[PREVIOUS_GTIDS_LOG_EVENT - 1];
14035
14036 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
14037 event_len, common_header_len, post_header_len));
14038
14039 buf= (const uchar *)buffer + common_header_len + post_header_len;
14040 buf_size= (const uchar *)buffer + event_len - buf;
14041 DBUG_PRINT("info", ("data size of the event: %d", buf_size));
14042 DBUG_VOID_RETURN;
14043 }
14044
14045 #ifndef MYSQL_CLIENT
Previous_gtids_log_event(const Gtid_set * set)14046 Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set)
14047 : Log_event(Log_event::EVENT_NO_CACHE,
14048 Log_event::EVENT_IMMEDIATE_LOGGING)
14049 {
14050 DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event(THD *, const Gtid_set *)");
14051 global_sid_lock->assert_some_lock();
14052 buf_size= set->get_encoded_length();
14053 uchar *buffer= (uchar *) my_malloc(buf_size, MYF(MY_WME));
14054 if (buffer != NULL)
14055 {
14056 set->encode(buffer);
14057 register_temp_buf((char *)buffer);
14058 }
14059 this->buf= buffer;
14060 // if buf == NULL, is_valid will return false
14061 DBUG_VOID_RETURN;
14062 }
14063 #endif
14064
14065 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14066 int Previous_gtids_log_event::pack_info(Protocol *protocol)
14067 {
14068 size_t length= 0;
14069 global_sid_lock->rdlock();
14070 char *str= get_str(&length, &Gtid_set::default_string_format);
14071 global_sid_lock->unlock();
14072 if (str == NULL)
14073 return 1;
14074 protocol->store(str, length, &my_charset_bin);
14075 my_free(str);
14076 return 0;
14077 }
14078 #endif
14079
14080 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14081 void Previous_gtids_log_event::print(FILE *file,
14082 PRINT_EVENT_INFO *print_event_info)
14083 {
14084 IO_CACHE *const head= &print_event_info->head_cache;
14085
14086 global_sid_lock->rdlock();
14087 char *str= get_str(NULL, &Gtid_set::commented_string_format);
14088 global_sid_lock->unlock();
14089 if (str != NULL)
14090 {
14091 if (!print_event_info->short_form)
14092 {
14093 print_header(head, print_event_info, FALSE);
14094 my_b_printf(head, "\tPrevious-GTIDs\n");
14095 }
14096 my_b_printf(head, "%s\n", str);
14097 my_free(str);
14098 }
14099 }
14100 #endif
14101
add_to_set(Gtid_set * target) const14102 int Previous_gtids_log_event::add_to_set(Gtid_set *target) const
14103 {
14104 DBUG_ENTER("Previous_gtids_log_event::add_to_set(Gtid_set *)");
14105 size_t end_pos= 0;
14106 size_t add_size= DBUG_EVALUATE_IF("gtid_has_extra_data", 10, 0);
14107 /* Silently ignore additional unknown data at the end of the encoding */
14108 PROPAGATE_REPORTED_ERROR_INT(target->add_gtid_encoding(buf,
14109 buf_size + add_size,
14110 &end_pos));
14111 DBUG_ASSERT(end_pos <= (size_t) buf_size);
14112 DBUG_RETURN(0);
14113 }
14114
get_str(size_t * length_p,const Gtid_set::String_format * string_format) const14115 char *Previous_gtids_log_event::get_str(
14116 size_t *length_p, const Gtid_set::String_format *string_format) const
14117 {
14118 DBUG_ENTER("Previous_gtids_log_event::get_str(size_t *)");
14119 Sid_map sid_map(NULL);
14120 Gtid_set set(&sid_map, NULL);
14121 DBUG_PRINT("info", ("temp_buf=%p buf=%p", temp_buf, buf));
14122 if (set.add_gtid_encoding(buf, buf_size) != RETURN_STATUS_OK)
14123 DBUG_RETURN(NULL);
14124 set.dbug_print("set");
14125 size_t length= set.get_string_length(string_format);
14126 DBUG_PRINT("info", ("string length= %lu", (ulong) length));
14127 char* str= (char *)my_malloc(length + 1, MYF(MY_WME));
14128 if (str != NULL)
14129 {
14130 set.to_string(str, string_format);
14131 if (length_p != NULL)
14132 *length_p= length;
14133 }
14134 DBUG_RETURN(str);
14135 }
14136
14137 #ifndef MYSQL_CLIENT
write_data_body(IO_CACHE * file)14138 bool Previous_gtids_log_event::write_data_body(IO_CACHE *file)
14139 {
14140 DBUG_ENTER("Previous_gtids_log_event::write_data_body");
14141 DBUG_PRINT("info", ("size=%d", buf_size));
14142 bool ret= wrapper_my_b_safe_write(file, buf, buf_size);
14143 DBUG_RETURN(ret);
14144 }
14145 #endif
14146
14147 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_update_pos(Relay_log_info * rli)14148 int Previous_gtids_log_event::do_update_pos(Relay_log_info *rli)
14149 {
14150 rli->inc_event_relay_log_pos();
14151 return 0;
14152 }
14153 #endif
14154
14155
14156 #ifdef MYSQL_CLIENT
14157 /**
14158 The default values for these variables should be values that are
14159 *incorrect*, i.e., values that cannot occur in an event. This way,
14160 they will always be printed for the first event.
14161 */
st_print_event_info()14162 st_print_event_info::st_print_event_info()
14163 :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
14164 auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
14165 lc_time_names_number(~0),
14166 charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
14167 thread_id(0), thread_id_printed(false),server_id_from_fd_event(0),
14168 base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE),
14169 have_unflushed_events(false), skipped_event_in_transaction(false),
14170 is_gtid_next_set(false), is_gtid_next_valid(true)
14171 {
14172 /*
14173 Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
14174 program's startup, but these explicit memset() is for the day someone
14175 creates dynamic instances.
14176 */
14177 memset(db, 0, sizeof(db));
14178 memset(charset, 0, sizeof(charset));
14179 memset(time_zone_str, 0, sizeof(time_zone_str));
14180 delimiter[0]= ';';
14181 delimiter[1]= 0;
14182 myf const flags = MYF(MY_WME | MY_NABP);
14183 open_cached_file(&head_cache, NULL, NULL, 0, flags);
14184 open_cached_file(&body_cache, NULL, NULL, 0, flags);
14185 }
14186 #endif
14187
14188
14189 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)14190 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
14191 const Format_description_log_event* description_event)
14192 :Log_event(buf, description_event)
14193 {
14194 uint8 header_size= description_event->common_header_len;
14195 ident_len = event_len - header_size;
14196 set_if_smaller(ident_len,FN_REFLEN-1);
14197 log_ident= buf + header_size;
14198 }
14199 #endif
14200
14201 #ifdef MYSQL_SERVER
14202 /*
14203 This is a utility function that adds a quoted identifier into the a buffer.
14204 This also escapes any existance of the quote string inside the identifier.
14205
14206 SYNOPSIS
14207 my_strmov_quoted_identifier
14208 thd thread handler
14209 buffer target buffer
14210 identifier the identifier to be quoted
14211 length length of the identifier
14212 */
my_strmov_quoted_identifier(THD * thd,char * buffer,const char * identifier,uint length)14213 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
14214 const char* identifier,
14215 uint length)
14216 {
14217 int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
14218 return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
14219 }
14220 #else
my_strmov_quoted_identifier(char * buffer,const char * identifier)14221 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier)
14222 {
14223 int q= '`';
14224 return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
14225 }
14226
14227 #endif
14228
my_strmov_quoted_identifier_helper(int q,char * buffer,const char * identifier,uint length)14229 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
14230 const char* identifier,
14231 uint length)
14232 {
14233 size_t written= 0;
14234 char quote_char;
14235 uint id_length= (length) ? length : strlen(identifier);
14236
14237 if (q == EOF)
14238 {
14239 (void) strncpy(buffer, identifier, id_length);
14240 return id_length;
14241 }
14242 quote_char= (char) q;
14243 *buffer++= quote_char;
14244 written++;
14245 while (id_length--)
14246 {
14247 if (*identifier == quote_char)
14248 {
14249 *buffer++= quote_char;
14250 written++;
14251 }
14252 *buffer++= *identifier++;
14253 written++;
14254 }
14255 *buffer++= quote_char;
14256 return ++written;
14257 }
14258
14259