1/*
2 Copyright (c) 2000, 2018, Oracle and/or its affiliates.
3 Copyright (c) 2009, 2018, MariaDB
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
17
18
19#include "mariadb.h"
20#include "sql_priv.h"
21
22#ifndef MYSQL_CLIENT
23#include "unireg.h"
24#include "log_event.h"
25#include "sql_base.h" // close_thread_tables
26#include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE
27#include "sql_locale.h" // MY_LOCALE, my_locale_by_number, my_locale_en_US
28#include "key.h" // key_copy
29#include "lock.h" // mysql_unlock_tables
30#include "sql_parse.h" // mysql_test_parse_for_slave
31#include "tztime.h" // struct Time_zone
32#include "sql_load.h" // mysql_load
33#include "sql_db.h" // load_db_opt_by_name
34#include "slave.h"
35#include "rpl_rli.h"
36#include "rpl_mi.h"
37#include "rpl_filter.h"
38#include "rpl_record.h"
39#include "transaction.h"
40#include <my_dir.h>
41#include "sql_show.h" // append_identifier
42#include <mysql/psi/mysql_statement.h>
43#include <strfunc.h>
44#include "compat56.h"
45#include "wsrep_mysqld.h"
46#include "sql_insert.h"
47#else
48#include "mysqld_error.h"
49#endif /* MYSQL_CLIENT */
50
51#include <my_bitmap.h>
52#include "rpl_utility.h"
53#include "rpl_constants.h"
54#include "sql_digest.h"
55#include "zlib.h"
56#include "my_atomic.h"
57
58#define my_b_write_string(A, B) my_b_write((A), (uchar*)(B), (uint) (sizeof(B) - 1))
59
60/**
61 BINLOG_CHECKSUM variable.
62*/
63const char *binlog_checksum_type_names[]= {
64 "NONE",
65 "CRC32",
66 NullS
67};
68
69unsigned int binlog_checksum_type_length[]= {
70 sizeof("NONE") - 1,
71 sizeof("CRC32") - 1,
72 0
73};
74
75TYPELIB binlog_checksum_typelib=
76{
77 array_elements(binlog_checksum_type_names) - 1, "",
78 binlog_checksum_type_names,
79 binlog_checksum_type_length
80};
81
82
83
84#define log_cs &my_charset_latin1
85
86#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
87
88/*
89 Size of buffer for printing a double in format %.<PREC>g
90
91 optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
92 exponent digits + '\0'
93*/
94#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
95
96/*
97 replication event checksum is introduced in the following "checksum-home" version.
98 The checksum-aware servers extract FD's version to decide whether the FD event
99 carries checksum info.
100
101 TODO: correct the constant when it has been determined
102 (which main tree to push and when)
103*/
104const uchar checksum_version_split_mysql[3]= {5, 6, 1};
105const ulong checksum_version_product_mysql=
106 (checksum_version_split_mysql[0] * 256 +
107 checksum_version_split_mysql[1]) * 256 +
108 checksum_version_split_mysql[2];
109const uchar checksum_version_split_mariadb[3]= {5, 3, 0};
110const ulong checksum_version_product_mariadb=
111 (checksum_version_split_mariadb[0] * 256 +
112 checksum_version_split_mariadb[1]) * 256 +
113 checksum_version_split_mariadb[2];
114
115#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
116static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD* thd);
117
118static const char *HA_ERR(int i)
119{
120 /*
121 This function should only be called in case of an error
122 was detected
123 */
124 DBUG_ASSERT(i != 0);
125 switch (i) {
126 case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
127 case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
128 case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
129 case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
130 case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
131 case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
132 case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
133 case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
134 case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
135 case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
136 case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
137 case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
138 case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
139 case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
140 case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
141 case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
142 case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
143 case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
144 case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
145 case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
146 case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
147 case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
148 case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
149 case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
150 case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
151 case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
152 case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
153 case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
154 case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
155 case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
156 case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
157 case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
158 case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
159 case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
160 case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
161 case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
162 case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
163 case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
164 case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
165 case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
166 case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
167 case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
168 case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
169 case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
170 case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
171 case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
172 case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
173 case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
174 case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
175 case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
176 }
177 return "No Error!";
178}
179
180
181/*
182 Return true if an error caught during event execution is a temporary error
183 that will cause automatic retry of the event group during parallel
184 replication, false otherwise.
185
186 In parallel replication, conflicting transactions can occasionally cause
187 deadlocks; such errors are handled automatically by rolling back re-trying
188 the transactions, so should not pollute the error log.
189*/
190static bool
191is_parallel_retry_error(rpl_group_info *rgi, int err)
192{
193 if (!rgi->is_parallel_exec)
194 return false;
195 if (rgi->speculation == rpl_group_info::SPECULATE_OPTIMISTIC)
196 return true;
197 if (rgi->killed_for_retry &&
198 (err == ER_QUERY_INTERRUPTED || err == ER_CONNECTION_KILLED))
199 return true;
200 return has_temporary_error(rgi->thd);
201}
202
203
204/**
205 Error reporting facility for Rows_log_event::do_apply_event
206
207 @param level error, warning or info
208 @param ha_error HA_ERR_ code
209 @param rli pointer to the active Relay_log_info instance
210 @param thd pointer to the slave thread's thd
211 @param table pointer to the event's table object
212 @param type the type of the event
213 @param log_name the master binlog file name
214 @param pos the master binlog file pos (the next after the event)
215
216*/
217static void inline slave_rows_error_report(enum loglevel level, int ha_error,
218 rpl_group_info *rgi, THD *thd,
219 TABLE *table, const char * type,
220 const char *log_name, my_off_t pos)
221{
222 const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
223 char buff[MAX_SLAVE_ERRMSG], *slider;
224 const char *buff_end= buff + sizeof(buff);
225 size_t len;
226 Diagnostics_area::Sql_condition_iterator it=
227 thd->get_stmt_da()->sql_conditions();
228 Relay_log_info const *rli= rgi->rli;
229 const Sql_condition *err;
230 buff[0]= 0;
231 int errcode= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
232
233 /*
234 In parallel replication, deadlocks or other temporary errors can happen
235 occasionally in normal operation, they will be handled correctly and
236 automatically by re-trying the transactions. So do not pollute the error
237 log with messages about them.
238 */
239 if (is_parallel_retry_error(rgi, errcode))
240 return;
241
242 for (err= it++, slider= buff; err && slider < buff_end - 1;
243 slider += len, err= it++)
244 {
245 len= my_snprintf(slider, buff_end - slider,
246 " %s, Error_code: %d;", err->get_message_text(),
247 err->get_sql_errno());
248 }
249
250 if (ha_error != 0)
251 rli->report(level, errcode, rgi->gtid_info(),
252 "Could not execute %s event on table %s.%s;"
253 "%s handler error %s; "
254 "the event's master log %s, end_log_pos %llu",
255 type, table->s->db.str, table->s->table_name.str,
256 buff, handler_error == NULL ? "<unknown>" : handler_error,
257 log_name, pos);
258 else
259 rli->report(level, errcode, rgi->gtid_info(),
260 "Could not execute %s event on table %s.%s;"
261 "%s the event's master log %s, end_log_pos %llu",
262 type, table->s->db.str, table->s->table_name.str,
263 buff, log_name, pos);
264}
265#endif
266
267/*
268 Cache that will automatically be written to a dedicated file on
269 destruction.
270
271 DESCRIPTION
272
273 */
274class Write_on_release_cache
275{
276public:
277 enum flag
278 {
279 FLUSH_F
280 };
281
282 typedef unsigned short flag_set;
283
284 /*
285 Constructor.
286
287 SYNOPSIS
288 Write_on_release_cache
289 cache Pointer to cache to use
290 file File to write cache to upon destruction
291 flags Flags for the cache
292
293 DESCRIPTION
294 Cache common parameters and ensure common flush_data() code
295 on successful copy of the cache, the cache will be reinited as a
296 WRITE_CACHE.
297
298 Currently, a pointer to the cache is provided in the
299 constructor, but it would be possible to create a subclass
300 holding the IO_CACHE itself.
301 */
302 Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0, Log_event *ev = NULL)
303 : m_cache(cache), m_file(file), m_flags(flags), m_ev(ev)
304 {
305 reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
306 }
307
308 ~Write_on_release_cache() {}
309
310 bool flush_data()
311 {
312#ifdef MYSQL_CLIENT
313 if (m_ev == NULL)
314 {
315 if (copy_event_cache_to_file_and_reinit(m_cache, m_file))
316 return 1;
317 if ((m_flags & FLUSH_F) && fflush(m_file))
318 return 1;
319 }
320 else // if m_ev<>NULL, then storing the output in output_buf
321 {
322 LEX_STRING tmp_str;
323 bool res;
324 if (copy_event_cache_to_string_and_reinit(m_cache, &tmp_str))
325 return 1;
326 /* use 2 argument append as tmp_str is not \0 terminated */
327 res= m_ev->output_buf.append(tmp_str.str, tmp_str.length);
328 my_free(tmp_str.str);
329 return res ? res : 0;
330 }
331#else /* MySQL_SERVER */
332 if (copy_event_cache_to_file_and_reinit(m_cache, m_file))
333 return 1;
334 if ((m_flags & FLUSH_F) && fflush(m_file))
335 return 1;
336#endif
337 return 0;
338 }
339
340 /*
341 Return a pointer to the internal IO_CACHE.
342
343 SYNOPSIS
344 operator&()
345
346 DESCRIPTION
347
348 Function to return a pointer to the internal cache, so that the
349 object can be treated as a IO_CACHE and used with the my_b_*
350 IO_CACHE functions
351
352 RETURN VALUE
353 A pointer to the internal IO_CACHE.
354 */
355 IO_CACHE *operator&()
356 {
357 return m_cache;
358 }
359
360private:
361 // Hidden, to prevent usage.
362 Write_on_release_cache(Write_on_release_cache const&);
363
364 IO_CACHE *m_cache;
365 FILE *m_file;
366 flag_set m_flags;
367 Log_event *m_ev; // Used for Flashback
368};
369
370/*
371 pretty_print_str()
372*/
373
374#ifdef MYSQL_CLIENT
375static bool pretty_print_str(IO_CACHE* cache, const char* str, int len)
376{
377 const char* end = str + len;
378 if (my_b_write_byte(cache, '\''))
379 goto err;
380
381 while (str < end)
382 {
383 char c;
384 int error;
385
386 switch ((c=*str++)) {
387 case '\n': error= my_b_write(cache, (uchar*)"\\n", 2); break;
388 case '\r': error= my_b_write(cache, (uchar*)"\\r", 2); break;
389 case '\\': error= my_b_write(cache, (uchar*)"\\\\", 2); break;
390 case '\b': error= my_b_write(cache, (uchar*)"\\b", 2); break;
391 case '\t': error= my_b_write(cache, (uchar*)"\\t", 2); break;
392 case '\'': error= my_b_write(cache, (uchar*)"\\'", 2); break;
393 case 0 : error= my_b_write(cache, (uchar*)"\\0", 2); break;
394 default:
395 error= my_b_write_byte(cache, c);
396 break;
397 }
398 if (unlikely(error))
399 goto err;
400 }
401 return my_b_write_byte(cache, '\'');
402
403err:
404 return 1;
405}
406#endif /* MYSQL_CLIENT */
407
408#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
409
410inline int idempotent_error_code(int err_code)
411{
412 int ret= 0;
413
414 switch (err_code)
415 {
416 case 0:
417 ret= 1;
418 break;
419 /*
420 The following list of "idempotent" errors
421 means that an error from the list might happen
422 because of idempotent (more than once)
423 applying of a binlog file.
424 Notice, that binlog has a ddl operation its
425 second applying may cause
426
427 case HA_ERR_TABLE_DEF_CHANGED:
428 case HA_ERR_CANNOT_ADD_FOREIGN:
429
430 which are not included into to the list.
431
432 Note that HA_ERR_RECORD_DELETED is not in the list since
433 do_exec_row() should not return that error code.
434 */
435 case HA_ERR_RECORD_CHANGED:
436 case HA_ERR_KEY_NOT_FOUND:
437 case HA_ERR_END_OF_FILE:
438 case HA_ERR_FOUND_DUPP_KEY:
439 case HA_ERR_FOUND_DUPP_UNIQUE:
440 case HA_ERR_FOREIGN_DUPLICATE_KEY:
441 case HA_ERR_NO_REFERENCED_ROW:
442 case HA_ERR_ROW_IS_REFERENCED:
443 ret= 1;
444 break;
445 default:
446 ret= 0;
447 break;
448 }
449 return (ret);
450}
451
452/**
453 Ignore error code specified on command line.
454*/
455
456inline int ignored_error_code(int err_code)
457{
458 if (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code))
459 {
460 statistic_increment(slave_skipped_errors, LOCK_status);
461 return 1;
462 }
463 return err_code == ER_SLAVE_IGNORED_TABLE;
464}
465
466/*
467 This function converts an engine's error to a server error.
468
469 If the thread does not have an error already reported, it tries to
470 define it by calling the engine's method print_error. However, if a
471 mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
472 warning message.
473*/
474int convert_handler_error(int error, THD* thd, TABLE *table)
475{
476 uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
477 0);
478
479 if (actual_error == 0)
480 {
481 table->file->print_error(error, MYF(0));
482 actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
483 ER_UNKNOWN_ERROR);
484 if (actual_error == ER_UNKNOWN_ERROR)
485 if (global_system_variables.log_warnings)
486 sql_print_warning("Unknown error detected %d in handler", error);
487 }
488
489 return (actual_error);
490}
491
492inline bool concurrency_error_code(int error)
493{
494 switch (error)
495 {
496 case ER_LOCK_WAIT_TIMEOUT:
497 case ER_LOCK_DEADLOCK:
498 case ER_XA_RBDEADLOCK:
499 return TRUE;
500 default:
501 return (FALSE);
502 }
503}
504
505inline bool unexpected_error_code(int unexpected_error)
506{
507 switch (unexpected_error)
508 {
509 case ER_NET_READ_ERROR:
510 case ER_NET_ERROR_ON_WRITE:
511 case ER_QUERY_INTERRUPTED:
512 case ER_STATEMENT_TIMEOUT:
513 case ER_CONNECTION_KILLED:
514 case ER_SERVER_SHUTDOWN:
515 case ER_NEW_ABORTING_CONNECTION:
516 return(TRUE);
517 default:
518 return(FALSE);
519 }
520}
521
522/*
523 pretty_print_str()
524*/
525
526static void
527pretty_print_str(String *packet, const char *str, int len)
528{
529 const char *end= str + len;
530 packet->append(STRING_WITH_LEN("'"));
531 while (str < end)
532 {
533 char c;
534 switch ((c=*str++)) {
535 case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
536 case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
537 case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
538 case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
539 case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
540 case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
541 case 0 : packet->append(STRING_WITH_LEN("\\0")); break;
542 default:
543 packet->append(&c, 1);
544 break;
545 }
546 }
547 packet->append(STRING_WITH_LEN("'"));
548}
549#endif /* !MYSQL_CLIENT */
550
551#ifndef DBUG_OFF
552#define DBUG_DUMP_EVENT_BUF(B,L) \
553 do { \
554 const uchar *_buf=(uchar*)(B); \
555 size_t _len=(L); \
556 if (_len >= LOG_EVENT_MINIMAL_HEADER_LEN) \
557 { \
558 DBUG_PRINT("data", ("header: timestamp:%u type:%u server_id:%u len:%u log_pos:%u flags:%u", \
559 uint4korr(_buf), _buf[EVENT_TYPE_OFFSET], \
560 uint4korr(_buf+SERVER_ID_OFFSET), \
561 uint4korr(_buf+EVENT_LEN_OFFSET), \
562 uint4korr(_buf+LOG_POS_OFFSET), \
563 uint4korr(_buf+FLAGS_OFFSET))); \
564 DBUG_DUMP("data", _buf+LOG_EVENT_MINIMAL_HEADER_LEN, \
565 _len-LOG_EVENT_MINIMAL_HEADER_LEN); \
566 } \
567 else \
568 DBUG_DUMP("data", _buf, _len); \
569 } while(0)
570#else
571#define DBUG_DUMP_EVENT_BUF(B,L) do { } while(0)
572#endif
573
574#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
575
576/**
577 Create a prefix for the temporary files that is to be used for
578 load data file name for this master
579
580 @param name Store prefix of name here
581 @param connection_name Connection name
582
583 @return pointer to end of name
584
585 @description
586 We assume that FN_REFLEN is big enough to hold
587 MAX_CONNECTION_NAME * MAX_FILENAME_MBWIDTH characters + 2 numbers +
588 a short extension.
589
590 The resulting file name has the following parts, each separated with a '-'
591 - PREFIX_SQL_LOAD (SQL_LOAD-)
592 - If a connection name is given (multi-master setup):
593 - Add an extra '-' to mark that this is a multi-master file
594 - connection name in lower case, converted to safe file characters.
595 (see create_logfile_name_with_suffix()).
596 - server_id
597 - A last '-' (after server_id).
598*/
599
600static char *load_data_tmp_prefix(char *name,
601 LEX_CSTRING *connection_name)
602{
603 name= strmov(name, PREFIX_SQL_LOAD);
604 if (connection_name->length)
605 {
606 uint buf_length;
607 uint errors;
608 /* Add marker that this is a multi-master-file */
609 *name++='-';
610 /* Convert connection_name to a safe filename */
611 buf_length= strconvert(system_charset_info, connection_name->str, FN_REFLEN,
612 &my_charset_filename, name, FN_REFLEN, &errors);
613 name+= buf_length;
614 *name++= '-';
615 }
616 name= int10_to_str(global_system_variables.server_id, name, 10);
617 *name++ = '-';
618 *name= '\0'; // For testing prefixes
619 return name;
620}
621
622
623/**
624 Creates a temporary name for LOAD DATA INFILE
625
626 @param buf Store new filename here
627 @param file_id File_id (part of file name)
628 @param event_server_id Event_id (part of file name)
629 @param ext Extension for file name
630
631 @return
632 Pointer to start of extension
633*/
634
635static char *slave_load_file_stem(char *buf, uint file_id,
636 int event_server_id, const char *ext,
637 LEX_CSTRING *connection_name)
638{
639 char *res;
640 res= buf+ unpack_dirname(buf, slave_load_tmpdir);
641 to_unix_path(buf);
642 buf= load_data_tmp_prefix(res, connection_name);
643 buf= int10_to_str(event_server_id, buf, 10);
644 *buf++ = '-';
645 res= int10_to_str(file_id, buf, 10);
646 strmov(res, ext); // Add extension last
647 return res; // Pointer to extension
648}
649#endif
650
651
652#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
653
654/**
655 Delete all temporary files used for SQL_LOAD.
656*/
657
658static void cleanup_load_tmpdir(LEX_CSTRING *connection_name)
659{
660 MY_DIR *dirp;
661 FILEINFO *file;
662 uint i;
663 char dir[FN_REFLEN], fname[FN_REFLEN];
664 char prefbuf[31 + MAX_CONNECTION_NAME* MAX_FILENAME_MBWIDTH + 1];
665 DBUG_ENTER("cleanup_load_tmpdir");
666
667 unpack_dirname(dir, slave_load_tmpdir);
668 if (!(dirp=my_dir(dir, MYF(MY_WME))))
669 return;
670
671 /*
672 When we are deleting temporary files, we should only remove
673 the files associated with the server id of our server.
674 We don't use event_server_id here because since we've disabled
675 direct binlogging of Create_file/Append_file/Exec_load events
676 we cannot meet Start_log event in the middle of events from one
677 LOAD DATA.
678 */
679
680 load_data_tmp_prefix(prefbuf, connection_name);
681 DBUG_PRINT("enter", ("dir: '%s' prefix: '%s'", dir, prefbuf));
682
683 for (i=0 ; i < (uint)dirp->number_of_files; i++)
684 {
685 file=dirp->dir_entry+i;
686 if (is_prefix(file->name, prefbuf))
687 {
688 fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
689 mysql_file_delete(key_file_misc, fname, MYF(0));
690 }
691 }
692
693 my_dirend(dirp);
694 DBUG_VOID_RETURN;
695}
696#endif
697
698
699/*
700 read_str()
701*/
702
703static inline int read_str(const char **buf, const char *buf_end,
704 const char **str, uint8 *len)
705{
706 if (*buf + ((uint) (uchar) **buf) >= buf_end)
707 return 1;
708 *len= (uint8) **buf;
709 *str= (*buf)+1;
710 (*buf)+= (uint) *len+1;
711 return 0;
712}
713
714
715/**
716 Transforms a string into "" or its expression in X'HHHH' form.
717*/
718
719char *str_to_hex(char *to, const char *from, size_t len)
720{
721 if (len)
722 {
723 *to++= 'X';
724 *to++= '\'';
725 to= octet2hex(to, from, len);
726 *to++= '\'';
727 *to= '\0';
728 }
729 else
730 to= strmov(to, "\"\"");
731 return to; // pointer to end 0 of 'to'
732}
733
734#define BINLOG_COMPRESSED_HEADER_LEN 1
735#define BINLOG_COMPRESSED_ORIGINAL_LENGTH_MAX_BYTES 4
736/**
737 Compressed Record
738 Record Header: 1 Byte
739 7 Bit: Always 1, mean compressed;
740 4-6 Bit: Compressed algorithm - Always 0, means zlib
741 It maybe support other compression algorithm in the future.
742 0-3 Bit: Bytes of "Record Original Length"
743 Record Original Length: 1-4 Bytes
744 Compressed Buf:
745*/
746
747/**
748 Get the length of compress content.
749*/
750
751uint32 binlog_get_compress_len(uint32 len)
752{
753 /* 5 for the begin content, 1 reserved for a '\0'*/
754 return ALIGN_SIZE((BINLOG_COMPRESSED_HEADER_LEN + BINLOG_COMPRESSED_ORIGINAL_LENGTH_MAX_BYTES)
755 + compressBound(len) + 1);
756}
757
758/**
759 Compress buf from 'src' to 'dst'.
760
761 Note: 1) Then the caller should guarantee the length of 'dst', which
762 can be got by binlog_get_uncompress_len, is enough to hold
763 the content uncompressed.
764 2) The 'comlen' should stored the length of 'dst', and it will
765 be set as the size of compressed content after return.
766
767 return zero if successful, others otherwise.
768*/
769int binlog_buf_compress(const char *src, char *dst, uint32 len, uint32 *comlen)
770{
771 uchar lenlen;
772 if (len & 0xFF000000)
773 {
774 dst[1] = uchar(len >> 24);
775 dst[2] = uchar(len >> 16);
776 dst[3] = uchar(len >> 8);
777 dst[4] = uchar(len);
778 lenlen = 4;
779 }
780 else if (len & 0x00FF0000)
781 {
782 dst[1] = uchar(len >> 16);
783 dst[2] = uchar(len >> 8);
784 dst[3] = uchar(len);
785 lenlen = 3;
786 }
787 else if (len & 0x0000FF00)
788 {
789 dst[1] = uchar(len >> 8);
790 dst[2] = uchar(len);
791 lenlen = 2;
792 }
793 else
794 {
795 dst[1] = uchar(len);
796 lenlen = 1;
797 }
798 dst[0] = 0x80 | (lenlen & 0x07);
799
800 uLongf tmplen = (uLongf)*comlen - BINLOG_COMPRESSED_HEADER_LEN - lenlen - 1;
801 if (compress((Bytef *)dst + BINLOG_COMPRESSED_HEADER_LEN + lenlen, &tmplen,
802 (const Bytef *)src, (uLongf)len) != Z_OK)
803 {
804 return 1;
805 }
806 *comlen = (uint32)tmplen + BINLOG_COMPRESSED_HEADER_LEN + lenlen;
807 return 0;
808}
809
810/**
811 Convert a query_compressed_log_event to query_log_event
812 from 'src' to 'dst', the size after compression stored in 'newlen'.
813
814 @Note:
815 1) The caller should call my_free to release 'dst' if *is_malloc is
816 returned as true.
817 2) If *is_malloc is retuened as false, then 'dst' reuses the passed-in
818 'buf'.
819
820 return zero if successful, non-zero otherwise.
821*/
822
823int
824query_event_uncompress(const Format_description_log_event *description_event,
825 bool contain_checksum, const char *src, ulong src_len,
826 char* buf, ulong buf_size, bool* is_malloc, char **dst,
827 ulong *newlen)
828{
829 ulong len = uint4korr(src + EVENT_LEN_OFFSET);
830 const char *tmp = src;
831 const char *end = src + len;
832
833 // bad event
834 if (src_len < len )
835 return 1;
836
837 DBUG_ASSERT((uchar)src[EVENT_TYPE_OFFSET] == QUERY_COMPRESSED_EVENT);
838
839 uint8 common_header_len= description_event->common_header_len;
840 uint8 post_header_len=
841 description_event->post_header_len[QUERY_COMPRESSED_EVENT-1];
842
843 *is_malloc = false;
844
845 tmp += common_header_len;
846 // bad event
847 if (end <= tmp)
848 return 1;
849
850 uint db_len = (uint)tmp[Q_DB_LEN_OFFSET];
851 uint16 status_vars_len= uint2korr(tmp + Q_STATUS_VARS_LEN_OFFSET);
852
853 tmp += post_header_len + status_vars_len + db_len + 1;
854 // bad event
855 if (end <= tmp)
856 return 1;
857
858 int32 comp_len = (int32)(len - (tmp - src) -
859 (contain_checksum ? BINLOG_CHECKSUM_LEN : 0));
860 uint32 un_len = binlog_get_uncompress_len(tmp);
861
862 // bad event
863 if (comp_len < 0 || un_len == 0)
864 return 1;
865
866 *newlen = (ulong)(tmp - src) + un_len;
867 if(contain_checksum)
868 *newlen += BINLOG_CHECKSUM_LEN;
869
870 uint32 alloc_size = (uint32)ALIGN_SIZE(*newlen);
871 char *new_dst = NULL;
872
873
874 if (alloc_size <= buf_size)
875 {
876 new_dst = buf;
877 }
878 else
879 {
880 new_dst = (char *)my_malloc(alloc_size, MYF(MY_WME));
881 if (!new_dst)
882 return 1;
883
884 *is_malloc = true;
885 }
886
887 /* copy the head*/
888 memcpy(new_dst, src , tmp - src);
889 if (binlog_buf_uncompress(tmp, new_dst + (tmp - src),
890 comp_len, &un_len))
891 {
892 if (*is_malloc)
893 my_free(new_dst);
894
895 *is_malloc = false;
896
897 return 1;
898 }
899
900 new_dst[EVENT_TYPE_OFFSET] = QUERY_EVENT;
901 int4store(new_dst + EVENT_LEN_OFFSET, *newlen);
902 if(contain_checksum)
903 {
904 ulong clear_len = *newlen - BINLOG_CHECKSUM_LEN;
905 int4store(new_dst + clear_len,
906 my_checksum(0L, (uchar *)new_dst, clear_len));
907 }
908 *dst = new_dst;
909 return 0;
910}
911
912int
913row_log_event_uncompress(const Format_description_log_event *description_event,
914 bool contain_checksum, const char *src, ulong src_len,
915 char* buf, ulong buf_size, bool* is_malloc, char **dst,
916 ulong *newlen)
917{
918 Log_event_type type = (Log_event_type)(uchar)src[EVENT_TYPE_OFFSET];
919 ulong len = uint4korr(src + EVENT_LEN_OFFSET);
920 const char *tmp = src;
921 char *new_dst = NULL;
922 const char *end = tmp + len;
923
924 // bad event
925 if (src_len < len)
926 return 1;
927
928 DBUG_ASSERT(LOG_EVENT_IS_ROW_COMPRESSED(type));
929
930 uint8 common_header_len= description_event->common_header_len;
931 uint8 post_header_len= description_event->post_header_len[type-1];
932
933 tmp += common_header_len + ROWS_HEADER_LEN_V1;
934 if (post_header_len == ROWS_HEADER_LEN_V2)
935 {
936 /*
937 Have variable length header, check length,
938 which includes length bytes
939 */
940
941 // bad event
942 if (end - tmp <= 2)
943 return 1;
944
945 uint16 var_header_len= uint2korr(tmp);
946 DBUG_ASSERT(var_header_len >= 2);
947
948 /* skip over var-len header, extracting 'chunks' */
949 tmp += var_header_len;
950
951 /* get the uncompressed event type */
952 type=
953 (Log_event_type)(type - WRITE_ROWS_COMPRESSED_EVENT + WRITE_ROWS_EVENT);
954 }
955 else
956 {
957 /* get the uncompressed event type */
958 type= (Log_event_type)
959 (type - WRITE_ROWS_COMPRESSED_EVENT_V1 + WRITE_ROWS_EVENT_V1);
960 }
961
962 //bad event
963 if (end <= tmp)
964 return 1;
965
966 ulong m_width = net_field_length((uchar **)&tmp);
967 tmp += (m_width + 7) / 8;
968
969 if (type == UPDATE_ROWS_EVENT_V1 || type == UPDATE_ROWS_EVENT)
970 {
971 tmp += (m_width + 7) / 8;
972 }
973
974 //bad event
975 if (end <= tmp)
976 return 1;
977
978 uint32 un_len = binlog_get_uncompress_len(tmp);
979 //bad event
980 if (un_len == 0)
981 return 1;
982
983 int32 comp_len = (int32)(len - (tmp - src) -
984 (contain_checksum ? BINLOG_CHECKSUM_LEN : 0));
985 //bad event
986 if (comp_len <=0)
987 return 1;
988
989 *newlen = ulong(tmp - src) + un_len;
990 if(contain_checksum)
991 *newlen += BINLOG_CHECKSUM_LEN;
992
993 size_t alloc_size = ALIGN_SIZE(*newlen);
994
995 *is_malloc = false;
996 if (alloc_size <= buf_size)
997 {
998 new_dst = buf;
999 }
1000 else
1001 {
1002 new_dst = (char *)my_malloc(alloc_size, MYF(MY_WME));
1003 if (!new_dst)
1004 return 1;
1005
1006 *is_malloc = true;
1007 }
1008
1009 /* Copy the head. */
1010 memcpy(new_dst, src , tmp - src);
1011 /* Uncompress the body. */
1012 if (binlog_buf_uncompress(tmp, new_dst + (tmp - src),
1013 comp_len, &un_len))
1014 {
1015 if (*is_malloc)
1016 my_free(new_dst);
1017
1018 return 1;
1019 }
1020
1021 new_dst[EVENT_TYPE_OFFSET] = type;
1022 int4store(new_dst + EVENT_LEN_OFFSET, *newlen);
1023 if(contain_checksum){
1024 ulong clear_len = *newlen - BINLOG_CHECKSUM_LEN;
1025 int4store(new_dst + clear_len,
1026 my_checksum(0L, (uchar *)new_dst, clear_len));
1027 }
1028 *dst = new_dst;
1029 return 0;
1030}
1031
1032/**
1033 Get the length of uncompress content.
1034 return 0 means error.
1035*/
1036
1037uint32 binlog_get_uncompress_len(const char *buf)
1038{
1039 DBUG_ASSERT((buf[0] & 0xe0) == 0x80);
1040 uint32 lenlen = buf[0] & 0x07;
1041 uint32 len = 0;
1042 switch(lenlen)
1043 {
1044 case 1:
1045 len = uchar(buf[1]);
1046 break;
1047 case 2:
1048 len = uchar(buf[1]) << 8 | uchar(buf[2]);
1049 break;
1050 case 3:
1051 len = uchar(buf[1]) << 16 | uchar(buf[2]) << 8 | uchar(buf[3]);
1052 break;
1053 case 4:
1054 len = uchar(buf[1]) << 24 | uchar(buf[2]) << 16 |
1055 uchar(buf[3]) << 8 | uchar(buf[4]);
1056 break;
1057 default:
1058 DBUG_ASSERT(lenlen >= 1 && lenlen <= 4);
1059 break;
1060 }
1061 return len;
1062}
1063
1064/**
1065 Uncompress the content in 'src' with length of 'len' to 'dst'.
1066
1067 Note: 1) Then the caller should guarantee the length of 'dst' (which
1068 can be got by statement_get_uncompress_len) is enough to hold
1069 the content uncompressed.
1070 2) The 'newlen' should stored the length of 'dst', and it will
1071 be set as the size of uncompressed content after return.
1072
1073 return zero if successful, others otherwise.
1074*/
1075int binlog_buf_uncompress(const char *src, char *dst, uint32 len,
1076 uint32 *newlen)
1077{
1078 if((src[0] & 0x80) == 0)
1079 {
1080 return 1;
1081 }
1082
1083 uint32 lenlen= src[0] & 0x07;
1084 uLongf buflen= *newlen;
1085
1086 uint32 alg = (src[0] & 0x70) >> 4;
1087 switch(alg)
1088 {
1089 case 0:
1090 // zlib
1091 if(uncompress((Bytef *)dst, &buflen,
1092 (const Bytef*)src + 1 + lenlen, len - 1 - lenlen) != Z_OK)
1093 {
1094 return 1;
1095 }
1096 break;
1097 default:
1098 //TODO
1099 //bad algorithm
1100 return 1;
1101 }
1102
1103 DBUG_ASSERT(*newlen == (uint32)buflen);
1104 *newlen = (uint32)buflen;
1105 return 0;
1106}
1107
1108#ifndef MYSQL_CLIENT
1109
1110/**
1111 Append a version of the 'str' string suitable for use in a query to
1112 the 'to' string. To generate a correct escaping, the character set
1113 information in 'csinfo' is used.
1114*/
1115
1116int append_query_string(CHARSET_INFO *csinfo, String *to,
1117 const char *str, size_t len, bool no_backslash)
1118{
1119 char *beg, *ptr;
1120 uint32 const orig_len= to->length();
1121 if (to->reserve(orig_len + len * 2 + 4))
1122 return 1;
1123
1124 beg= (char*) to->ptr() + to->length();
1125 ptr= beg;
1126 if (csinfo->escape_with_backslash_is_dangerous)
1127 ptr= str_to_hex(ptr, str, len);
1128 else
1129 {
1130 *ptr++= '\'';
1131 if (!no_backslash)
1132 {
1133 ptr+= escape_string_for_mysql(csinfo, ptr, 0, str, len);
1134 }
1135 else
1136 {
1137 const char *frm_str= str;
1138
1139 for (; frm_str < (str + len); frm_str++)
1140 {
1141 /* Using '' way to represent "'" */
1142 if (*frm_str == '\'')
1143 *ptr++= *frm_str;
1144
1145 *ptr++= *frm_str;
1146 }
1147 }
1148
1149 *ptr++= '\'';
1150 }
1151 to->length((uint32)(orig_len + ptr - beg));
1152 return 0;
1153}
1154#endif
1155
1156
1157/**
1158 Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
1159 commands just before it prints a query.
1160*/
1161
1162#ifdef MYSQL_CLIENT
1163
1164static bool print_set_option(IO_CACHE* file, uint32 bits_changed,
1165 uint32 option, uint32 flags, const char* name,
1166 bool* need_comma)
1167{
1168 if (bits_changed & option)
1169 {
1170 if (*need_comma)
1171 if (my_b_write(file, (uchar*)", ", 2))
1172 goto err;
1173 if (my_b_printf(file, "%s=%d", name, MY_TEST(flags & option)))
1174 goto err;
1175 *need_comma= 1;
1176 }
1177 return 0;
1178err:
1179 return 1;
1180}
1181#endif
1182
1183/**************************************************************************
1184 Log_event methods (= the parent class of all events)
1185**************************************************************************/
1186
1187/**
1188 @return
1189 returns the human readable name of the event's type
1190*/
1191
1192const char* Log_event::get_type_str(Log_event_type type)
1193{
1194 switch(type) {
1195 case START_EVENT_V3: return "Start_v3";
1196 case STOP_EVENT: return "Stop";
1197 case QUERY_EVENT: return "Query";
1198 case ROTATE_EVENT: return "Rotate";
1199 case INTVAR_EVENT: return "Intvar";
1200 case LOAD_EVENT: return "Load";
1201 case NEW_LOAD_EVENT: return "New_load";
1202 case SLAVE_EVENT: return "Slave";
1203 case CREATE_FILE_EVENT: return "Create_file";
1204 case APPEND_BLOCK_EVENT: return "Append_block";
1205 case DELETE_FILE_EVENT: return "Delete_file";
1206 case EXEC_LOAD_EVENT: return "Exec_load";
1207 case RAND_EVENT: return "RAND";
1208 case XID_EVENT: return "Xid";
1209 case USER_VAR_EVENT: return "User var";
1210 case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
1211 case TABLE_MAP_EVENT: return "Table_map";
1212 case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
1213 case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
1214 case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
1215 case WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
1216 case UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
1217 case DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
1218 case WRITE_ROWS_EVENT: return "Write_rows";
1219 case UPDATE_ROWS_EVENT: return "Update_rows";
1220 case DELETE_ROWS_EVENT: return "Delete_rows";
1221 case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
1222 case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
1223 case INCIDENT_EVENT: return "Incident";
1224 case ANNOTATE_ROWS_EVENT: return "Annotate_rows";
1225 case BINLOG_CHECKPOINT_EVENT: return "Binlog_checkpoint";
1226 case GTID_EVENT: return "Gtid";
1227 case GTID_LIST_EVENT: return "Gtid_list";
1228 case START_ENCRYPTION_EVENT: return "Start_encryption";
1229
1230 /* The following is only for mysqlbinlog */
1231 case IGNORABLE_LOG_EVENT: return "Ignorable log event";
1232 case ROWS_QUERY_LOG_EVENT: return "MySQL Rows_query";
1233 case GTID_LOG_EVENT: return "MySQL Gtid";
1234 case ANONYMOUS_GTID_LOG_EVENT: return "MySQL Anonymous_Gtid";
1235 case PREVIOUS_GTIDS_LOG_EVENT: return "MySQL Previous_gtids";
1236 case HEARTBEAT_LOG_EVENT: return "Heartbeat";
1237 case TRANSACTION_CONTEXT_EVENT: return "Transaction_context";
1238 case VIEW_CHANGE_EVENT: return "View_change";
1239 case XA_PREPARE_LOG_EVENT: return "XA_prepare";
1240 case QUERY_COMPRESSED_EVENT: return "Query_compressed";
1241 case WRITE_ROWS_COMPRESSED_EVENT: return "Write_rows_compressed";
1242 case UPDATE_ROWS_COMPRESSED_EVENT: return "Update_rows_compressed";
1243 case DELETE_ROWS_COMPRESSED_EVENT: return "Delete_rows_compressed";
1244 case WRITE_ROWS_COMPRESSED_EVENT_V1: return "Write_rows_compressed_v1";
1245 case UPDATE_ROWS_COMPRESSED_EVENT_V1: return "Update_rows_compressed_v1";
1246 case DELETE_ROWS_COMPRESSED_EVENT_V1: return "Delete_rows_compressed_v1";
1247
1248 default: return "Unknown"; /* impossible */
1249 }
1250}
1251
1252const char* Log_event::get_type_str()
1253{
1254 return get_type_str(get_type_code());
1255}
1256
1257
1258/*
1259 Log_event::Log_event()
1260*/
1261
1262#ifndef MYSQL_CLIENT
1263Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
1264 :log_pos(0), temp_buf(0), exec_time(0), thd(thd_arg),
1265 checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
1266{
1267 server_id= thd->variables.server_id;
1268 when= thd->start_time;
1269 when_sec_part=thd->start_time_sec_part;
1270
1271 if (using_trans)
1272 cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
1273 else
1274 cache_type= Log_event::EVENT_STMT_CACHE;
1275 flags= flags_arg |
1276 (thd->variables.option_bits & OPTION_SKIP_REPLICATION ?
1277 LOG_EVENT_SKIP_REPLICATION_F : 0);
1278}
1279
1280/**
1281 This minimal constructor is for when you are not even sure that there
1282 is a valid THD. For example in the server when we are shutting down or
1283 flushing logs after receiving a SIGHUP (then we must write a Rotate to
1284 the binlog but we have no THD, so we need this minimal constructor).
1285*/
1286
1287Log_event::Log_event()
1288 :temp_buf(0), exec_time(0), flags(0), cache_type(EVENT_INVALID_CACHE),
1289 thd(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
1290{
1291 server_id= global_system_variables.server_id;
1292 /*
1293 We can't call my_time() here as this would cause a call before
1294 my_init() is called
1295 */
1296 when= 0;
1297 when_sec_part=0;
1298 log_pos= 0;
1299}
1300#endif /* !MYSQL_CLIENT */
1301
1302
1303/*
1304 Log_event::Log_event()
1305*/
1306
1307Log_event::Log_event(const char* buf,
1308 const Format_description_log_event* description_event)
1309 :temp_buf(0), exec_time(0), cache_type(Log_event::EVENT_INVALID_CACHE),
1310 checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
1311{
1312#ifndef MYSQL_CLIENT
1313 thd = 0;
1314#endif
1315 when = uint4korr(buf);
1316 when_sec_part= ~0UL;
1317 server_id = uint4korr(buf + SERVER_ID_OFFSET);
1318 data_written= uint4korr(buf + EVENT_LEN_OFFSET);
1319 if (description_event->binlog_version==1)
1320 {
1321 log_pos= 0;
1322 flags= 0;
1323 return;
1324 }
1325 /* 4.0 or newer */
1326 log_pos= uint4korr(buf + LOG_POS_OFFSET);
1327 /*
1328 If the log is 4.0 (so here it can only be a 4.0 relay log read by
1329 the SQL thread or a 4.0 master binlog read by the I/O thread),
1330 log_pos is the beginning of the event: we transform it into the end
1331 of the event, which is more useful.
1332 But how do you know that the log is 4.0: you know it if
1333 description_event is version 3 *and* you are not reading a
1334 Format_desc (remember that mysqlbinlog starts by assuming that 5.0
1335 logs are in 4.0 format, until it finds a Format_desc).
1336 */
1337 if (description_event->binlog_version==3 &&
1338 (uchar)buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
1339 {
1340 /*
1341 If log_pos=0, don't change it. log_pos==0 is a marker to mean
1342 "don't change rli->group_master_log_pos" (see
1343 inc_group_relay_log_pos()). As it is unreal log_pos, adding the
1344 event len's is nonsense. For example, a fake Rotate event should
1345 not have its log_pos (which is 0) changed or it will modify
1346 Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
1347 value of (a non-zero offset which does not exist in the master's
1348 binlog, so which will cause problems if the user uses this value
1349 in CHANGE MASTER).
1350 */
1351 log_pos+= data_written; /* purecov: inspected */
1352 }
1353 DBUG_PRINT("info", ("log_pos: %llu", log_pos));
1354
1355 flags= uint2korr(buf + FLAGS_OFFSET);
1356 if (((uchar)buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
1357 ((uchar)buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
1358 {
1359 /*
1360 These events always have a header which stops here (i.e. their
1361 header is FROZEN).
1362 */
1363 /*
1364 Initialization to zero of all other Log_event members as they're
1365 not specified. Currently there are no such members; in the future
1366 there will be an event UID (but Format_description and Rotate
1367 don't need this UID, as they are not propagated through
1368 --log-slave-updates (remember the UID is used to not play a query
1369 twice when you have two masters which are slaves of a 3rd master).
1370 Then we are done.
1371 */
1372 return;
1373 }
1374 /* otherwise, go on with reading the header from buf (nothing now) */
1375}
1376
1377#ifndef MYSQL_CLIENT
1378#ifdef HAVE_REPLICATION
1379
1380int Log_event::do_update_pos(rpl_group_info *rgi)
1381{
1382 Relay_log_info *rli= rgi->rli;
1383 DBUG_ENTER("Log_event::do_update_pos");
1384
1385 DBUG_ASSERT(!rli->belongs_to_client());
1386 /*
1387 rli is null when (as far as I (Guilhem) know) the caller is
1388 Load_log_event::do_apply_event *and* that one is called from
1389 Execute_load_log_event::do_apply_event. In this case, we don't
1390 do anything here ; Execute_load_log_event::do_apply_event will
1391 call Log_event::do_apply_event again later with the proper rli.
1392 Strictly speaking, if we were sure that rli is null only in the
1393 case discussed above, 'if (rli)' is useless here. But as we are
1394 not 100% sure, keep it for now.
1395
1396 Matz: I don't think we will need this check with this refactoring.
1397 */
1398 if (rli)
1399 {
1400 /*
1401 In parallel execution, delay position update for the events that are
1402 not part of event groups (format description, rotate, and such) until
1403 the actual event execution reaches that point.
1404 */
1405 if (!rgi->is_parallel_exec || is_group_event(get_type_code()))
1406 rli->stmt_done(log_pos, thd, rgi);
1407 }
1408 DBUG_RETURN(0); // Cannot fail currently
1409}
1410
1411
1412Log_event::enum_skip_reason
1413Log_event::do_shall_skip(rpl_group_info *rgi)
1414{
1415 Relay_log_info *rli= rgi->rli;
1416 DBUG_PRINT("info", ("ev->server_id: %lu, ::server_id: %lu,"
1417 " rli->replicate_same_server_id: %d,"
1418 " rli->slave_skip_counter: %llu",
1419 (ulong) server_id,
1420 (ulong) global_system_variables.server_id,
1421 rli->replicate_same_server_id,
1422 rli->slave_skip_counter));
1423 if ((server_id == global_system_variables.server_id &&
1424 !rli->replicate_same_server_id) ||
1425 (rli->slave_skip_counter == 1 && rli->is_in_group()) ||
1426 (flags & LOG_EVENT_SKIP_REPLICATION_F &&
1427 opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE))
1428 return EVENT_SKIP_IGNORE;
1429 if (rli->slave_skip_counter > 0)
1430 return EVENT_SKIP_COUNT;
1431 return EVENT_SKIP_NOT;
1432}
1433
1434
1435/*
1436 Log_event::pack_info()
1437*/
1438
1439void Log_event::pack_info(Protocol *protocol)
1440{
1441 protocol->store("", &my_charset_bin);
1442}
1443
1444
1445/**
1446 Only called by SHOW BINLOG EVENTS
1447*/
1448int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
1449{
1450 const char *p= strrchr(log_name, FN_LIBCHAR);
1451 const char *event_type;
1452 if (p)
1453 log_name = p + 1;
1454
1455 protocol->prepare_for_resend();
1456 protocol->store(log_name, &my_charset_bin);
1457 protocol->store((ulonglong) pos);
1458 event_type = get_type_str();
1459 protocol->store(event_type, strlen(event_type), &my_charset_bin);
1460 protocol->store((uint32) server_id);
1461 protocol->store((ulonglong) log_pos);
1462 pack_info(protocol);
1463 return protocol->write();
1464}
1465#endif /* HAVE_REPLICATION */
1466
1467
1468/**
1469 init_show_field_list() prepares the column names and types for the
1470 output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
1471 EVENTS.
1472*/
1473
1474void Log_event::init_show_field_list(THD *thd, List<Item>* field_list)
1475{
1476 MEM_ROOT *mem_root= thd->mem_root;
1477 field_list->push_back(new (mem_root)
1478 Item_empty_string(thd, "Log_name", 20),
1479 mem_root);
1480 field_list->push_back(new (mem_root)
1481 Item_return_int(thd, "Pos",
1482 MY_INT64_NUM_DECIMAL_DIGITS,
1483 MYSQL_TYPE_LONGLONG),
1484 mem_root);
1485 field_list->push_back(new (mem_root)
1486 Item_empty_string(thd, "Event_type", 20),
1487 mem_root);
1488 field_list->push_back(new (mem_root)
1489 Item_return_int(thd, "Server_id", 10,
1490 MYSQL_TYPE_LONG),
1491 mem_root);
1492 field_list->push_back(new (mem_root)
1493 Item_return_int(thd, "End_log_pos",
1494 MY_INT64_NUM_DECIMAL_DIGITS,
1495 MYSQL_TYPE_LONGLONG),
1496 mem_root);
1497 field_list->push_back(new (mem_root) Item_empty_string(thd, "Info", 20),
1498 mem_root);
1499}
1500
1501/**
1502 A decider of whether to trigger checksum computation or not.
1503 To be invoked in Log_event::write() stack.
1504 The decision is positive
1505
1506 S,M) if it's been marked for checksumming with @c checksum_alg
1507
1508 M) otherwise, if @@global.binlog_checksum is not NONE and the event is
1509 directly written to the binlog file.
1510 The to-be-cached event decides at @c write_cache() time.
1511
1512 Otherwise the decision is negative.
1513
1514 @note A side effect of the method is altering Log_event::checksum_alg
1515 it the latter was undefined at calling.
1516
1517 @return true (positive) or false (negative)
1518*/
1519my_bool Log_event::need_checksum()
1520{
1521 DBUG_ENTER("Log_event::need_checksum");
1522 my_bool ret;
1523 /*
1524 few callers of Log_event::write
1525 (incl FD::write, FD constructing code on the slave side, Rotate relay log
1526 and Stop event)
1527 provides their checksum alg preference through Log_event::checksum_alg.
1528 */
1529 if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1530 ret= checksum_alg != BINLOG_CHECKSUM_ALG_OFF;
1531 else
1532 {
1533 ret= binlog_checksum_options && cache_type == Log_event::EVENT_NO_CACHE;
1534 checksum_alg= ret ? (enum_binlog_checksum_alg)binlog_checksum_options
1535 : BINLOG_CHECKSUM_ALG_OFF;
1536 }
1537 /*
1538 FD calls the methods before data_written has been calculated.
1539 The following invariant claims if the current is not the first
1540 call (and therefore data_written is not zero) then `ret' must be
1541 TRUE. It may not be null because FD is always checksummed.
1542 */
1543
1544 DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
1545 data_written == 0);
1546
1547 DBUG_ASSERT(!ret ||
1548 ((checksum_alg == binlog_checksum_options ||
1549 /*
1550 Stop event closes the relay-log and its checksum alg
1551 preference is set by the caller can be different
1552 from the server's binlog_checksum_options.
1553 */
1554 get_type_code() == STOP_EVENT ||
1555 /*
1556 Rotate:s can be checksummed regardless of the server's
1557 binlog_checksum_options. That applies to both
1558 the local RL's Rotate and the master's Rotate
1559 which IO thread instantiates via queue_binlog_ver_3_event.
1560 */
1561 get_type_code() == ROTATE_EVENT ||
1562 get_type_code() == START_ENCRYPTION_EVENT ||
1563 /* FD is always checksummed */
1564 get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
1565 checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
1566
1567 DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
1568
1569 DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
1570 get_type_code() != STOP_EVENT) ||
1571 get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
1572 cache_type == Log_event::EVENT_NO_CACHE);
1573
1574 DBUG_RETURN(ret);
1575}
1576
1577int Log_event_writer::write_internal(const uchar *pos, size_t len)
1578{
1579 if (my_b_safe_write(file, pos, len))
1580 return 1;
1581 bytes_written+= len;
1582 return 0;
1583}
1584
1585/*
1586 as soon as encryption produces the first output block, write event_len
1587 where it should be in a valid event header
1588*/
1589int Log_event_writer::maybe_write_event_len(uchar *pos, size_t len)
1590{
1591 if (len && event_len)
1592 {
1593 DBUG_ASSERT(len >= EVENT_LEN_OFFSET);
1594 if (write_internal(pos + EVENT_LEN_OFFSET - 4, 4))
1595 return 1;
1596 int4store(pos + EVENT_LEN_OFFSET - 4, event_len);
1597 event_len= 0;
1598 }
1599 return 0;
1600}
1601
1602int Log_event_writer::encrypt_and_write(const uchar *pos, size_t len)
1603{
1604 uchar *dst= 0;
1605 size_t dstsize= 0;
1606
1607 if (ctx)
1608 {
1609 dstsize= encryption_encrypted_length((uint)len, ENCRYPTION_KEY_SYSTEM_DATA,
1610 crypto->key_version);
1611 if (!(dst= (uchar*)my_safe_alloca(dstsize)))
1612 return 1;
1613
1614 uint dstlen;
1615 if (encryption_ctx_update(ctx, pos, (uint)len, dst, &dstlen))
1616 goto err;
1617 if (maybe_write_event_len(dst, dstlen))
1618 return 1;
1619 pos= dst;
1620 len= dstlen;
1621 }
1622 if (write_internal(pos, len))
1623 goto err;
1624
1625 my_safe_afree(dst, dstsize);
1626 return 0;
1627err:
1628 my_safe_afree(dst, dstsize);
1629 return 1;
1630}
1631
1632int Log_event_writer::write_header(uchar *pos, size_t len)
1633{
1634 DBUG_ENTER("Log_event_writer::write_header");
1635 /*
1636 recording checksum of FD event computed with dropped
1637 possibly active LOG_EVENT_BINLOG_IN_USE_F flag.
1638 Similar step at verication: the active flag is dropped before
1639 checksum computing.
1640 */
1641 if (checksum_len)
1642 {
1643 uchar save=pos[FLAGS_OFFSET];
1644 pos[FLAGS_OFFSET]&= ~LOG_EVENT_BINLOG_IN_USE_F;
1645 crc= my_checksum(0, pos, len);
1646 pos[FLAGS_OFFSET]= save;
1647 }
1648
1649 if (ctx)
1650 {
1651 uchar iv[BINLOG_IV_LENGTH];
1652 crypto->set_iv(iv, (uint32)my_b_safe_tell(file));
1653 if (encryption_ctx_init(ctx, crypto->key, crypto->key_length,
1654 iv, sizeof(iv), ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
1655 ENCRYPTION_KEY_SYSTEM_DATA, crypto->key_version))
1656 DBUG_RETURN(1);
1657
1658 DBUG_ASSERT(len >= LOG_EVENT_HEADER_LEN);
1659 event_len= uint4korr(pos + EVENT_LEN_OFFSET);
1660 DBUG_ASSERT(event_len >= len);
1661 memcpy(pos + EVENT_LEN_OFFSET, pos, 4);
1662 pos+= 4;
1663 len-= 4;
1664 }
1665 DBUG_RETURN(encrypt_and_write(pos, len));
1666}
1667
1668int Log_event_writer::write_data(const uchar *pos, size_t len)
1669{
1670 DBUG_ENTER("Log_event_writer::write_data");
1671 if (checksum_len)
1672 crc= my_checksum(crc, pos, len);
1673
1674 DBUG_RETURN(encrypt_and_write(pos, len));
1675}
1676
1677int Log_event_writer::write_footer()
1678{
1679 DBUG_ENTER("Log_event_writer::write_footer");
1680 if (checksum_len)
1681 {
1682 uchar checksum_buf[BINLOG_CHECKSUM_LEN];
1683 int4store(checksum_buf, crc);
1684 if (encrypt_and_write(checksum_buf, BINLOG_CHECKSUM_LEN))
1685 DBUG_RETURN(ER_ERROR_ON_WRITE);
1686 }
1687 if (ctx)
1688 {
1689 uint dstlen;
1690 uchar dst[MY_AES_BLOCK_SIZE*2];
1691 if (encryption_ctx_finish(ctx, dst, &dstlen))
1692 DBUG_RETURN(1);
1693 if (maybe_write_event_len(dst, dstlen) || write_internal(dst, dstlen))
1694 DBUG_RETURN(ER_ERROR_ON_WRITE);
1695 }
1696 DBUG_RETURN(0);
1697}
1698
1699/*
1700 Log_event::write_header()
1701*/
1702
1703bool Log_event::write_header(size_t event_data_length)
1704{
1705 uchar header[LOG_EVENT_HEADER_LEN];
1706 ulong now;
1707 DBUG_ENTER("Log_event::write_header");
1708 DBUG_PRINT("enter", ("filepos: %lld length: %zu type: %d",
1709 (longlong) writer->pos(), event_data_length,
1710 (int) get_type_code()));
1711
1712 writer->checksum_len= need_checksum() ? BINLOG_CHECKSUM_LEN : 0;
1713
1714 /* Store number of bytes that will be written by this event */
1715 data_written= event_data_length + sizeof(header) + writer->checksum_len;
1716
1717 /*
1718 log_pos != 0 if this is relay-log event. In this case we should not
1719 change the position
1720 */
1721
1722 if (is_artificial_event())
1723 {
1724 /*
1725 Artificial events are automatically generated and do not exist
1726 in master's binary log, so log_pos should be set to 0.
1727 */
1728 log_pos= 0;
1729 }
1730 else if (!log_pos)
1731 {
1732 /*
1733 Calculate the position of where the next event will start
1734 (end of this event, that is).
1735 */
1736
1737 log_pos= writer->pos() + data_written;
1738
1739 DBUG_EXECUTE_IF("dbug_master_binlog_over_2GB", log_pos += (1ULL <<31););
1740 }
1741
1742 now= get_time(); // Query start time
1743
1744 /*
1745 Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1746 FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1747 LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1748 because we read them before knowing the format).
1749 */
1750
1751 int4store(header, now); // timestamp
1752 header[EVENT_TYPE_OFFSET]= get_type_code();
1753 int4store(header+ SERVER_ID_OFFSET, server_id);
1754 int4store(header+ EVENT_LEN_OFFSET, data_written);
1755 int4store(header+ LOG_POS_OFFSET, log_pos);
1756 int2store(header + FLAGS_OFFSET, flags);
1757
1758 bool ret= writer->write_header(header, sizeof(header));
1759 DBUG_RETURN(ret);
1760}
1761
1762#endif /* !MYSQL_CLIENT */
1763
1764/**
1765 This needn't be format-tolerant, because we only parse the first
1766 LOG_EVENT_MINIMAL_HEADER_LEN bytes (just need the event's length).
1767*/
1768
1769int Log_event::read_log_event(IO_CACHE* file, String* packet,
1770 const Format_description_log_event *fdle,
1771 enum enum_binlog_checksum_alg checksum_alg_arg)
1772{
1773 ulong data_len;
1774 char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1775 uchar ev_offset= packet->length();
1776#if !defined(MYSQL_CLIENT)
1777 THD *thd=current_thd;
1778 ulong max_allowed_packet= thd ? thd->slave_thread ? slave_max_allowed_packet
1779 : thd->variables.max_allowed_packet
1780 : ~(uint)0;
1781#endif
1782 DBUG_ENTER("Log_event::read_log_event(IO_CACHE*,String*...)");
1783
1784 if (my_b_read(file, (uchar*) buf, sizeof(buf)))
1785 {
1786 /*
1787 If the read hits eof, we must report it as eof so the caller
1788 will know it can go into cond_wait to be woken up on the next
1789 update to the log.
1790 */
1791 DBUG_PRINT("error",("file->error: %d", file->error));
1792 DBUG_RETURN(file->error == 0 ? LOG_READ_EOF :
1793 file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1794 }
1795 data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1796
1797 /* Append the log event header to packet */
1798 if (packet->append(buf, sizeof(buf)))
1799 DBUG_RETURN(LOG_READ_MEM);
1800
1801 if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN)
1802 DBUG_RETURN(LOG_READ_BOGUS);
1803
1804 if (data_len > MY_MAX(max_allowed_packet,
1805 opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
1806 DBUG_RETURN(LOG_READ_TOO_LARGE);
1807
1808 if (likely(data_len > LOG_EVENT_MINIMAL_HEADER_LEN))
1809 {
1810 /* Append rest of event, read directly from file into packet */
1811 if (packet->append(file, data_len - LOG_EVENT_MINIMAL_HEADER_LEN))
1812 {
1813 /*
1814 Fatal error occurred when appending rest of the event
1815 to packet, possible failures:
1816 1. EOF occurred when reading from file, it's really an error
1817 as there's supposed to be more bytes available.
1818 file->error will have been set to number of bytes left to read
1819 2. Read was interrupted, file->error would normally be set to -1
1820 3. Failed to allocate memory for packet, my_errno
1821 will be ENOMEM(file->error should be 0, but since the
1822 memory allocation occurs before the call to read it might
1823 be uninitialized)
1824 */
1825 DBUG_RETURN(my_errno == ENOMEM ? LOG_READ_MEM :
1826 (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1827 }
1828 }
1829
1830 if (fdle->crypto_data.scheme)
1831 {
1832 uchar iv[BINLOG_IV_LENGTH];
1833 fdle->crypto_data.set_iv(iv, (uint32) (my_b_tell(file) - data_len));
1834
1835 char *newpkt= (char*)my_malloc(data_len + ev_offset + 1, MYF(MY_WME));
1836 if (!newpkt)
1837 DBUG_RETURN(LOG_READ_MEM);
1838 memcpy(newpkt, packet->ptr(), ev_offset);
1839
1840 uint dstlen;
1841 uchar *src= (uchar*)packet->ptr() + ev_offset;
1842 uchar *dst= (uchar*)newpkt + ev_offset;
1843 memcpy(src + EVENT_LEN_OFFSET, src, 4);
1844 if (encryption_crypt(src + 4, data_len - 4, dst + 4, &dstlen,
1845 fdle->crypto_data.key, fdle->crypto_data.key_length, iv,
1846 sizeof(iv), ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD,
1847 ENCRYPTION_KEY_SYSTEM_DATA, fdle->crypto_data.key_version))
1848 {
1849 my_free(newpkt);
1850 DBUG_RETURN(LOG_READ_DECRYPT);
1851 }
1852 DBUG_ASSERT(dstlen == data_len - 4);
1853 memcpy(dst, dst + EVENT_LEN_OFFSET, 4);
1854 int4store(dst + EVENT_LEN_OFFSET, data_len);
1855 packet->reset(newpkt, data_len + ev_offset, data_len + ev_offset + 1,
1856 &my_charset_bin);
1857 }
1858
1859 /*
1860 CRC verification of the Dump thread
1861 */
1862 if (data_len > LOG_EVENT_MINIMAL_HEADER_LEN)
1863 {
1864 /* Corrupt the event for Dump thread*/
1865 DBUG_EXECUTE_IF("corrupt_read_log_event2",
1866 uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
1867 if (debug_event_buf_c[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT)
1868 {
1869 int debug_cor_pos = rand() % (data_len - BINLOG_CHECKSUM_LEN);
1870 debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1871 DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
1872 DBUG_SET("-d,corrupt_read_log_event2");
1873 }
1874 );
1875 if (event_checksum_test((uchar*) packet->ptr() + ev_offset,
1876 data_len, checksum_alg_arg))
1877 DBUG_RETURN(LOG_READ_CHECKSUM_FAILURE);
1878 }
1879 DBUG_RETURN(0);
1880}
1881
1882Log_event* Log_event::read_log_event(IO_CACHE* file,
1883 const Format_description_log_event *fdle,
1884 my_bool crc_check)
1885{
1886 DBUG_ENTER("Log_event::read_log_event(IO_CACHE*,Format_description_log_event*...)");
1887 DBUG_ASSERT(fdle != 0);
1888 String event;
1889 const char *error= 0;
1890 Log_event *res= 0;
1891
1892 switch (read_log_event(file, &event, fdle, BINLOG_CHECKSUM_ALG_OFF))
1893 {
1894 case 0:
1895 break;
1896 case LOG_READ_EOF: // no error here; we are at the file's end
1897 goto err;
1898 case LOG_READ_BOGUS:
1899 error= "Event invalid";
1900 goto err;
1901 case LOG_READ_IO:
1902 error= "read error";
1903 goto err;
1904 case LOG_READ_MEM:
1905 error= "Out of memory";
1906 goto err;
1907 case LOG_READ_TRUNC:
1908 error= "Event truncated";
1909 goto err;
1910 case LOG_READ_TOO_LARGE:
1911 error= "Event too big";
1912 goto err;
1913 case LOG_READ_DECRYPT:
1914 error= "Event decryption failure";
1915 goto err;
1916 case LOG_READ_CHECKSUM_FAILURE:
1917 default:
1918 DBUG_ASSERT(0);
1919 error= "internal error";
1920 goto err;
1921 }
1922
1923 if ((res= read_log_event(event.ptr(), event.length(),
1924 &error, fdle, crc_check)))
1925 res->register_temp_buf(event.release(), true);
1926
1927err:
1928 if (unlikely(error))
1929 {
1930 DBUG_ASSERT(!res);
1931#ifdef MYSQL_CLIENT
1932 if (force_opt)
1933 DBUG_RETURN(new Unknown_log_event());
1934#endif
1935 if (event.length() >= OLD_HEADER_LEN)
1936 sql_print_error("Error in Log_event::read_log_event(): '%s',"
1937 " data_len: %lu, event_type: %u", error,
1938 (ulong) uint4korr(&event[EVENT_LEN_OFFSET]),
1939 (uint) (uchar)event[EVENT_TYPE_OFFSET]);
1940 else
1941 sql_print_error("Error in Log_event::read_log_event(): '%s'", error);
1942 /*
1943 The SQL slave thread will check if file->error<0 to know
1944 if there was an I/O error. Even if there is no "low-level" I/O errors
1945 with 'file', any of the high-level above errors is worrying
1946 enough to stop the SQL thread now ; as we are skipping the current event,
1947 going on with reading and successfully executing other events can
1948 only corrupt the slave's databases. So stop.
1949 */
1950 file->error= -1;
1951 }
1952 DBUG_RETURN(res);
1953}
1954
1955
1956/**
1957 Binlog format tolerance is in (buf, event_len, fdle)
1958 constructors.
1959*/
1960
1961Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1962 const char **error,
1963 const Format_description_log_event *fdle,
1964 my_bool crc_check)
1965{
1966 Log_event* ev;
1967 enum enum_binlog_checksum_alg alg;
1968 DBUG_ENTER("Log_event::read_log_event(char*,...)");
1969 DBUG_ASSERT(fdle != 0);
1970 DBUG_PRINT("info", ("binlog_version: %d", fdle->binlog_version));
1971 DBUG_DUMP_EVENT_BUF(buf, event_len);
1972
1973 /*
1974 Check the integrity; This is needed because handle_slave_io() doesn't
1975 check if packet is of proper length.
1976 */
1977 if (event_len < EVENT_LEN_OFFSET)
1978 {
1979 *error="Sanity check failed"; // Needed to free buffer
1980 DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1981 }
1982
1983 uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
1984 // all following START events in the current file are without checksum
1985 if (event_type == START_EVENT_V3)
1986 (const_cast< Format_description_log_event *>(fdle))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
1987 /*
1988 CRC verification by SQL and Show-Binlog-Events master side.
1989 The caller has to provide @fdle->checksum_alg to
1990 be the last seen FD's (A) descriptor.
1991 If event is FD the descriptor is in it.
1992 Notice, FD of the binlog can be only in one instance and therefore
1993 Show-Binlog-Events executing master side thread needs just to know
1994 the only FD's (A) value - whereas RL can contain more.
1995 In the RL case, the alg is kept in FD_e (@fdle) which is reset
1996 to the newer read-out event after its execution with possibly new alg descriptor.
1997 Therefore in a typical sequence of RL:
1998 {FD_s^0, FD_m, E_m^1} E_m^1
1999 will be verified with (A) of FD_m.
2000
2001 See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
2002 lines (log.h).
2003
2004 Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
2005 */
2006 alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
2007 fdle->checksum_alg : get_checksum_alg(buf, event_len);
2008 // Emulate the corruption during reading an event
2009 DBUG_EXECUTE_IF("corrupt_read_log_event_char",
2010 if (event_type != FORMAT_DESCRIPTION_EVENT)
2011 {
2012 char *debug_event_buf_c = (char *)buf;
2013 int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
2014 debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
2015 DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
2016 DBUG_SET("-d,corrupt_read_log_event_char");
2017 }
2018 );
2019 if (crc_check &&
2020 event_checksum_test((uchar *) buf, event_len, alg))
2021 {
2022#ifdef MYSQL_CLIENT
2023 *error= "Event crc check failed! Most likely there is event corruption.";
2024 if (force_opt)
2025 {
2026 ev= new Unknown_log_event(buf, fdle);
2027 DBUG_RETURN(ev);
2028 }
2029 else
2030 DBUG_RETURN(NULL);
2031#else
2032 *error= ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
2033 sql_print_error("%s", *error);
2034 DBUG_RETURN(NULL);
2035#endif
2036 }
2037
2038 if (event_type > fdle->number_of_event_types &&
2039 event_type != FORMAT_DESCRIPTION_EVENT)
2040 {
2041 /*
2042 It is unsafe to use the fdle if its post_header_len
2043 array does not include the event type.
2044 */
2045 DBUG_PRINT("error", ("event type %d found, but the current "
2046 "Format_description_log_event supports only %d event "
2047 "types", event_type,
2048 fdle->number_of_event_types));
2049 ev= NULL;
2050 }
2051 else
2052 {
2053 /*
2054 In some previuos versions (see comment in
2055 Format_description_log_event::Format_description_log_event(char*,...)),
2056 event types were assigned different id numbers than in the
2057 present version. In order to replicate from such versions to the
2058 present version, we must map those event type id's to our event
2059 type id's. The mapping is done with the event_type_permutation
2060 array, which was set up when the Format_description_log_event
2061 was read.
2062 */
2063 if (fdle->event_type_permutation)
2064 {
2065 int new_event_type= fdle->event_type_permutation[event_type];
2066 DBUG_PRINT("info", ("converting event type %d to %d (%s)",
2067 event_type, new_event_type,
2068 get_type_str((Log_event_type)new_event_type)));
2069 event_type= new_event_type;
2070 }
2071
2072 if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
2073 (event_type == FORMAT_DESCRIPTION_EVENT ||
2074 alg != BINLOG_CHECKSUM_ALG_OFF))
2075 event_len= event_len - BINLOG_CHECKSUM_LEN;
2076
2077 switch(event_type) {
2078 case QUERY_EVENT:
2079 ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT);
2080 break;
2081 case QUERY_COMPRESSED_EVENT:
2082 ev = new Query_compressed_log_event(buf, event_len, fdle,
2083 QUERY_COMPRESSED_EVENT);
2084 break;
2085 case LOAD_EVENT:
2086 ev = new Load_log_event(buf, event_len, fdle);
2087 break;
2088 case NEW_LOAD_EVENT:
2089 ev = new Load_log_event(buf, event_len, fdle);
2090 break;
2091 case ROTATE_EVENT:
2092 ev = new Rotate_log_event(buf, event_len, fdle);
2093 break;
2094 case BINLOG_CHECKPOINT_EVENT:
2095 ev = new Binlog_checkpoint_log_event(buf, event_len, fdle);
2096 break;
2097 case GTID_EVENT:
2098 ev = new Gtid_log_event(buf, event_len, fdle);
2099 break;
2100 case GTID_LIST_EVENT:
2101 ev = new Gtid_list_log_event(buf, event_len, fdle);
2102 break;
2103 case CREATE_FILE_EVENT:
2104 ev = new Create_file_log_event(buf, event_len, fdle);
2105 break;
2106 case APPEND_BLOCK_EVENT:
2107 ev = new Append_block_log_event(buf, event_len, fdle);
2108 break;
2109 case DELETE_FILE_EVENT:
2110 ev = new Delete_file_log_event(buf, event_len, fdle);
2111 break;
2112 case EXEC_LOAD_EVENT:
2113 ev = new Execute_load_log_event(buf, event_len, fdle);
2114 break;
2115 case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
2116 ev = new Start_log_event_v3(buf, event_len, fdle);
2117 break;
2118 case STOP_EVENT:
2119 ev = new Stop_log_event(buf, fdle);
2120 break;
2121 case INTVAR_EVENT:
2122 ev = new Intvar_log_event(buf, fdle);
2123 break;
2124 case XID_EVENT:
2125 ev = new Xid_log_event(buf, fdle);
2126 break;
2127 case RAND_EVENT:
2128 ev = new Rand_log_event(buf, fdle);
2129 break;
2130 case USER_VAR_EVENT:
2131 ev = new User_var_log_event(buf, event_len, fdle);
2132 break;
2133 case FORMAT_DESCRIPTION_EVENT:
2134 ev = new Format_description_log_event(buf, event_len, fdle);
2135 break;
2136#if defined(HAVE_REPLICATION)
2137 case PRE_GA_WRITE_ROWS_EVENT:
2138 ev = new Write_rows_log_event_old(buf, event_len, fdle);
2139 break;
2140 case PRE_GA_UPDATE_ROWS_EVENT:
2141 ev = new Update_rows_log_event_old(buf, event_len, fdle);
2142 break;
2143 case PRE_GA_DELETE_ROWS_EVENT:
2144 ev = new Delete_rows_log_event_old(buf, event_len, fdle);
2145 break;
2146 case WRITE_ROWS_EVENT_V1:
2147 case WRITE_ROWS_EVENT:
2148 ev = new Write_rows_log_event(buf, event_len, fdle);
2149 break;
2150 case UPDATE_ROWS_EVENT_V1:
2151 case UPDATE_ROWS_EVENT:
2152 ev = new Update_rows_log_event(buf, event_len, fdle);
2153 break;
2154 case DELETE_ROWS_EVENT_V1:
2155 case DELETE_ROWS_EVENT:
2156 ev = new Delete_rows_log_event(buf, event_len, fdle);
2157 break;
2158
2159 case WRITE_ROWS_COMPRESSED_EVENT:
2160 case WRITE_ROWS_COMPRESSED_EVENT_V1:
2161 ev = new Write_rows_compressed_log_event(buf, event_len, fdle);
2162 break;
2163 case UPDATE_ROWS_COMPRESSED_EVENT:
2164 case UPDATE_ROWS_COMPRESSED_EVENT_V1:
2165 ev = new Update_rows_compressed_log_event(buf, event_len, fdle);
2166 break;
2167 case DELETE_ROWS_COMPRESSED_EVENT:
2168 case DELETE_ROWS_COMPRESSED_EVENT_V1:
2169 ev = new Delete_rows_compressed_log_event(buf, event_len, fdle);
2170 break;
2171
2172 /* MySQL GTID events are ignored */
2173 case GTID_LOG_EVENT:
2174 case ANONYMOUS_GTID_LOG_EVENT:
2175 case PREVIOUS_GTIDS_LOG_EVENT:
2176 case TRANSACTION_CONTEXT_EVENT:
2177 case VIEW_CHANGE_EVENT:
2178 case XA_PREPARE_LOG_EVENT:
2179 ev= new Ignorable_log_event(buf, fdle,
2180 get_type_str((Log_event_type) event_type));
2181 break;
2182
2183 case TABLE_MAP_EVENT:
2184 ev = new Table_map_log_event(buf, event_len, fdle);
2185 break;
2186#endif
2187 case BEGIN_LOAD_QUERY_EVENT:
2188 ev = new Begin_load_query_log_event(buf, event_len, fdle);
2189 break;
2190 case EXECUTE_LOAD_QUERY_EVENT:
2191 ev= new Execute_load_query_log_event(buf, event_len, fdle);
2192 break;
2193 case INCIDENT_EVENT:
2194 ev = new Incident_log_event(buf, event_len, fdle);
2195 break;
2196 case ANNOTATE_ROWS_EVENT:
2197 ev = new Annotate_rows_log_event(buf, event_len, fdle);
2198 break;
2199 case START_ENCRYPTION_EVENT:
2200 ev = new Start_encryption_log_event(buf, event_len, fdle);
2201 break;
2202 default:
2203 /*
2204 Create an object of Ignorable_log_event for unrecognized sub-class.
2205 So that SLAVE SQL THREAD will only update the position and continue.
2206 */
2207 if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
2208 {
2209 ev= new Ignorable_log_event(buf, fdle,
2210 get_type_str((Log_event_type) event_type));
2211 }
2212 else
2213 {
2214 DBUG_PRINT("error",("Unknown event code: %d",
2215 (uchar) buf[EVENT_TYPE_OFFSET]));
2216 ev= NULL;
2217 break;
2218 }
2219 }
2220 }
2221
2222 if (ev)
2223 {
2224 ev->checksum_alg= alg;
2225#ifdef MYSQL_CLIENT
2226 if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
2227 ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
2228 ev->crc= uint4korr(buf + (event_len));
2229#endif
2230 }
2231
2232 DBUG_PRINT("read_event", ("%s(type_code: %u; event_len: %u)",
2233 ev ? ev->get_type_str() : "<unknown>",
2234 (uchar)buf[EVENT_TYPE_OFFSET],
2235 event_len));
2236 /*
2237 is_valid() are small event-specific sanity tests which are
2238 important; for example there are some my_malloc() in constructors
2239 (e.g. Query_log_event::Query_log_event(char*...)); when these
2240 my_malloc() fail we can't return an error out of the constructor
2241 (because constructor is "void") ; so instead we leave the pointer we
2242 wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
2243 Same for Format_description_log_event, member 'post_header_len'.
2244
2245 SLAVE_EVENT is never used, so it should not be read ever.
2246 */
2247 if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
2248 {
2249 DBUG_PRINT("error",("Found invalid event in binary log"));
2250
2251 delete ev;
2252#ifdef MYSQL_CLIENT
2253 if (!force_opt) /* then mysqlbinlog dies */
2254 {
2255 *error= "Found invalid event in binary log";
2256 DBUG_RETURN(0);
2257 }
2258 ev= new Unknown_log_event(buf, fdle);
2259#else
2260 *error= "Found invalid event in binary log";
2261 DBUG_RETURN(0);
2262#endif
2263 }
2264 DBUG_RETURN(ev);
2265}
2266
2267#ifdef MYSQL_CLIENT
2268
2269static bool hexdump_minimal_header_to_io_cache(IO_CACHE *file,
2270 my_off_t offset,
2271 uchar *ptr)
2272{
2273 DBUG_ASSERT(LOG_EVENT_MINIMAL_HEADER_LEN == 19);
2274
2275 /*
2276 Pretty-print the first LOG_EVENT_MINIMAL_HEADER_LEN (19) bytes of the
2277 common header, which contains the basic information about the log event.
2278 Every event will have at least this much header, but events could contain
2279 more headers (which must be printed by other methods, if desired).
2280 */
2281 char emit_buf[120]; // Enough for storing one line
2282 size_t emit_buf_written;
2283
2284 if (my_b_printf(file,
2285 "# "
2286 "|Timestamp "
2287 "|Type "
2288 "|Master ID "
2289 "|Size "
2290 "|Master Pos "
2291 "|Flags\n"))
2292 goto err;
2293 emit_buf_written=
2294 my_snprintf(emit_buf, sizeof(emit_buf),
2295 "# %8llx " /* Position */
2296 "|%02x %02x %02x %02x " /* Timestamp */
2297 "|%02x " /* Type */
2298 "|%02x %02x %02x %02x " /* Master ID */
2299 "|%02x %02x %02x %02x " /* Size */
2300 "|%02x %02x %02x %02x " /* Master Pos */
2301 "|%02x %02x\n", /* Flags */
2302 (ulonglong) offset, /* Position */
2303 ptr[0], ptr[1], ptr[2], ptr[3], /* Timestamp */
2304 ptr[4], /* Type */
2305 ptr[5], ptr[6], ptr[7], ptr[8], /* Master ID */
2306 ptr[9], ptr[10], ptr[11], ptr[12], /* Size */
2307 ptr[13], ptr[14], ptr[15], ptr[16], /* Master Pos */
2308 ptr[17], ptr[18]); /* Flags */
2309
2310 DBUG_ASSERT(static_cast<size_t>(emit_buf_written) < sizeof(emit_buf));
2311 if (my_b_write(file, reinterpret_cast<uchar*>(emit_buf), emit_buf_written) ||
2312 my_b_write(file, (uchar*)"#\n", 2))
2313 goto err;
2314
2315 return 0;
2316err:
2317 return 1;
2318}
2319
2320
2321/*
2322 The number of bytes to print per line. Should be an even number,
2323 and "hexdump -C" uses 16, so we'll duplicate that here.
2324*/
2325#define HEXDUMP_BYTES_PER_LINE 16
2326
2327static void format_hex_line(char *emit_buff)
2328{
2329 memset(emit_buff + 1, ' ',
2330 1 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
2331 HEXDUMP_BYTES_PER_LINE);
2332 emit_buff[0]= '#';
2333 emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 1]= '|';
2334 emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
2335 HEXDUMP_BYTES_PER_LINE]= '|';
2336 emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
2337 HEXDUMP_BYTES_PER_LINE + 1]= '\n';
2338 emit_buff[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
2339 HEXDUMP_BYTES_PER_LINE + 2]= '\0';
2340}
2341
2342static bool hexdump_data_to_io_cache(IO_CACHE *file,
2343 my_off_t offset,
2344 uchar *ptr,
2345 my_off_t size)
2346{
2347 /*
2348 2 = '# '
2349 8 = address
2350 2 = ' '
2351 (HEXDUMP_BYTES_PER_LINE * 3 + 1) = Each byte prints as two hex digits,
2352 plus a space
2353 2 = ' |'
2354 HEXDUMP_BYTES_PER_LINE = text representation
2355 2 = '|\n'
2356 1 = '\0'
2357 */
2358 char emit_buffer[2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2 +
2359 HEXDUMP_BYTES_PER_LINE + 2 + 1 ];
2360 char *h,*c;
2361 my_off_t i;
2362
2363 if (size == 0)
2364 return 0; // ok, nothing to do
2365
2366 format_hex_line(emit_buffer);
2367 /*
2368 Print the rest of the event (without common header)
2369 */
2370 my_off_t starting_offset = offset;
2371 for (i= 0,
2372 c= emit_buffer + 2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2,
2373 h= emit_buffer + 2 + 8 + 2;
2374 i < size;
2375 i++, ptr++)
2376 {
2377 my_snprintf(h, 4, "%02x ", *ptr);
2378 h+= 3;
2379
2380 *c++= my_isprint(&my_charset_bin, *ptr) ? *ptr : '.';
2381
2382 /* Print in groups of HEXDUMP_BYTES_PER_LINE characters. */
2383 if ((i % HEXDUMP_BYTES_PER_LINE) == (HEXDUMP_BYTES_PER_LINE - 1))
2384 {
2385 /* remove \0 left after printing hex byte representation */
2386 *h= ' ';
2387 /* prepare space to print address */
2388 memset(emit_buffer + 2, ' ', 8);
2389 /* print address */
2390 size_t const emit_buf_written= my_snprintf(emit_buffer + 2, 9, "%8llx",
2391 (ulonglong) starting_offset);
2392 /* remove \0 left after printing address */
2393 emit_buffer[2 + emit_buf_written]= ' ';
2394 if (my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
2395 sizeof(emit_buffer) - 1))
2396 goto err;
2397 c= emit_buffer + 2 + 8 + 2 + (HEXDUMP_BYTES_PER_LINE * 3 + 1) + 2;
2398 h= emit_buffer + 2 + 8 + 2;
2399 format_hex_line(emit_buffer);
2400 starting_offset+= HEXDUMP_BYTES_PER_LINE;
2401 }
2402 else if ((i % (HEXDUMP_BYTES_PER_LINE / 2))
2403 == ((HEXDUMP_BYTES_PER_LINE / 2) - 1))
2404 {
2405 /*
2406 In the middle of the group of HEXDUMP_BYTES_PER_LINE, emit an extra
2407 space in the hex string, to make two groups.
2408 */
2409 *h++= ' ';
2410 }
2411
2412 }
2413
2414 /*
2415 There is still data left in our buffer, which means that the previous
2416 line was not perfectly HEXDUMP_BYTES_PER_LINE characters, so write an
2417 incomplete line, with spaces to pad out to the same length as a full
2418 line would be, to make things more readable.
2419 */
2420 if (h != emit_buffer + 2 + 8 + 2)
2421 {
2422 *h= ' ';
2423 *c++= '|'; *c++= '\n';
2424 memset(emit_buffer + 2, ' ', 8);
2425 size_t const emit_buf_written= my_snprintf(emit_buffer + 2, 9, "%8llx",
2426 (ulonglong) starting_offset);
2427 emit_buffer[2 + emit_buf_written]= ' ';
2428 /* pad unprinted area */
2429 memset(h, ' ',
2430 (HEXDUMP_BYTES_PER_LINE * 3 + 1) - (h - (emit_buffer + 2 + 8 + 2)));
2431 if (my_b_write(file, reinterpret_cast<uchar*>(emit_buffer),
2432 c - emit_buffer))
2433 goto err;
2434 }
2435 if (my_b_write(file, (uchar*)"#\n", 2))
2436 goto err;
2437
2438 return 0;
2439err:
2440 return 1;
2441}
2442
2443/*
2444 Log_event::print_header()
2445*/
2446
2447bool Log_event::print_header(IO_CACHE* file,
2448 PRINT_EVENT_INFO* print_event_info,
2449 bool is_more __attribute__((unused)))
2450{
2451 char llbuff[22];
2452 my_off_t hexdump_from= print_event_info->hexdump_from;
2453 DBUG_ENTER("Log_event::print_header");
2454
2455 if (my_b_write_byte(file, '#') ||
2456 print_timestamp(file) ||
2457 my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
2458 llstr(log_pos,llbuff)))
2459 goto err;
2460
2461 /* print the checksum */
2462
2463 if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
2464 checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
2465 {
2466 char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "%p "
2467 size_t const bytes_written=
2468 my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08x ", crc);
2469 if (my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib,
2470 checksum_alg)) ||
2471 my_b_printf(file, checksum_buf, bytes_written))
2472 goto err;
2473 }
2474
2475 /* mysqlbinlog --hexdump */
2476 if (print_event_info->hexdump_from)
2477 {
2478 my_b_write_byte(file, '\n');
2479 uchar *ptr= (uchar*)temp_buf;
2480 my_off_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
2481 my_off_t hdr_len= get_header_len(print_event_info->common_header_len);
2482
2483 size-= hdr_len;
2484
2485 if (my_b_printf(file, "# Position\n"))
2486 goto err;
2487
2488 /* Write the header, nicely formatted by field. */
2489 if (hexdump_minimal_header_to_io_cache(file, hexdump_from, ptr))
2490 goto err;
2491
2492 ptr+= hdr_len;
2493 hexdump_from+= hdr_len;
2494
2495 /* Print the rest of the data, mimicking "hexdump -C" output. */
2496 if (hexdump_data_to_io_cache(file, hexdump_from, ptr, size))
2497 goto err;
2498
2499 /*
2500 Prefix the next line so that the output from print_helper()
2501 will appear as a comment.
2502 */
2503 if (my_b_write(file, (uchar*)"# Event: ", 9))
2504 goto err;
2505 }
2506
2507 DBUG_RETURN(0);
2508
2509err:
2510 DBUG_RETURN(1);
2511}
2512
2513
2514/**
2515 Prints a quoted string to io cache.
2516 Control characters are displayed as hex sequence, e.g. \x00
2517 Single-quote and backslash characters are escaped with a \
2518
2519 @param[in] file IO cache
2520 @param[in] prt Pointer to string
2521 @param[in] length String length
2522*/
2523
2524static void
2525my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
2526{
2527 const uchar *s;
2528 my_b_write_byte(file, '\'');
2529 for (s= ptr; length > 0 ; s++, length--)
2530 {
2531 if (*s > 0x1F)
2532 my_b_write_byte(file, *s);
2533 else if (*s == '\'')
2534 my_b_write(file, (uchar*)"\\'", 2);
2535 else if (*s == '\\')
2536 my_b_write(file, (uchar*)"\\\\", 2);
2537 else
2538 {
2539 uchar hex[10];
2540 size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
2541 my_b_write(file, hex, len);
2542 }
2543 }
2544 my_b_write_byte(file, '\'');
2545}
2546
2547
2548/**
2549 Prints a bit string to io cache in format b'1010'.
2550
2551 @param[in] file IO cache
2552 @param[in] ptr Pointer to string
2553 @param[in] nbits Number of bits
2554*/
2555static void
2556my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
2557{
2558 uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
2559 my_b_write(file, (uchar*)"b'", 2);
2560 for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
2561 {
2562 int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
2563 my_b_write_byte(file, (is_set ? '1' : '0'));
2564 }
2565 my_b_write_byte(file, '\'');
2566}
2567
2568
2569/**
2570 Prints a packed string to io cache.
2571 The string consists of length packed to 1 or 2 bytes,
2572 followed by string data itself.
2573
2574 @param[in] file IO cache
2575 @param[in] ptr Pointer to string
2576 @param[in] length String size
2577
2578 @retval - number of bytes scanned.
2579*/
2580static size_t
2581my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
2582{
2583 if (length < 256)
2584 {
2585 length= *ptr;
2586 my_b_write_quoted(file, ptr + 1, length);
2587 return length + 1;
2588 }
2589 else
2590 {
2591 length= uint2korr(ptr);
2592 my_b_write_quoted(file, ptr + 2, length);
2593 return length + 2;
2594 }
2595}
2596
2597
2598/**
2599 Prints a 32-bit number in both signed and unsigned representation
2600
2601 @param[in] file IO cache
2602 @param[in] sl Signed number
2603 @param[in] ul Unsigned number
2604*/
2605static bool
2606my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
2607{
2608 bool res= my_b_printf(file, "%d", si);
2609 if (si < 0)
2610 if (my_b_printf(file, " (%u)", ui))
2611 res= 1;
2612 return res;
2613}
2614
2615
2616/**
2617 Print a packed value of the given SQL type into IO cache
2618
2619 @param[in] file IO cache
2620 @param[in] ptr Pointer to string
2621 @param[in] type Column type
2622 @param[in] meta Column meta information
2623 @param[out] typestr SQL type string buffer (for verbose output)
2624 @param[out] typestr_length Size of typestr
2625
2626 @retval - number of bytes scanned from ptr.
2627 Except in case of NULL, in which case we return 1 to indicate ok
2628*/
2629
2630static size_t
2631log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info,
2632 const uchar *ptr, uint type, uint meta,
2633 char *typestr, size_t typestr_length)
2634{
2635 uint32 length= 0;
2636
2637 if (type == MYSQL_TYPE_STRING)
2638 {
2639 if (meta >= 256)
2640 {
2641 uint byte0= meta >> 8;
2642 uint byte1= meta & 0xFF;
2643
2644 if ((byte0 & 0x30) != 0x30)
2645 {
2646 /* a long CHAR() field: see #37426 */
2647 length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
2648 type= byte0 | 0x30;
2649 }
2650 else
2651 length = meta & 0xFF;
2652 }
2653 else
2654 length= meta;
2655 }
2656
2657 switch (type) {
2658 case MYSQL_TYPE_LONG:
2659 {
2660 strmake(typestr, "INT", typestr_length);
2661 if (!ptr)
2662 goto return_null;
2663
2664 int32 si= sint4korr(ptr);
2665 uint32 ui= uint4korr(ptr);
2666 my_b_write_sint32_and_uint32(file, si, ui);
2667 return 4;
2668 }
2669
2670 case MYSQL_TYPE_TINY:
2671 {
2672 strmake(typestr, "TINYINT", typestr_length);
2673 if (!ptr)
2674 goto return_null;
2675
2676 my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
2677 (uint) (unsigned char) *ptr);
2678 return 1;
2679 }
2680
2681 case MYSQL_TYPE_SHORT:
2682 {
2683 strmake(typestr, "SHORTINT", typestr_length);
2684 if (!ptr)
2685 goto return_null;
2686
2687 int32 si= (int32) sint2korr(ptr);
2688 uint32 ui= (uint32) uint2korr(ptr);
2689 my_b_write_sint32_and_uint32(file, si, ui);
2690 return 2;
2691 }
2692
2693 case MYSQL_TYPE_INT24:
2694 {
2695 strmake(typestr, "MEDIUMINT", typestr_length);
2696 if (!ptr)
2697 goto return_null;
2698
2699 int32 si= sint3korr(ptr);
2700 uint32 ui= uint3korr(ptr);
2701 my_b_write_sint32_and_uint32(file, si, ui);
2702 return 3;
2703 }
2704
2705 case MYSQL_TYPE_LONGLONG:
2706 {
2707 strmake(typestr, "LONGINT", typestr_length);
2708 if (!ptr)
2709 goto return_null;
2710
2711 char tmp[64];
2712 size_t length;
2713 longlong si= sint8korr(ptr);
2714 length= (longlong10_to_str(si, tmp, -10) - tmp);
2715 my_b_write(file, (uchar*)tmp, length);
2716 if (si < 0)
2717 {
2718 ulonglong ui= uint8korr(ptr);
2719 longlong10_to_str((longlong) ui, tmp, 10);
2720 my_b_printf(file, " (%s)", tmp);
2721 }
2722 return 8;
2723 }
2724
2725 case MYSQL_TYPE_NEWDECIMAL:
2726 {
2727 uint precision= meta >> 8;
2728 uint decimals= meta & 0xFF;
2729 my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2730 precision, decimals);
2731 if (!ptr)
2732 goto return_null;
2733
2734 uint bin_size= my_decimal_get_binary_size(precision, decimals);
2735 my_decimal dec;
2736 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2737 precision, decimals);
2738 int length= DECIMAL_MAX_STR_LENGTH;
2739 char buff[DECIMAL_MAX_STR_LENGTH + 1];
2740 decimal2string(&dec, buff, &length, 0, 0, 0);
2741 my_b_write(file, (uchar*)buff, length);
2742 return bin_size;
2743 }
2744
2745 case MYSQL_TYPE_FLOAT:
2746 {
2747 strmake(typestr, "FLOAT", typestr_length);
2748 if (!ptr)
2749 goto return_null;
2750
2751 float fl;
2752 float4get(fl, ptr);
2753 char tmp[320];
2754 sprintf(tmp, "%-20g", (double) fl);
2755 my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2756 return 4;
2757 }
2758
2759 case MYSQL_TYPE_DOUBLE:
2760 {
2761 double dbl;
2762 strmake(typestr, "DOUBLE", typestr_length);
2763 if (!ptr)
2764 goto return_null;
2765
2766 float8get(dbl, ptr);
2767 char tmp[320];
2768 sprintf(tmp, "%-.20g", dbl); /* strmake doesn't support %-20g */
2769 my_b_printf(file, tmp, "%s");
2770 return 8;
2771 }
2772
2773 case MYSQL_TYPE_BIT:
2774 {
2775 /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2776 uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2777 my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2778 if (!ptr)
2779 goto return_null;
2780
2781 length= (nbits + 7) / 8;
2782 my_b_write_bit(file, ptr, nbits);
2783 return length;
2784 }
2785
2786 case MYSQL_TYPE_TIMESTAMP:
2787 {
2788 strmake(typestr, "TIMESTAMP", typestr_length);
2789 if (!ptr)
2790 goto return_null;
2791
2792 uint32 i32= uint4korr(ptr);
2793 my_b_printf(file, "%d", i32);
2794 return 4;
2795 }
2796
2797 case MYSQL_TYPE_TIMESTAMP2:
2798 {
2799 my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2800 if (!ptr)
2801 goto return_null;
2802
2803 char buf[MAX_DATE_STRING_REP_LENGTH];
2804 struct timeval tm;
2805 my_timestamp_from_binary(&tm, ptr, meta);
2806 int buflen= my_timeval_to_str(&tm, buf, meta);
2807 my_b_write(file, (uchar*)buf, buflen);
2808 return my_timestamp_binary_length(meta);
2809 }
2810
2811 case MYSQL_TYPE_DATETIME:
2812 {
2813 strmake(typestr, "DATETIME", typestr_length);
2814 if (!ptr)
2815 goto return_null;
2816
2817 ulong d, t;
2818 uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2819 d= (ulong) (i64 / 1000000);
2820 t= (ulong) (i64 % 1000000);
2821
2822 my_b_printf(file, "'%04d-%02d-%02d %02d:%02d:%02d'",
2823 (int) (d / 10000), (int) (d % 10000) / 100, (int) (d % 100),
2824 (int) (t / 10000), (int) (t % 10000) / 100, (int) t % 100);
2825 return 8;
2826 }
2827
2828 case MYSQL_TYPE_DATETIME2:
2829 {
2830 my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2831 if (!ptr)
2832 goto return_null;
2833
2834 char buf[MAX_DATE_STRING_REP_LENGTH];
2835 MYSQL_TIME ltime;
2836 longlong packed= my_datetime_packed_from_binary(ptr, meta);
2837 TIME_from_longlong_datetime_packed(&ltime, packed);
2838 int buflen= my_datetime_to_str(&ltime, buf, meta);
2839 my_b_write_quoted(file, (uchar *) buf, buflen);
2840 return my_datetime_binary_length(meta);
2841 }
2842
2843 case MYSQL_TYPE_TIME:
2844 {
2845 strmake(typestr, "TIME", typestr_length);
2846 if (!ptr)
2847 goto return_null;
2848
2849 int32 tmp= sint3korr(ptr);
2850 int32 i32= tmp >= 0 ? tmp : - tmp;
2851 const char *sign= tmp < 0 ? "-" : "";
2852 my_b_printf(file, "'%s%02d:%02d:%02d'",
2853 sign, i32 / 10000, (i32 % 10000) / 100, i32 % 100, i32);
2854 return 3;
2855 }
2856
2857 case MYSQL_TYPE_TIME2:
2858 {
2859 my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2860 if (!ptr)
2861 goto return_null;
2862
2863 char buf[MAX_DATE_STRING_REP_LENGTH];
2864 MYSQL_TIME ltime;
2865 longlong packed= my_time_packed_from_binary(ptr, meta);
2866 TIME_from_longlong_time_packed(&ltime, packed);
2867 int buflen= my_time_to_str(&ltime, buf, meta);
2868 my_b_write_quoted(file, (uchar *) buf, buflen);
2869 return my_time_binary_length(meta);
2870 }
2871
2872 case MYSQL_TYPE_NEWDATE:
2873 {
2874 strmake(typestr, "DATE", typestr_length);
2875 if (!ptr)
2876 goto return_null;
2877
2878 uint32 tmp= uint3korr(ptr);
2879 int part;
2880 char buf[11];
2881 char *pos= &buf[10]; // start from '\0' to the beginning
2882
2883 /* Copied from field.cc */
2884 *pos--=0; // End NULL
2885 part=(int) (tmp & 31);
2886 *pos--= (char) ('0'+part%10);
2887 *pos--= (char) ('0'+part/10);
2888 *pos--= ':';
2889 part=(int) (tmp >> 5 & 15);
2890 *pos--= (char) ('0'+part%10);
2891 *pos--= (char) ('0'+part/10);
2892 *pos--= ':';
2893 part=(int) (tmp >> 9);
2894 *pos--= (char) ('0'+part%10); part/=10;
2895 *pos--= (char) ('0'+part%10); part/=10;
2896 *pos--= (char) ('0'+part%10); part/=10;
2897 *pos= (char) ('0'+part);
2898 my_b_printf(file , "'%s'", buf);
2899 return 3;
2900 }
2901
2902 case MYSQL_TYPE_DATE:
2903 {
2904 strmake(typestr, "DATE", typestr_length);
2905 if (!ptr)
2906 goto return_null;
2907
2908 uint i32= uint3korr(ptr);
2909 my_b_printf(file , "'%04d:%02d:%02d'",
2910 (int)(i32 / (16L * 32L)), (int)(i32 / 32L % 16L),
2911 (int)(i32 % 32L));
2912 return 3;
2913 }
2914
2915 case MYSQL_TYPE_YEAR:
2916 {
2917 strmake(typestr, "YEAR", typestr_length);
2918 if (!ptr)
2919 goto return_null;
2920
2921 uint32 i32= *ptr;
2922 my_b_printf(file, "%04d", i32+ 1900);
2923 return 1;
2924 }
2925
2926 case MYSQL_TYPE_ENUM:
2927 switch (meta & 0xFF) {
2928 case 1:
2929 strmake(typestr, "ENUM(1 byte)", typestr_length);
2930 if (!ptr)
2931 goto return_null;
2932
2933 my_b_printf(file, "%d", (int) *ptr);
2934 return 1;
2935 case 2:
2936 {
2937 strmake(typestr, "ENUM(2 bytes)", typestr_length);
2938 if (!ptr)
2939 goto return_null;
2940
2941 int32 i32= uint2korr(ptr);
2942 my_b_printf(file, "%d", i32);
2943 return 2;
2944 }
2945 default:
2946 my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2947 return 0;
2948 }
2949 break;
2950
2951 case MYSQL_TYPE_SET:
2952 my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2953 if (!ptr)
2954 goto return_null;
2955
2956 my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2957 return meta & 0xFF;
2958
2959 case MYSQL_TYPE_BLOB:
2960 switch (meta) {
2961 case 1:
2962 strmake(typestr, "TINYBLOB/TINYTEXT", typestr_length);
2963 if (!ptr)
2964 goto return_null;
2965
2966 length= *ptr;
2967 my_b_write_quoted(file, ptr + 1, length);
2968 return length + 1;
2969 case 2:
2970 strmake(typestr, "BLOB/TEXT", typestr_length);
2971 if (!ptr)
2972 goto return_null;
2973
2974 length= uint2korr(ptr);
2975 my_b_write_quoted(file, ptr + 2, length);
2976 return length + 2;
2977 case 3:
2978 strmake(typestr, "MEDIUMBLOB/MEDIUMTEXT", typestr_length);
2979 if (!ptr)
2980 goto return_null;
2981
2982 length= uint3korr(ptr);
2983 my_b_write_quoted(file, ptr + 3, length);
2984 return length + 3;
2985 case 4:
2986 strmake(typestr, "LONGBLOB/LONGTEXT", typestr_length);
2987 if (!ptr)
2988 goto return_null;
2989
2990 length= uint4korr(ptr);
2991 my_b_write_quoted(file, ptr + 4, length);
2992 return length + 4;
2993 default:
2994 my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2995 return 0;
2996 }
2997
2998 case MYSQL_TYPE_VARCHAR:
2999 case MYSQL_TYPE_VAR_STRING:
3000 length= meta;
3001 my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
3002 if (!ptr)
3003 goto return_null;
3004
3005 return my_b_write_quoted_with_length(file, ptr, length);
3006
3007 case MYSQL_TYPE_STRING:
3008 my_snprintf(typestr, typestr_length, "STRING(%d)", length);
3009 if (!ptr)
3010 goto return_null;
3011
3012 return my_b_write_quoted_with_length(file, ptr, length);
3013
3014 case MYSQL_TYPE_DECIMAL:
3015 print_event_info->flush_for_error();
3016 fprintf(stderr, "\nError: Found Old DECIMAL (mysql-4.1 or earlier). "
3017 "Not enough metadata to display the value.\n");
3018 break;
3019 default:
3020 print_event_info->flush_for_error();
3021 fprintf(stderr,
3022 "\nError: Don't know how to handle column type: %d meta: %d (%04x)\n",
3023 type, meta, meta);
3024 break;
3025 }
3026 *typestr= 0;
3027 return 0;
3028
3029return_null:
3030 return my_b_write(file, (uchar*) "NULL", 4) ? 0 : 1;
3031}
3032
3033
3034/**
3035 Print a packed row into IO cache
3036
3037 @param[in] file IO cache
3038 @param[in] td Table definition
3039 @param[in] print_event_into Print parameters
3040 @param[in] cols_bitmap Column bitmaps.
3041 @param[in] value Pointer to packed row
3042 @param[in] prefix Row's SQL clause ("SET", "WHERE", etc)
3043
3044 @retval 0 error
3045 # number of bytes scanned.
3046*/
3047
3048
3049size_t
3050Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
3051 PRINT_EVENT_INFO *print_event_info,
3052 MY_BITMAP *cols_bitmap,
3053 const uchar *value, const uchar *prefix,
3054 const my_bool no_fill_output)
3055{
3056 const uchar *value0= value;
3057 const uchar *null_bits= value;
3058 uint null_bit_index= 0;
3059 char typestr[64]= "";
3060
3061#ifdef WHEN_FLASHBACK_REVIEW_READY
3062 /* Storing the review SQL */
3063 IO_CACHE *review_sql= &print_event_info->review_sql_cache;
3064 LEX_STRING review_str;
3065#endif
3066
3067 /*
3068 Skip metadata bytes which gives the information about nullabity of master
3069 columns. Master writes one bit for each affected column.
3070 */
3071
3072 value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
3073
3074 if (!no_fill_output)
3075 if (my_b_printf(file, "%s", prefix))
3076 goto err;
3077
3078 for (uint i= 0; i < (uint)td->size(); i ++)
3079 {
3080 size_t size;
3081 int is_null= (null_bits[null_bit_index / 8]
3082 >> (null_bit_index % 8)) & 0x01;
3083
3084 if (bitmap_is_set(cols_bitmap, i) == 0)
3085 continue;
3086
3087 if (!no_fill_output)
3088 if (my_b_printf(file, "### @%d=", static_cast<int>(i + 1)))
3089 goto err;
3090
3091 if (!is_null)
3092 {
3093 size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
3094 if (value + fsize > m_rows_end)
3095 {
3096 if (!no_fill_output)
3097 if (my_b_printf(file, "***Corrupted replication event was detected."
3098 " Not printing the value***\n"))
3099 goto err;
3100 value+= fsize;
3101 return 0;
3102 }
3103 }
3104
3105 if (!no_fill_output)
3106 {
3107 size= log_event_print_value(file, print_event_info, is_null? NULL: value,
3108 td->type(i), td->field_metadata(i),
3109 typestr, sizeof(typestr));
3110#ifdef WHEN_FLASHBACK_REVIEW_READY
3111 if (need_flashback_review)
3112 {
3113 String tmp_str, hex_str;
3114 IO_CACHE tmp_cache;
3115
3116 // Using a tmp IO_CACHE to get the value output
3117 open_cached_file(&tmp_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP));
3118 size= log_event_print_value(&tmp_cache, print_event_info,
3119 is_null ? NULL: value,
3120 td->type(i), td->field_metadata(i),
3121 typestr, sizeof(typestr));
3122 error= copy_event_cache_to_string_and_reinit(&tmp_cache, &review_str);
3123 close_cached_file(&tmp_cache);
3124 if (unlikely(error))
3125 return 0;
3126
3127 switch (td->type(i)) // Converting a string to HEX format
3128 {
3129 case MYSQL_TYPE_VARCHAR:
3130 case MYSQL_TYPE_VAR_STRING:
3131 case MYSQL_TYPE_STRING:
3132 case MYSQL_TYPE_BLOB:
3133 // Avoid write_pos changed to a new area
3134 // tmp_str.free();
3135 tmp_str.append(review_str.str + 1, review_str.length - 2); // Removing quotation marks
3136 if (hex_str.alloc(tmp_str.length()*2+1)) // If out of memory
3137 {
3138 fprintf(stderr, "\nError: Out of memory. "
3139 "Could not print correct binlog event.\n");
3140 exit(1);
3141 }
3142 octet2hex((char*) hex_str.ptr(), tmp_str.ptr(), tmp_str.length());
3143 if (my_b_printf(review_sql, ", UNHEX('%s')", hex_str.ptr()))
3144 goto err;
3145 break;
3146 default:
3147 tmp_str.free();
3148 if (tmp_str.append(review_str.str, review_str.length) ||
3149 my_b_printf(review_sql, ", %s", tmp_str.ptr()))
3150 goto err;
3151 break;
3152 }
3153 my_free(revieww_str.str);
3154 }
3155#endif
3156 }
3157 else
3158 {
3159 IO_CACHE tmp_cache;
3160 open_cached_file(&tmp_cache, NULL, NULL, 0, MYF(MY_WME | MY_NABP));
3161 size= log_event_print_value(&tmp_cache, print_event_info,
3162 is_null ? NULL: value,
3163 td->type(i), td->field_metadata(i),
3164 typestr, sizeof(typestr));
3165 close_cached_file(&tmp_cache);
3166 }
3167
3168 if (!size)
3169 goto err;
3170
3171 if (!is_null)
3172 value+= size;
3173
3174 if (print_event_info->verbose > 1 && !no_fill_output)
3175 {
3176 if (my_b_write(file, (uchar*)" /* ", 4) ||
3177 my_b_printf(file, "%s ", typestr) ||
3178 my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
3179 td->field_metadata(i),
3180 td->maybe_null(i), is_null) ||
3181 my_b_write(file, (uchar*)"*/", 2))
3182 goto err;
3183 }
3184
3185 if (!no_fill_output)
3186 if (my_b_write_byte(file, '\n'))
3187 goto err;
3188
3189 null_bit_index++;
3190 }
3191 return value - value0;
3192
3193err:
3194 return 0;
3195}
3196
3197
3198/**
3199 Exchange the SET part and WHERE part for the Update events.
3200 Revert the operations order for the Write and Delete events.
3201 And then revert the events order from the last one to the first one.
3202
3203 @param[in] print_event_info PRINT_EVENT_INFO
3204 @param[in] rows_buff Packed event buff
3205*/
3206
3207void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_info,
3208 uchar *rows_buff, Log_event_type ev_type)
3209{
3210 Table_map_log_event *map;
3211 table_def *td;
3212 DYNAMIC_ARRAY rows_arr;
3213 uchar *swap_buff1, *swap_buff2;
3214 uchar *rows_pos= rows_buff + m_rows_before_size;
3215
3216 if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
3217 !(td= map->create_table_def()))
3218 return;
3219
3220 /* If the write rows event contained no values for the AI */
3221 if (((get_general_type_code() == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
3222 goto end;
3223
3224 (void) my_init_dynamic_array(&rows_arr, sizeof(LEX_STRING), 8, 8, MYF(0));
3225
3226 for (uchar *value= m_rows_buf; value < m_rows_end; )
3227 {
3228 uchar *start_pos= value;
3229 size_t length1= 0;
3230 if (!(length1= print_verbose_one_row(NULL, td, print_event_info,
3231 &m_cols, value,
3232 (const uchar*) "", TRUE)))
3233 {
3234 fprintf(stderr, "\nError row length: %zu\n", length1);
3235 exit(1);
3236 }
3237 value+= length1;
3238
3239 swap_buff1= (uchar *) my_malloc(length1, MYF(0));
3240 if (!swap_buff1)
3241 {
3242 fprintf(stderr, "\nError: Out of memory. "
3243 "Could not exchange to flashback event.\n");
3244 exit(1);
3245 }
3246 memcpy(swap_buff1, start_pos, length1);
3247
3248 // For Update_event, we have the second part
3249 size_t length2= 0;
3250 if (ev_type == UPDATE_ROWS_EVENT ||
3251 ev_type == UPDATE_ROWS_EVENT_V1)
3252 {
3253 if (!(length2= print_verbose_one_row(NULL, td, print_event_info,
3254 &m_cols, value,
3255 (const uchar*) "", TRUE)))
3256 {
3257 fprintf(stderr, "\nError row length: %zu\n", length2);
3258 exit(1);
3259 }
3260 value+= length2;
3261
3262 swap_buff2= (uchar *) my_malloc(length2, MYF(0));
3263 if (!swap_buff2)
3264 {
3265 fprintf(stderr, "\nError: Out of memory. "
3266 "Could not exchange to flashback event.\n");
3267 exit(1);
3268 }
3269 memcpy(swap_buff2, start_pos + length1, length2); // WHERE part
3270 }
3271
3272 if (ev_type == UPDATE_ROWS_EVENT ||
3273 ev_type == UPDATE_ROWS_EVENT_V1)
3274 {
3275 /* Swap SET and WHERE part */
3276 memcpy(start_pos, swap_buff2, length2);
3277 memcpy(start_pos + length2, swap_buff1, length1);
3278 }
3279
3280 /* Free tmp buffers */
3281 my_free(swap_buff1);
3282 if (ev_type == UPDATE_ROWS_EVENT ||
3283 ev_type == UPDATE_ROWS_EVENT_V1)
3284 my_free(swap_buff2);
3285
3286 /* Copying one row into a buff, and pushing into the array */
3287 LEX_STRING one_row;
3288
3289 one_row.length= length1 + length2;
3290 one_row.str= (char *) my_malloc(one_row.length, MYF(0));
3291 memcpy(one_row.str, start_pos, one_row.length);
3292 if (one_row.str == NULL || push_dynamic(&rows_arr, (uchar *) &one_row))
3293 {
3294 fprintf(stderr, "\nError: Out of memory. "
3295 "Could not push flashback event into array.\n");
3296 exit(1);
3297 }
3298 }
3299
3300 /* Copying rows from the end to the begining into event */
3301 for (uint i= rows_arr.elements; i > 0; --i)
3302 {
3303 LEX_STRING *one_row= dynamic_element(&rows_arr, i - 1, LEX_STRING*);
3304
3305 memcpy(rows_pos, (uchar *)one_row->str, one_row->length);
3306 rows_pos+= one_row->length;
3307 my_free(one_row->str);
3308 }
3309 delete_dynamic(&rows_arr);
3310
3311end:
3312 delete td;
3313}
3314
3315/**
3316 Calc length of a packed value of the given SQL type
3317
3318 @param[in] ptr Pointer to string
3319 @param[in] type Column type
3320 @param[in] meta Column meta information
3321
3322 @retval - number of bytes scanned from ptr.
3323 Except in case of NULL, in which case we return 1 to indicate ok
3324*/
3325
3326static size_t calc_field_event_length(const uchar *ptr, uint type, uint meta)
3327{
3328 uint32 length= 0;
3329
3330 if (type == MYSQL_TYPE_STRING)
3331 {
3332 if (meta >= 256)
3333 {
3334 uint byte0= meta >> 8;
3335 uint byte1= meta & 0xFF;
3336
3337 if ((byte0 & 0x30) != 0x30)
3338 {
3339 /* a long CHAR() field: see #37426 */
3340 length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
3341 type= byte0 | 0x30;
3342 }
3343 else
3344 length = meta & 0xFF;
3345 }
3346 else
3347 length= meta;
3348 }
3349
3350 switch (type) {
3351 case MYSQL_TYPE_LONG:
3352 case MYSQL_TYPE_TIMESTAMP:
3353 return 4;
3354 case MYSQL_TYPE_TINY:
3355 case MYSQL_TYPE_YEAR:
3356 return 1;
3357 case MYSQL_TYPE_SHORT:
3358 return 2;
3359 case MYSQL_TYPE_INT24:
3360 case MYSQL_TYPE_TIME:
3361 case MYSQL_TYPE_NEWDATE:
3362 case MYSQL_TYPE_DATE:
3363 return 3;
3364 case MYSQL_TYPE_LONGLONG:
3365 case MYSQL_TYPE_DATETIME:
3366 return 8;
3367 case MYSQL_TYPE_NEWDECIMAL:
3368 {
3369 uint precision= meta >> 8;
3370 uint decimals= meta & 0xFF;
3371 uint bin_size= my_decimal_get_binary_size(precision, decimals);
3372 return bin_size;
3373 }
3374 case MYSQL_TYPE_FLOAT:
3375 return 4;
3376 case MYSQL_TYPE_DOUBLE:
3377 return 8;
3378 case MYSQL_TYPE_BIT:
3379 {
3380 /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
3381 uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
3382 length= (nbits + 7) / 8;
3383 return length;
3384 }
3385 case MYSQL_TYPE_TIMESTAMP2:
3386 return my_timestamp_binary_length(meta);
3387 case MYSQL_TYPE_DATETIME2:
3388 return my_datetime_binary_length(meta);
3389 case MYSQL_TYPE_TIME2:
3390 return my_time_binary_length(meta);
3391 case MYSQL_TYPE_ENUM:
3392 switch (meta & 0xFF) {
3393 case 1:
3394 case 2:
3395 return (meta & 0xFF);
3396 default:
3397 /* Unknown ENUM packlen=%d", meta & 0xFF */
3398 return 0;
3399 }
3400 break;
3401 case MYSQL_TYPE_SET:
3402 return meta & 0xFF;
3403 case MYSQL_TYPE_BLOB:
3404 return (meta <= 4 ? meta : 0);
3405 case MYSQL_TYPE_VARCHAR:
3406 case MYSQL_TYPE_VAR_STRING:
3407 length= meta;
3408 /* fall through */
3409 case MYSQL_TYPE_STRING:
3410 if (length < 256)
3411 return (uint) *ptr + 1;
3412 return uint2korr(ptr) + 2;
3413 case MYSQL_TYPE_DECIMAL:
3414 break;
3415 default:
3416 break;
3417 }
3418 return 0;
3419}
3420
3421
3422size_t
3423Rows_log_event::calc_row_event_length(table_def *td,
3424 PRINT_EVENT_INFO *print_event_info,
3425 MY_BITMAP *cols_bitmap,
3426 const uchar *value)
3427{
3428 const uchar *value0= value;
3429 const uchar *null_bits= value;
3430 uint null_bit_index= 0;
3431
3432 /*
3433 Skip metadata bytes which gives the information about nullabity of master
3434 columns. Master writes one bit for each affected column.
3435 */
3436
3437 value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
3438
3439 for (uint i= 0; i < (uint)td->size(); i ++)
3440 {
3441 int is_null;
3442 is_null= (null_bits[null_bit_index / 8] >> (null_bit_index % 8)) & 0x01;
3443
3444 if (bitmap_is_set(cols_bitmap, i) == 0)
3445 continue;
3446
3447 if (!is_null)
3448 {
3449 size_t size;
3450 size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
3451 if (value + fsize > m_rows_end)
3452 {
3453 /* Corrupted replication event was detected, skipping entry */
3454 return 0;
3455 }
3456 if (!(size= calc_field_event_length(value, td->type(i),
3457 td->field_metadata(i))))
3458 return 0;
3459 value+= size;
3460 }
3461 null_bit_index++;
3462 }
3463 return value - value0;
3464}
3465
3466
3467/**
3468 Calculate how many rows there are in the event
3469
3470 @param[in] file IO cache
3471 @param[in] print_event_into Print parameters
3472*/
3473
3474void Rows_log_event::count_row_events(PRINT_EVENT_INFO *print_event_info)
3475{
3476 Table_map_log_event *map;
3477 table_def *td;
3478 uint row_events;
3479 Log_event_type general_type_code= get_general_type_code();
3480
3481 switch (general_type_code) {
3482 case WRITE_ROWS_EVENT:
3483 case DELETE_ROWS_EVENT:
3484 row_events= 1;
3485 break;
3486 case UPDATE_ROWS_EVENT:
3487 row_events= 2;
3488 break;
3489 default:
3490 DBUG_ASSERT(0); /* Not possible */
3491 return;
3492 }
3493
3494 if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
3495 !(td= map->create_table_def()))
3496 {
3497 /* Row event for unknown table */
3498 return;
3499 }
3500
3501 for (const uchar *value= m_rows_buf; value < m_rows_end; )
3502 {
3503 size_t length;
3504 print_event_info->row_events++;
3505
3506 /* Print the first image */
3507 if (!(length= calc_row_event_length(td, print_event_info,
3508 &m_cols, value)))
3509 break;
3510 value+= length;
3511 DBUG_ASSERT(value <= m_rows_end);
3512
3513 /* Print the second image (for UPDATE only) */
3514 if (row_events == 2)
3515 {
3516 if (!(length= calc_row_event_length(td, print_event_info,
3517 &m_cols_ai, value)))
3518 break;
3519 value+= length;
3520 DBUG_ASSERT(value <= m_rows_end);
3521 }
3522 }
3523 delete td;
3524}
3525
3526
3527/**
3528 Print a row event into IO cache in human readable form (in SQL format)
3529
3530 @param[in] file IO cache
3531 @param[in] print_event_into Print parameters
3532*/
3533
3534bool Rows_log_event::print_verbose(IO_CACHE *file,
3535 PRINT_EVENT_INFO *print_event_info)
3536{
3537 Table_map_log_event *map;
3538 table_def *td= 0;
3539 const char *sql_command, *sql_clause1, *sql_clause2;
3540 const char *sql_command_short __attribute__((unused));
3541 Log_event_type general_type_code= get_general_type_code();
3542#ifdef WHEN_FLASHBACK_REVIEW_READY
3543 IO_CACHE *review_sql= &print_event_info->review_sql_cache;
3544#endif
3545
3546 if (m_extra_row_data)
3547 {
3548 uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
3549 uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
3550 assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
3551
3552 if (my_b_printf(file, "### Extra row data format: %u, len: %u :",
3553 m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
3554 extra_payload_len))
3555 goto err;
3556 if (extra_payload_len)
3557 {
3558 /*
3559 Buffer for hex view of string, including '0x' prefix,
3560 2 hex chars / byte and trailing 0
3561 */
3562 const int buff_len= 2 + (256 * 2) + 1;
3563 char buff[buff_len];
3564 str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
3565 extra_payload_len);
3566 if (my_b_printf(file, "%s", buff))
3567 goto err;
3568 }
3569 if (my_b_printf(file, "\n"))
3570 goto err;
3571 }
3572
3573 switch (general_type_code) {
3574 case WRITE_ROWS_EVENT:
3575 sql_command= "INSERT INTO";
3576 sql_clause1= "### SET\n";
3577 sql_clause2= NULL;
3578 sql_command_short= "I";
3579 break;
3580 case DELETE_ROWS_EVENT:
3581 sql_command= "DELETE FROM";
3582 sql_clause1= "### WHERE\n";
3583 sql_clause2= NULL;
3584 sql_command_short= "D";
3585 break;
3586 case UPDATE_ROWS_EVENT:
3587 sql_command= "UPDATE";
3588 sql_clause1= "### WHERE\n";
3589 sql_clause2= "### SET\n";
3590 sql_command_short= "U";
3591 break;
3592 default:
3593 sql_command= sql_clause1= sql_clause2= NULL;
3594 sql_command_short= "";
3595 DBUG_ASSERT(0); /* Not possible */
3596 }
3597
3598 if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
3599 !(td= map->create_table_def()))
3600 {
3601 return (my_b_printf(file, "### Row event for unknown table #%lu",
3602 (ulong) m_table_id));
3603 }
3604
3605 /* If the write rows event contained no values for the AI */
3606 if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
3607 {
3608 if (my_b_printf(file, "### INSERT INTO %`s.%`s VALUES ()\n",
3609 map->get_db_name(), map->get_table_name()))
3610 goto err;
3611 goto end;
3612 }
3613
3614 for (const uchar *value= m_rows_buf; value < m_rows_end; )
3615 {
3616 size_t length;
3617 print_event_info->row_events++;
3618
3619 if (my_b_printf(file, "### %s %`s.%`s\n",
3620 sql_command,
3621 map->get_db_name(), map->get_table_name()))
3622 goto err;
3623#ifdef WHEN_FLASHBACK_REVIEW_READY
3624 if (need_flashback_review)
3625 if (my_b_printf(review_sql, "\nINSERT INTO `%s`.`%s` VALUES ('%s'",
3626 map->get_review_dbname(), map->get_review_tablename(),
3627 sql_command_short))
3628 goto err;
3629#endif
3630
3631 /* Print the first image */
3632 if (!(length= print_verbose_one_row(file, td, print_event_info,
3633 &m_cols, value,
3634 (const uchar*) sql_clause1)))
3635 goto err;
3636 value+= length;
3637
3638 /* Print the second image (for UPDATE only) */
3639 if (sql_clause2)
3640 {
3641 if (!(length= print_verbose_one_row(file, td, print_event_info,
3642 &m_cols_ai, value,
3643 (const uchar*) sql_clause2)))
3644 goto err;
3645 value+= length;
3646 }
3647#ifdef WHEN_FLASHBACK_REVIEW_READY
3648 else
3649 {
3650 if (need_flashback_review)
3651 for (size_t i= 0; i < td->size(); i ++)
3652 if (my_b_printf(review_sql, ", NULL"))
3653 goto err;
3654 }
3655
3656 if (need_flashback_review)
3657 if (my_b_printf(review_sql, ")%s\n", print_event_info->delimiter))
3658 goto err;
3659#endif
3660 }
3661
3662end:
3663 delete td;
3664 return 0;
3665err:
3666 delete td;
3667 return 1;
3668}
3669
3670void free_table_map_log_event(Table_map_log_event *event)
3671{
3672 delete event;
3673}
3674
3675bool Log_event::print_base64(IO_CACHE* file,
3676 PRINT_EVENT_INFO* print_event_info,
3677 bool more)
3678{
3679 uchar *ptr= (uchar *)temp_buf;
3680 uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
3681 DBUG_ENTER("Log_event::print_base64");
3682
3683 if (is_flashback)
3684 {
3685 uint tmp_size= size;
3686 Rows_log_event *ev= NULL;
3687 Log_event_type ev_type = (enum Log_event_type) ptr[EVENT_TYPE_OFFSET];
3688 if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
3689 checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
3690 tmp_size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
3691 switch (ev_type) {
3692 case WRITE_ROWS_EVENT:
3693 ptr[EVENT_TYPE_OFFSET]= DELETE_ROWS_EVENT;
3694 ev= new Delete_rows_log_event((const char*) ptr, tmp_size,
3695 glob_description_event);
3696 ev->change_to_flashback_event(print_event_info, ptr, ev_type);
3697 break;
3698 case WRITE_ROWS_EVENT_V1:
3699 ptr[EVENT_TYPE_OFFSET]= DELETE_ROWS_EVENT_V1;
3700 ev= new Delete_rows_log_event((const char*) ptr, tmp_size,
3701 glob_description_event);
3702 ev->change_to_flashback_event(print_event_info, ptr, ev_type);
3703 break;
3704 case DELETE_ROWS_EVENT:
3705 ptr[EVENT_TYPE_OFFSET]= WRITE_ROWS_EVENT;
3706 ev= new Write_rows_log_event((const char*) ptr, tmp_size,
3707 glob_description_event);
3708 ev->change_to_flashback_event(print_event_info, ptr, ev_type);
3709 break;
3710 case DELETE_ROWS_EVENT_V1:
3711 ptr[EVENT_TYPE_OFFSET]= WRITE_ROWS_EVENT_V1;
3712 ev= new Write_rows_log_event((const char*) ptr, tmp_size,
3713 glob_description_event);
3714 ev->change_to_flashback_event(print_event_info, ptr, ev_type);
3715 break;
3716 case UPDATE_ROWS_EVENT:
3717 case UPDATE_ROWS_EVENT_V1:
3718 ev= new Update_rows_log_event((const char*) ptr, tmp_size,
3719 glob_description_event);
3720 ev->change_to_flashback_event(print_event_info, ptr, ev_type);
3721 break;
3722 default:
3723 break;
3724 }
3725 delete ev;
3726 }
3727
3728 if (print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
3729 print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS &&
3730 ! print_event_info->short_form)
3731 {
3732 size_t const tmp_str_sz= my_base64_needed_encoded_length((int) size);
3733 bool error= 0;
3734 char *tmp_str;
3735 if (!(tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME))))
3736 goto err;
3737
3738 if (my_base64_encode(ptr, (size_t) size, tmp_str))
3739 {
3740 DBUG_ASSERT(0);
3741 }
3742
3743 if (my_b_tell(file) == 0)
3744 if (unlikely(my_b_write_string(file, "\nBINLOG '\n")))
3745 error= 1;
3746 if (likely(!error) && unlikely(my_b_printf(file, "%s\n", tmp_str)))
3747 error= 1;
3748 if (!more && likely(!error))
3749 if (unlikely(my_b_printf(file, "'%s\n", print_event_info->delimiter)))
3750 error= 1;
3751 my_free(tmp_str);
3752 if (unlikely(error))
3753 goto err;
3754 }
3755
3756#ifdef WHEN_FLASHBACK_REVIEW_READY
3757 if (print_event_info->verbose || print_event_info->print_row_count ||
3758 need_flashback_review)
3759#else
3760 // Flashback need the table_map to parse the event
3761 if (print_event_info->verbose || print_event_info->print_row_count ||
3762 is_flashback)
3763#endif
3764 {
3765 Rows_log_event *ev= NULL;
3766 Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
3767
3768 if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
3769 checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
3770 size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
3771
3772 switch (et)
3773 {
3774 case TABLE_MAP_EVENT:
3775 {
3776 Table_map_log_event *map;
3777 map= new Table_map_log_event((const char*) ptr, size,
3778 glob_description_event);
3779#ifdef WHEN_FLASHBACK_REVIEW_READY
3780 if (need_flashback_review)
3781 {
3782 map->set_review_dbname(m_review_dbname.ptr());
3783 map->set_review_tablename(m_review_tablename.ptr());
3784 }
3785#endif
3786 print_event_info->m_table_map.set_table(map->get_table_id(), map);
3787 break;
3788 }
3789 case WRITE_ROWS_EVENT:
3790 case WRITE_ROWS_EVENT_V1:
3791 {
3792 ev= new Write_rows_log_event((const char*) ptr, size,
3793 glob_description_event);
3794 break;
3795 }
3796 case DELETE_ROWS_EVENT:
3797 case DELETE_ROWS_EVENT_V1:
3798 {
3799 ev= new Delete_rows_log_event((const char*) ptr, size,
3800 glob_description_event);
3801 break;
3802 }
3803 case UPDATE_ROWS_EVENT:
3804 case UPDATE_ROWS_EVENT_V1:
3805 {
3806 ev= new Update_rows_log_event((const char*) ptr, size,
3807 glob_description_event);
3808 break;
3809 }
3810 case WRITE_ROWS_COMPRESSED_EVENT:
3811 case WRITE_ROWS_COMPRESSED_EVENT_V1:
3812 {
3813 ev= new Write_rows_compressed_log_event((const char*) ptr, size,
3814 glob_description_event);
3815 break;
3816 }
3817 case UPDATE_ROWS_COMPRESSED_EVENT:
3818 case UPDATE_ROWS_COMPRESSED_EVENT_V1:
3819 {
3820 ev= new Update_rows_compressed_log_event((const char*) ptr, size,
3821 glob_description_event);
3822 break;
3823 }
3824 case DELETE_ROWS_COMPRESSED_EVENT:
3825 case DELETE_ROWS_COMPRESSED_EVENT_V1:
3826 {
3827 ev= new Delete_rows_compressed_log_event((const char*) ptr, size,
3828 glob_description_event);
3829 break;
3830 }
3831 default:
3832 break;
3833 }
3834
3835 if (ev)
3836 {
3837 bool error= 0;
3838
3839#ifdef WHEN_FLASHBACK_REVIEW_READY
3840 ev->need_flashback_review= need_flashback_review;
3841 if (print_event_info->verbose)
3842 {
3843 if (ev->print_verbose(file, print_event_info))
3844 goto err;
3845 }
3846 else
3847 {
3848 IO_CACHE tmp_cache;
3849
3850 if (open_cached_file(&tmp_cache, NULL, NULL, 0,
3851 MYF(MY_WME | MY_NABP)))
3852 {
3853 delete ev;
3854 goto err;
3855 }
3856
3857 error= ev->print_verbose(&tmp_cache, print_event_info);
3858 close_cached_file(&tmp_cache);
3859 if (unlikely(error))
3860 {
3861 delete ev;
3862 goto err;
3863 }
3864 }
3865#else
3866 if (print_event_info->verbose)
3867 error= ev->print_verbose(file, print_event_info);
3868 else
3869 ev->count_row_events(print_event_info);
3870#endif
3871 delete ev;
3872 if (unlikely(error))
3873 goto err;
3874 }
3875 }
3876 DBUG_RETURN(0);
3877
3878err:
3879 DBUG_RETURN(1);
3880}
3881
3882
3883/*
3884 Log_event::print_timestamp()
3885*/
3886
3887bool Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
3888{
3889 struct tm *res;
3890 time_t my_when= when;
3891 DBUG_ENTER("Log_event::print_timestamp");
3892 if (!ts)
3893 ts = &my_when;
3894 res=localtime(ts);
3895
3896 DBUG_RETURN(my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
3897 res->tm_year % 100,
3898 res->tm_mon+1,
3899 res->tm_mday,
3900 res->tm_hour,
3901 res->tm_min,
3902 res->tm_sec));
3903}
3904
3905#endif /* MYSQL_CLIENT */
3906
3907
3908#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
3909inline Log_event::enum_skip_reason
3910Log_event::continue_group(rpl_group_info *rgi)
3911{
3912 if (rgi->rli->slave_skip_counter == 1)
3913 return Log_event::EVENT_SKIP_IGNORE;
3914 return Log_event::do_shall_skip(rgi);
3915}
3916#endif
3917
3918/**************************************************************************
3919 Query_log_event methods
3920**************************************************************************/
3921
3922#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3923
3924/**
3925 This (which is used only for SHOW BINLOG EVENTS) could be updated to
3926 print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
3927 only an information, it does not produce suitable queries to replay (for
3928 example it does not print LOAD DATA INFILE).
3929 @todo
3930 show the catalog ??
3931*/
3932
3933void Query_log_event::pack_info(Protocol *protocol)
3934{
3935 // TODO: show the catalog ??
3936 char buf_mem[1024];
3937 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
3938 buf.real_alloc(9 + db_len + q_len);
3939 if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
3940 && db && db_len)
3941 {
3942 buf.append(STRING_WITH_LEN("use "));
3943 append_identifier(protocol->thd, &buf, db, db_len);
3944 buf.append(STRING_WITH_LEN("; "));
3945 }
3946 if (query && q_len)
3947 buf.append(query, q_len);
3948 protocol->store(&buf);
3949}
3950#endif
3951
3952#ifndef MYSQL_CLIENT
3953
3954/**
3955 Utility function for the next method (Query_log_event::write()) .
3956*/
3957static void store_str_with_code_and_len(uchar **dst, const char *src,
3958 uint len, uint code)
3959{
3960 /*
3961 only 1 byte to store the length of catalog, so it should not
3962 surpass 255
3963 */
3964 DBUG_ASSERT(len <= 255);
3965 DBUG_ASSERT(src);
3966 *((*dst)++)= (uchar) code;
3967 *((*dst)++)= (uchar) len;
3968 bmove(*dst, src, len);
3969 (*dst)+= len;
3970}
3971
3972
3973/**
3974 Query_log_event::write().
3975
3976 @note
3977 In this event we have to modify the header to have the correct
3978 EVENT_LEN_OFFSET as we don't yet know how many status variables we
3979 will print!
3980*/
3981
3982bool Query_log_event::write()
3983{
3984 uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3985 uchar *start, *start_of_status;
3986 ulong event_length;
3987
3988 if (!query)
3989 return 1; // Something wrong with event
3990
3991 /*
3992 We want to store the thread id:
3993 (- as an information for the user when he reads the binlog)
3994 - if the query uses temporary table: for the slave SQL thread to know to
3995 which master connection the temp table belongs.
3996 Now imagine we (write()) are called by the slave SQL thread (we are
3997 logging a query executed by this thread; the slave runs with
3998 --log-slave-updates). Then this query will be logged with
3999 thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
4000 the same name were created simultaneously on the master (in the master
4001 binlog you have
4002 CREATE TEMPORARY TABLE t; (thread 1)
4003 CREATE TEMPORARY TABLE t; (thread 2)
4004 ...)
4005 then in the slave's binlog there will be
4006 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
4007 CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
4008 which is bad (same thread id!).
4009
4010 To avoid this, we log the thread's thread id EXCEPT for the SQL
4011 slave thread for which we log the original (master's) thread id.
4012 Now this moves the bug: what happens if the thread id on the
4013 master was 10 and when the slave replicates the query, a
4014 connection number 10 is opened by a normal client on the slave,
4015 and updates a temp table of the same name? We get a problem
4016 again. To avoid this, in the handling of temp tables (sql_base.cc)
4017 we use thread_id AND server_id. TODO when this is merged into
4018 4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
4019 and is a session variable: that's to make mysqlbinlog work with
4020 temp tables. We probably need to introduce
4021
4022 SET PSEUDO_SERVER_ID
4023 for mysqlbinlog in 4.1. mysqlbinlog would print:
4024 SET PSEUDO_SERVER_ID=
4025 SET PSEUDO_THREAD_ID=
4026 for each query using temp tables.
4027 */
4028 int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
4029 int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
4030 buf[Q_DB_LEN_OFFSET] = (char) db_len;
4031 int2store(buf + Q_ERR_CODE_OFFSET, error_code);
4032
4033 /*
4034 You MUST always write status vars in increasing order of code. This
4035 guarantees that a slightly older slave will be able to parse those he
4036 knows.
4037 */
4038 start_of_status= start= buf+QUERY_HEADER_LEN;
4039 if (flags2_inited)
4040 {
4041 *start++= Q_FLAGS2_CODE;
4042 int4store(start, flags2);
4043 start+= 4;
4044 }
4045 if (sql_mode_inited)
4046 {
4047 *start++= Q_SQL_MODE_CODE;
4048 int8store(start, (ulonglong)sql_mode);
4049 start+= 8;
4050 }
4051 if (catalog_len) // i.e. this var is inited (false for 4.0 events)
4052 {
4053 store_str_with_code_and_len(&start,
4054 catalog, catalog_len, Q_CATALOG_NZ_CODE);
4055 /*
4056 In 5.0.x where x<4 masters we used to store the end zero here. This was
4057 a waste of one byte so we don't do it in x>=4 masters. We change code to
4058 Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
4059 of this x>=4 master segfault (expecting a zero when there is
4060 none). Remaining compatibility problems are: the older slave will not
4061 find the catalog; but it is will not crash, and it's not an issue
4062 that it does not find the catalog as catalogs were not used in these
4063 older MySQL versions (we store it in binlog and read it from relay log
4064 but do nothing useful with it). What is an issue is that the older slave
4065 will stop processing the Q_* blocks (and jumps to the db/query) as soon
4066 as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
4067 Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
4068 various ways. Documented that you should not mix alpha/beta versions if
4069 they are not exactly the same version, with example of 5.0.3->5.0.2 and
4070 5.0.4->5.0.3. If replication is from older to new, the new will
4071 recognize Q_CATALOG_CODE and have no problem.
4072 */
4073 }
4074 if (auto_increment_increment != 1 || auto_increment_offset != 1)
4075 {
4076 *start++= Q_AUTO_INCREMENT;
4077 int2store(start, auto_increment_increment);
4078 int2store(start+2, auto_increment_offset);
4079 start+= 4;
4080 }
4081 if (charset_inited)
4082 {
4083 *start++= Q_CHARSET_CODE;
4084 memcpy(start, charset, 6);
4085 start+= 6;
4086 }
4087 if (time_zone_len)
4088 {
4089 /* In the TZ sys table, column Name is of length 64 so this should be ok */
4090 DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
4091 store_str_with_code_and_len(&start,
4092 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
4093 }
4094 if (lc_time_names_number)
4095 {
4096 DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
4097 *start++= Q_LC_TIME_NAMES_CODE;
4098 int2store(start, lc_time_names_number);
4099 start+= 2;
4100 }
4101 if (charset_database_number)
4102 {
4103 DBUG_ASSERT(charset_database_number <= 0xFFFF);
4104 *start++= Q_CHARSET_DATABASE_CODE;
4105 int2store(start, charset_database_number);
4106 start+= 2;
4107 }
4108 if (table_map_for_update)
4109 {
4110 *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
4111 int8store(start, table_map_for_update);
4112 start+= 8;
4113 }
4114 if (master_data_written != 0)
4115 {
4116 /*
4117 Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
4118 has binlog_version<4 and the slave has binlog_version=4. See comment
4119 for master_data_written in log_event.h for details.
4120 */
4121 *start++= Q_MASTER_DATA_WRITTEN_CODE;
4122 int4store(start, master_data_written);
4123 start+= 4;
4124 }
4125
4126 if (thd && thd->need_binlog_invoker())
4127 {
4128 LEX_CSTRING user;
4129 LEX_CSTRING host;
4130 memset(&user, 0, sizeof(user));
4131 memset(&host, 0, sizeof(host));
4132
4133 if (thd->slave_thread && thd->has_invoker())
4134 {
4135 /* user will be null, if master is older than this patch */
4136 user= thd->get_invoker_user();
4137 host= thd->get_invoker_host();
4138 }
4139 else
4140 {
4141 Security_context *ctx= thd->security_ctx;
4142
4143 if (thd->need_binlog_invoker() == THD::INVOKER_USER)
4144 {
4145 user.str= ctx->priv_user;
4146 host.str= ctx->priv_host;
4147 host.length= strlen(host.str);
4148 }
4149 else
4150 {
4151 user.str= ctx->priv_role;
4152 host= empty_clex_str;
4153 }
4154 user.length= strlen(user.str);
4155 }
4156
4157 if (user.length > 0)
4158 {
4159 *start++= Q_INVOKER;
4160
4161 /*
4162 Store user length and user. The max length of use is 16, so 1 byte is
4163 enough to store the user's length.
4164 */
4165 *start++= (uchar)user.length;
4166 memcpy(start, user.str, user.length);
4167 start+= user.length;
4168
4169 /*
4170 Store host length and host. The max length of host is 60, so 1 byte is
4171 enough to store the host's length.
4172 */
4173 *start++= (uchar)host.length;
4174 memcpy(start, host.str, host.length);
4175 start+= host.length;
4176 }
4177 }
4178
4179 if (thd && thd->query_start_sec_part_used)
4180 {
4181 *start++= Q_HRNOW;
4182 get_time();
4183 int3store(start, when_sec_part);
4184 start+= 3;
4185 }
4186 /*
4187 NOTE: When adding new status vars, please don't forget to update
4188 the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
4189 code_name() in this file.
4190
4191 Here there could be code like
4192 if (command-line-option-which-says-"log_this_variable" && inited)
4193 {
4194 *start++= Q_THIS_VARIABLE_CODE;
4195 int4store(start, this_variable);
4196 start+= 4;
4197 }
4198 */
4199
4200 /* Store length of status variables */
4201 status_vars_len= (uint) (start-start_of_status);
4202 DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
4203 int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
4204
4205 /*
4206 Calculate length of whole event
4207 The "1" below is the \0 in the db's length
4208 */
4209 event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
4210
4211 return write_header(event_length) ||
4212 write_data(buf, QUERY_HEADER_LEN) ||
4213 write_post_header_for_derived() ||
4214 write_data(start_of_status, (uint) (start-start_of_status)) ||
4215 write_data(safe_str(db), db_len + 1) ||
4216 write_data(query, q_len) ||
4217 write_footer();
4218}
4219
4220bool Query_compressed_log_event::write()
4221{
4222 const char *query_tmp = query;
4223 uint32 q_len_tmp = q_len;
4224 uint32 alloc_size;
4225 bool ret = true;
4226 q_len = alloc_size = binlog_get_compress_len(q_len);
4227 query = (char *)my_safe_alloca(alloc_size);
4228 if(query && !binlog_buf_compress(query_tmp, (char *)query, q_len_tmp, &q_len))
4229 {
4230 ret = Query_log_event::write();
4231 }
4232 my_safe_afree((void *)query, alloc_size);
4233 query = query_tmp;
4234 q_len = q_len_tmp;
4235 return ret;
4236}
4237
4238/**
4239 The simplest constructor that could possibly work. This is used for
4240 creating static objects that have a special meaning and are invisible
4241 to the log.
4242*/
4243Query_log_event::Query_log_event()
4244 :Log_event(), data_buf(0)
4245{
4246 memset(&user, 0, sizeof(user));
4247 memset(&host, 0, sizeof(host));
4248}
4249
4250
4251/*
4252 SYNOPSIS
4253 Query_log_event::Query_log_event()
4254 thd_arg - thread handle
4255 query_arg - array of char representing the query
4256 query_length - size of the `query_arg' array
4257 using_trans - there is a modified transactional table
4258 direct - Don't cache statement
4259 suppress_use - suppress the generation of 'USE' statements
4260 errcode - the error code of the query
4261
4262 DESCRIPTION
4263 Creates an event for binlogging
4264 The value for `errcode' should be supplied by caller.
4265*/
4266Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, size_t query_length, bool using_trans,
4267 bool direct, bool suppress_use, int errcode)
4268
4269 :Log_event(thd_arg,
4270 (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
4271 0) |
4272 (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
4273 using_trans),
4274 data_buf(0), query(query_arg), catalog(thd_arg->catalog),
4275 db(thd_arg->db.str), q_len((uint32) query_length),
4276 thread_id(thd_arg->thread_id),
4277 /* save the original thread id; we already know the server id */
4278 slave_proxy_id((ulong)thd_arg->variables.pseudo_thread_id),
4279 flags2_inited(1), sql_mode_inited(1), charset_inited(1),
4280 sql_mode(thd_arg->variables.sql_mode),
4281 auto_increment_increment(thd_arg->variables.auto_increment_increment),
4282 auto_increment_offset(thd_arg->variables.auto_increment_offset),
4283 lc_time_names_number(thd_arg->variables.lc_time_names->number),
4284 charset_database_number(0),
4285 table_map_for_update((ulonglong)thd_arg->table_map_for_update),
4286 master_data_written(0)
4287{
4288 time_t end_time;
4289
4290#ifdef WITH_WSREP
4291 /*
4292 If Query_log_event will contain non trans keyword (not BEGIN, COMMIT,
4293 SAVEPOINT or ROLLBACK) we disable PA for this transaction.
4294 */
4295 if (WSREP_ON && !is_trans_keyword())
4296 thd->wsrep_PA_safe= false;
4297#endif /* WITH_WSREP */
4298
4299 memset(&user, 0, sizeof(user));
4300 memset(&host, 0, sizeof(host));
4301
4302 error_code= errcode;
4303
4304 end_time= my_time(0);
4305 exec_time = (ulong) (end_time - thd_arg->start_time);
4306 /**
4307 @todo this means that if we have no catalog, then it is replicated
4308 as an existing catalog of length zero. is that safe? /sven
4309 */
4310 catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
4311 /* status_vars_len is set just before writing the event */
4312 db_len = (db) ? (uint32) strlen(db) : 0;
4313 if (thd_arg->variables.collation_database != thd_arg->db_charset)
4314 charset_database_number= thd_arg->variables.collation_database->number;
4315
4316 /*
4317 We only replicate over the bits of flags2 that we need: the rest
4318 are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
4319
4320 We also force AUTOCOMMIT=1. Rationale (cf. BUG#29288): After
4321 fixing BUG#26395, we always write BEGIN and COMMIT around all
4322 transactions (even single statements in autocommit mode). This is
4323 so that replication from non-transactional to transactional table
4324 and error recovery from XA to non-XA table should work as
4325 expected. The BEGIN/COMMIT are added in log.cc. However, there is
4326 one exception: MyISAM bypasses log.cc and writes directly to the
4327 binlog. So if autocommit is off, master has MyISAM, and slave has
4328 a transactional engine, then the slave will just see one long
4329 never-ending transaction. The only way to bypass explicit
4330 BEGIN/COMMIT in the binlog is by using a non-transactional table.
4331 So setting AUTOCOMMIT=1 will make this work as expected.
4332
4333 Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
4334 assume AUTOCOMMIT=1 on slave; the slave still reads the state of
4335 the autocommit flag as written by the master to the binlog. This
4336 behavior may change after WL#4162 has been implemented.
4337 */
4338 flags2= (uint32) (thd_arg->variables.option_bits &
4339 (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
4340 DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
4341 DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
4342 DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
4343 DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
4344 int2store(charset, thd_arg->variables.character_set_client->number);
4345 int2store(charset+2, thd_arg->variables.collation_connection->number);
4346 int2store(charset+4, thd_arg->variables.collation_server->number);
4347 if (thd_arg->time_zone_used)
4348 {
4349 /*
4350 Note that our event becomes dependent on the Time_zone object
4351 representing the time zone. Fortunately such objects are never deleted
4352 or changed during mysqld's lifetime.
4353 */
4354 time_zone_len= thd_arg->variables.time_zone->get_name()->length();
4355 time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
4356 }
4357 else
4358 time_zone_len= 0;
4359
4360 LEX *lex= thd->lex;
4361 /*
4362 Defines that the statement will be written directly to the binary log
4363 without being wrapped by a BEGIN...COMMIT. Otherwise, the statement
4364 will be written to either the trx-cache or stmt-cache.
4365
4366 Note that a cache will not be used if the parameter direct is TRUE.
4367 */
4368 bool use_cache= FALSE;
4369 /*
4370 TRUE defines that the trx-cache must be used and by consequence the
4371 use_cache is TRUE.
4372
4373 Note that a cache will not be used if the parameter direct is TRUE.
4374 */
4375 bool trx_cache= FALSE;
4376 cache_type= Log_event::EVENT_INVALID_CACHE;
4377
4378 switch (lex->sql_command)
4379 {
4380 case SQLCOM_DROP_TABLE:
4381 case SQLCOM_DROP_SEQUENCE:
4382 use_cache= (lex->tmp_table() && thd->in_multi_stmt_transaction_mode());
4383 break;
4384
4385 case SQLCOM_CREATE_TABLE:
4386 case SQLCOM_CREATE_SEQUENCE:
4387 /*
4388 If we are using CREATE ... SELECT or if we are a slave
4389 executing BEGIN...COMMIT (generated by CREATE...SELECT) we
4390 have to use the transactional cache to ensure we don't
4391 calculate any checksum for the CREATE part.
4392 */
4393 trx_cache= (lex->select_lex.item_list.elements &&
4394 thd->is_current_stmt_binlog_format_row()) ||
4395 (thd->variables.option_bits & OPTION_GTID_BEGIN);
4396 use_cache= (lex->tmp_table() &&
4397 thd->in_multi_stmt_transaction_mode()) || trx_cache;
4398 break;
4399 case SQLCOM_SET_OPTION:
4400 if (lex->autocommit)
4401 use_cache= trx_cache= FALSE;
4402 else
4403 use_cache= TRUE;
4404 break;
4405 case SQLCOM_RELEASE_SAVEPOINT:
4406 case SQLCOM_ROLLBACK_TO_SAVEPOINT:
4407 case SQLCOM_SAVEPOINT:
4408 use_cache= trx_cache= TRUE;
4409 break;
4410 default:
4411 use_cache= sqlcom_can_generate_row_events(thd);
4412 break;
4413 }
4414
4415 if (!use_cache || direct)
4416 {
4417 cache_type= Log_event::EVENT_NO_CACHE;
4418 }
4419 else if (using_trans || trx_cache || stmt_has_updated_trans_table(thd) ||
4420 thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
4421 thd->variables.binlog_direct_non_trans_update,
4422 trans_has_updated_trans_table(thd),
4423 thd->tx_isolation))
4424 cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
4425 else
4426 cache_type= Log_event::EVENT_STMT_CACHE;
4427 DBUG_ASSERT(cache_type != Log_event::EVENT_INVALID_CACHE);
4428 DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu cache_tye: %d",
4429 (ulong) flags2, sql_mode, cache_type));
4430}
4431
4432Query_compressed_log_event::Query_compressed_log_event(THD* thd_arg, const char* query_arg,
4433 ulong query_length, bool using_trans,
4434 bool direct, bool suppress_use, int errcode)
4435 :Query_log_event(thd_arg, query_arg, query_length, using_trans, direct,
4436 suppress_use, errcode),
4437 query_buf(0)
4438{
4439
4440}
4441#endif /* MYSQL_CLIENT */
4442
4443
4444/* 2 utility functions for the next method */
4445
4446/**
4447 Read a string with length from memory.
4448
4449 This function reads the string-with-length stored at
4450 <code>src</code> and extract the length into <code>*len</code> and
4451 a pointer to the start of the string into <code>*dst</code>. The
4452 string can then be copied using <code>memcpy()</code> with the
4453 number of bytes given in <code>*len</code>.
4454
4455 @param src Pointer to variable holding a pointer to the memory to
4456 read the string from.
4457 @param dst Pointer to variable holding a pointer where the actual
4458 string starts. Starting from this position, the string
4459 can be copied using @c memcpy().
4460 @param len Pointer to variable where the length will be stored.
4461 @param end One-past-the-end of the memory where the string is
4462 stored.
4463
4464 @return Zero if the entire string can be copied successfully,
4465 @c UINT_MAX if the length could not be read from memory
4466 (that is, if <code>*src >= end</code>), otherwise the
4467 number of bytes that are missing to read the full
4468 string, which happends <code>*dst + *len >= end</code>.
4469*/
4470static int
4471get_str_len_and_pointer(const Log_event::Byte **src,
4472 const char **dst,
4473 uint *len,
4474 const Log_event::Byte *end)
4475{
4476 if (*src >= end)
4477 return -1; // Will be UINT_MAX in two-complement arithmetics
4478 uint length= **src;
4479 if (length > 0)
4480 {
4481 if (*src + length >= end)
4482 return (int)(*src + length - end + 1); // Number of bytes missing
4483 *dst= (char *)*src + 1; // Will be copied later
4484 }
4485 *len= length;
4486 *src+= length + 1;
4487 return 0;
4488}
4489
4490static void copy_str_and_move(const char **src,
4491 Log_event::Byte **dst,
4492 size_t len)
4493{
4494 memcpy(*dst, *src, len);
4495 *src= (const char *)*dst;
4496 (*dst)+= len;
4497 *(*dst)++= 0;
4498}
4499
4500
4501#ifndef DBUG_OFF
4502static char const *
4503code_name(int code)
4504{
4505 static char buf[255];
4506 switch (code) {
4507 case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
4508 case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
4509 case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
4510 case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
4511 case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
4512 case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
4513 case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
4514 case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
4515 case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
4516 case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
4517 case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
4518 case Q_HRNOW: return "Q_HRNOW";
4519 }
4520 sprintf(buf, "CODE#%d", code);
4521 return buf;
4522}
4523#endif
4524
4525/**
4526 Macro to check that there is enough space to read from memory.
4527
4528 @param PTR Pointer to memory
4529 @param END End of memory
4530 @param CNT Number of bytes that should be read.
4531 */
4532#define CHECK_SPACE(PTR,END,CNT) \
4533 do { \
4534 DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
4535 DBUG_ASSERT((PTR) + (CNT) <= (END)); \
4536 if ((PTR) + (CNT) > (END)) { \
4537 DBUG_PRINT("info", ("query= 0")); \
4538 query= 0; \
4539 DBUG_VOID_RETURN; \
4540 } \
4541 } while (0)
4542
4543
4544/**
4545 This is used by the SQL slave thread to prepare the event before execution.
4546*/
4547Query_log_event::Query_log_event(const char* buf, uint event_len,
4548 const Format_description_log_event
4549 *description_event,
4550 Log_event_type event_type)
4551 :Log_event(buf, description_event), data_buf(0), query(NullS),
4552 db(NullS), catalog_len(0), status_vars_len(0),
4553 flags2_inited(0), sql_mode_inited(0), charset_inited(0),
4554 auto_increment_increment(1), auto_increment_offset(1),
4555 time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
4556 table_map_for_update(0), master_data_written(0)
4557{
4558 ulong data_len;
4559 uint32 tmp;
4560 uint8 common_header_len, post_header_len;
4561 Log_event::Byte *start;
4562 const Log_event::Byte *end;
4563 bool catalog_nz= 1;
4564 DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
4565
4566 memset(&user, 0, sizeof(user));
4567 memset(&host, 0, sizeof(host));
4568 common_header_len= description_event->common_header_len;
4569 post_header_len= description_event->post_header_len[event_type-1];
4570 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
4571 event_len, common_header_len, post_header_len));
4572
4573 /*
4574 We test if the event's length is sensible, and if so we compute data_len.
4575 We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
4576 We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
4577 */
4578 if (event_len < (uint)(common_header_len + post_header_len))
4579 DBUG_VOID_RETURN;
4580 data_len = event_len - (common_header_len + post_header_len);
4581 buf+= common_header_len;
4582
4583 thread_id = slave_proxy_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
4584 exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
4585 db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
4586 error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
4587
4588 /*
4589 5.0 format starts here.
4590 Depending on the format, we may or not have affected/warnings etc
4591 The remnent post-header to be parsed has length:
4592 */
4593 tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
4594 if (tmp)
4595 {
4596 status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
4597 /*
4598 Check if status variable length is corrupt and will lead to very
4599 wrong data. We could be even more strict and require data_len to
4600 be even bigger, but this will suffice to catch most corruption
4601 errors that can lead to a crash.
4602 */
4603 if (status_vars_len > MY_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
4604 {
4605 DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
4606 status_vars_len, data_len));
4607 query= 0;
4608 DBUG_VOID_RETURN;
4609 }
4610 data_len-= status_vars_len;
4611 DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
4612 (uint) status_vars_len));
4613 tmp-= 2;
4614 }
4615 else
4616 {
4617 /*
4618 server version < 5.0 / binlog_version < 4 master's event is
4619 relay-logged with storing the original size of the event in
4620 Q_MASTER_DATA_WRITTEN_CODE status variable.
4621 The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
4622 event from the relay log.
4623 */
4624 DBUG_ASSERT(description_event->binlog_version < 4);
4625 master_data_written= (uint32)data_written;
4626 }
4627 /*
4628 We have parsed everything we know in the post header for QUERY_EVENT,
4629 the rest of post header is either comes from older version MySQL or
4630 dedicated to derived events (e.g. Execute_load_query...)
4631 */
4632
4633 /* variable-part: the status vars; only in MySQL 5.0 */
4634
4635 start= (Log_event::Byte*) (buf+post_header_len);
4636 end= (const Log_event::Byte*) (start+status_vars_len);
4637 for (const Log_event::Byte* pos= start; pos < end;)
4638 {
4639 switch (*pos++) {
4640 case Q_FLAGS2_CODE:
4641 CHECK_SPACE(pos, end, 4);
4642 flags2_inited= 1;
4643 flags2= uint4korr(pos);
4644 DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
4645 pos+= 4;
4646 break;
4647 case Q_SQL_MODE_CODE:
4648 {
4649 CHECK_SPACE(pos, end, 8);
4650 sql_mode_inited= 1;
4651 sql_mode= (sql_mode_t) uint8korr(pos);
4652 DBUG_PRINT("info",("In Query_log_event, read sql_mode: %llu", sql_mode));
4653 pos+= 8;
4654 break;
4655 }
4656 case Q_CATALOG_NZ_CODE:
4657 DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos:%p; end:%p",
4658 pos, end));
4659 if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
4660 {
4661 DBUG_PRINT("info", ("query= 0"));
4662 query= 0;
4663 DBUG_VOID_RETURN;
4664 }
4665 break;
4666 case Q_AUTO_INCREMENT:
4667 CHECK_SPACE(pos, end, 4);
4668 auto_increment_increment= uint2korr(pos);
4669 auto_increment_offset= uint2korr(pos+2);
4670 pos+= 4;
4671 break;
4672 case Q_CHARSET_CODE:
4673 {
4674 CHECK_SPACE(pos, end, 6);
4675 charset_inited= 1;
4676 memcpy(charset, pos, 6);
4677 pos+= 6;
4678 break;
4679 }
4680 case Q_TIME_ZONE_CODE:
4681 {
4682 if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
4683 {
4684 DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
4685 query= 0;
4686 DBUG_VOID_RETURN;
4687 }
4688 break;
4689 }
4690 case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
4691 CHECK_SPACE(pos, end, 1);
4692 if ((catalog_len= *pos))
4693 catalog= (char*) pos+1; // Will be copied later
4694 CHECK_SPACE(pos, end, catalog_len + 2);
4695 pos+= catalog_len+2; // leap over end 0
4696 catalog_nz= 0; // catalog has end 0 in event
4697 break;
4698 case Q_LC_TIME_NAMES_CODE:
4699 CHECK_SPACE(pos, end, 2);
4700 lc_time_names_number= uint2korr(pos);
4701 pos+= 2;
4702 break;
4703 case Q_CHARSET_DATABASE_CODE:
4704 CHECK_SPACE(pos, end, 2);
4705 charset_database_number= uint2korr(pos);
4706 pos+= 2;
4707 break;
4708 case Q_TABLE_MAP_FOR_UPDATE_CODE:
4709 CHECK_SPACE(pos, end, 8);
4710 table_map_for_update= uint8korr(pos);
4711 pos+= 8;
4712 break;
4713 case Q_MASTER_DATA_WRITTEN_CODE:
4714 CHECK_SPACE(pos, end, 4);
4715 data_written= master_data_written= uint4korr(pos);
4716 pos+= 4;
4717 break;
4718 case Q_INVOKER:
4719 {
4720 CHECK_SPACE(pos, end, 1);
4721 user.length= *pos++;
4722 CHECK_SPACE(pos, end, user.length);
4723 user.str= (char *)pos;
4724 pos+= user.length;
4725
4726 CHECK_SPACE(pos, end, 1);
4727 host.length= *pos++;
4728 CHECK_SPACE(pos, end, host.length);
4729 host.str= (char *)pos;
4730 pos+= host.length;
4731 break;
4732 }
4733 case Q_HRNOW:
4734 {
4735 CHECK_SPACE(pos, end, 3);
4736 when_sec_part= uint3korr(pos);
4737 pos+= 3;
4738 break;
4739 }
4740 default:
4741 /* That's why you must write status vars in growing order of code */
4742 DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
4743 code: %u), skipping the rest of them", (uint) *(pos-1)));
4744 pos= (const uchar*) end; // Break loop
4745 }
4746 }
4747
4748 /**
4749 Layout for the data buffer is as follows
4750 +--------+-----------+------+------+---------+----+-------+
4751 | catlog | time_zone | user | host | db name | \0 | Query |
4752 +--------+-----------+------+------+---------+----+-------+
4753
4754 To support the query cache we append the following buffer to the above
4755 +-------+----------------------------------------+-------+
4756 |db len | uninitiatlized space of size of db len | FLAGS |
4757 +-------+----------------------------------------+-------+
4758
4759 The area of buffer starting from Query field all the way to the end belongs
4760 to the Query buffer and its structure is described in alloc_query() in
4761 sql_parse.cc
4762 */
4763
4764#if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4765 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4766 + time_zone_len + 1
4767 + user.length + 1
4768 + host.length + 1
4769 + data_len + 1
4770 + sizeof(size_t)//for db_len
4771 + db_len + 1
4772 + QUERY_CACHE_DB_LENGTH_SIZE
4773 + QUERY_CACHE_FLAGS_SIZE,
4774 MYF(MY_WME))))
4775#else
4776 if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4777 + time_zone_len + 1
4778 + user.length + 1
4779 + host.length + 1
4780 + data_len + 1,
4781 MYF(MY_WME))))
4782#endif
4783 DBUG_VOID_RETURN;
4784 if (catalog_len) // If catalog is given
4785 {
4786 /**
4787 @todo we should clean up and do only copy_str_and_move; it
4788 works for both cases. Then we can remove the catalog_nz
4789 flag. /sven
4790 */
4791 if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
4792 copy_str_and_move(&catalog, &start, catalog_len);
4793 else
4794 {
4795 memcpy(start, catalog, catalog_len+1); // copy end 0
4796 catalog= (const char *)start;
4797 start+= catalog_len+1;
4798 }
4799 }
4800 if (time_zone_len)
4801 copy_str_and_move(&time_zone_str, &start, time_zone_len);
4802
4803 if (user.length)
4804 {
4805 copy_str_and_move(&user.str, &start, user.length);
4806 }
4807 else
4808 {
4809 user.str= (char*) start;
4810 *(start++)= 0;
4811 }
4812
4813 if (host.length)
4814 copy_str_and_move(&host.str, &start, host.length);
4815 else
4816 {
4817 host.str= (char*) start;
4818 *(start++)= 0;
4819 }
4820
4821 /**
4822 if time_zone_len or catalog_len are 0, then time_zone and catalog
4823 are uninitialized at this point. shouldn't they point to the
4824 zero-length null-terminated strings we allocated space for in the
4825 my_alloc call above? /sven
4826 */
4827
4828 /* A 2nd variable part; this is common to all versions */
4829 memcpy((char*) start, end, data_len); // Copy db and query
4830 start[data_len]= '\0'; // End query with \0 (For safetly)
4831 db= (char *)start;
4832 query= (char *)(start + db_len + 1);
4833 q_len= data_len - db_len -1;
4834
4835 if (data_len && (data_len < db_len ||
4836 data_len < q_len ||
4837 data_len != (db_len + q_len + 1)))
4838 {
4839 q_len= 0;
4840 query= NULL;
4841 DBUG_VOID_RETURN;
4842 }
4843
4844 uint32 max_length= uint32(event_len - ((const char*)(end + db_len + 1) -
4845 (buf - common_header_len)));
4846 if (q_len != max_length)
4847 {
4848 q_len= 0;
4849 query= NULL;
4850 DBUG_VOID_RETURN;
4851 }
4852 /**
4853 Append the db length at the end of the buffer. This will be used by
4854 Query_cache::send_result_to_client() in case the query cache is On.
4855 */
4856#if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4857 size_t db_length= (size_t)db_len;
4858 memcpy(start + data_len + 1, &db_length, sizeof(size_t));
4859#endif
4860 DBUG_VOID_RETURN;
4861}
4862
4863Query_compressed_log_event::Query_compressed_log_event(const char *buf,
4864 uint event_len,
4865 const Format_description_log_event
4866 *description_event,
4867 Log_event_type event_type)
4868 :Query_log_event(buf, event_len, description_event, event_type),
4869 query_buf(NULL)
4870{
4871 if(query)
4872 {
4873 uint32 un_len=binlog_get_uncompress_len(query);
4874 if (!un_len)
4875 {
4876 query = 0;
4877 return;
4878 }
4879
4880 /* Reserve one byte for '\0' */
4881 query_buf = (Log_event::Byte*)my_malloc(ALIGN_SIZE(un_len + 1),
4882 MYF(MY_WME));
4883 if(query_buf &&
4884 !binlog_buf_uncompress(query, (char *)query_buf, q_len, &un_len))
4885 {
4886 query_buf[un_len] = 0;
4887 query = (const char *)query_buf;
4888 q_len = un_len;
4889 }
4890 else
4891 {
4892 query= 0;
4893 }
4894 }
4895}
4896
4897/*
4898 Replace a binlog event read into a packet with a dummy event. Either a
4899 Query_log_event that has just a comment, or if that will not fit in the
4900 space used for the event to be replaced, then a NULL user_var event.
4901
4902 This is used when sending binlog data to a slave which does not understand
4903 this particular event and which is too old to support informational events
4904 or holes in the event stream.
4905
4906 This allows to write such events into the binlog on the master and still be
4907 able to replicate against old slaves without them breaking.
4908
4909 Clears the flag LOG_EVENT_THREAD_SPECIFIC_F and set LOG_EVENT_SUPPRESS_USE_F.
4910 Overwrites the type with QUERY_EVENT (or USER_VAR_EVENT), and replaces the
4911 body with a minimal query / NULL user var.
4912
4913 Returns zero on success, -1 if error due to too little space in original
4914 event. A minimum of 25 bytes (19 bytes fixed header + 6 bytes in the body)
4915 is needed in any event to be replaced with a dummy event.
4916*/
4917int
4918Query_log_event::dummy_event(String *packet, ulong ev_offset,
4919 enum enum_binlog_checksum_alg checksum_alg)
4920{
4921 uchar *p= (uchar *)packet->ptr() + ev_offset;
4922 size_t data_len= packet->length() - ev_offset;
4923 uint16 flags;
4924 static const size_t min_user_var_event_len=
4925 LOG_EVENT_HEADER_LEN + UV_NAME_LEN_SIZE + 1 + UV_VAL_IS_NULL; // 25
4926 static const size_t min_query_event_len=
4927 LOG_EVENT_HEADER_LEN + QUERY_HEADER_LEN + 1 + 1; // 34
4928
4929 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
4930 data_len-= BINLOG_CHECKSUM_LEN;
4931 else
4932 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
4933 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
4934
4935 if (data_len < min_user_var_event_len)
4936 /* Cannot replace with dummy, event too short. */
4937 return -1;
4938
4939 flags= uint2korr(p + FLAGS_OFFSET);
4940 flags&= ~LOG_EVENT_THREAD_SPECIFIC_F;
4941 flags|= LOG_EVENT_SUPPRESS_USE_F;
4942 int2store(p + FLAGS_OFFSET, flags);
4943
4944 if (data_len < min_query_event_len)
4945 {
4946 /*
4947 Have to use dummy user_var event for such a short packet.
4948
4949 This works, but the event will be considered part of an event group with
4950 the following event. So for example @@global.sql_slave_skip_counter=1
4951 will skip not only the dummy event, but also the immediately following
4952 event.
4953
4954 We write a NULL user var with the name @`!dummyvar` (or as much
4955 as that as will fit within the size of the original event - so
4956 possibly just @`!`).
4957 */
4958 static const char var_name[]= "!dummyvar";
4959 size_t name_len= data_len - (min_user_var_event_len - 1);
4960
4961 p[EVENT_TYPE_OFFSET]= USER_VAR_EVENT;
4962 int4store(p + LOG_EVENT_HEADER_LEN, name_len);
4963 memcpy(p + LOG_EVENT_HEADER_LEN + UV_NAME_LEN_SIZE, var_name, name_len);
4964 p[LOG_EVENT_HEADER_LEN + UV_NAME_LEN_SIZE + name_len]= 1; // indicates NULL
4965 }
4966 else
4967 {
4968 /*
4969 Use a dummy query event, just a comment.
4970 */
4971 static const char message[]=
4972 "# Dummy event replacing event type %u that slave cannot handle.";
4973 char buf[sizeof(message)+1]; /* +1, as %u can expand to 3 digits. */
4974 uchar old_type= p[EVENT_TYPE_OFFSET];
4975 uchar *q= p + LOG_EVENT_HEADER_LEN;
4976 size_t comment_len, len;
4977
4978 p[EVENT_TYPE_OFFSET]= QUERY_EVENT;
4979 int4store(q + Q_THREAD_ID_OFFSET, 0);
4980 int4store(q + Q_EXEC_TIME_OFFSET, 0);
4981 q[Q_DB_LEN_OFFSET]= 0;
4982 int2store(q + Q_ERR_CODE_OFFSET, 0);
4983 int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
4984 q[Q_DATA_OFFSET]= 0; /* Zero terminator for empty db */
4985 q+= Q_DATA_OFFSET + 1;
4986 len= my_snprintf(buf, sizeof(buf), message, old_type);
4987 comment_len= data_len - (min_query_event_len - 1);
4988 if (comment_len <= len)
4989 memcpy(q, buf, comment_len);
4990 else
4991 {
4992 memcpy(q, buf, len);
4993 memset(q+len, ' ', comment_len - len);
4994 }
4995 }
4996
4997 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
4998 {
4999 ha_checksum crc= my_checksum(0, p, data_len);
5000 int4store(p + data_len, crc);
5001 }
5002 return 0;
5003}
5004
5005/*
5006 Replace an event (GTID event) with a BEGIN query event, to be compatible
5007 with an old slave.
5008*/
5009int
5010Query_log_event::begin_event(String *packet, ulong ev_offset,
5011 enum enum_binlog_checksum_alg checksum_alg)
5012{
5013 uchar *p= (uchar *)packet->ptr() + ev_offset;
5014 uchar *q= p + LOG_EVENT_HEADER_LEN;
5015 size_t data_len= packet->length() - ev_offset;
5016 uint16 flags;
5017
5018 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
5019 data_len-= BINLOG_CHECKSUM_LEN;
5020 else
5021 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
5022 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
5023
5024 /*
5025 Currently we only need to replace GTID event.
5026 The length of GTID differs depending on whether it contains commit id.
5027 */
5028 DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN ||
5029 data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
5030 if (data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN &&
5031 data_len != LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2)
5032 return 1;
5033
5034 flags= uint2korr(p + FLAGS_OFFSET);
5035 flags&= ~LOG_EVENT_THREAD_SPECIFIC_F;
5036 flags|= LOG_EVENT_SUPPRESS_USE_F;
5037 int2store(p + FLAGS_OFFSET, flags);
5038
5039 p[EVENT_TYPE_OFFSET]= QUERY_EVENT;
5040 int4store(q + Q_THREAD_ID_OFFSET, 0);
5041 int4store(q + Q_EXEC_TIME_OFFSET, 0);
5042 q[Q_DB_LEN_OFFSET]= 0;
5043 int2store(q + Q_ERR_CODE_OFFSET, 0);
5044 if (data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
5045 {
5046 int2store(q + Q_STATUS_VARS_LEN_OFFSET, 0);
5047 q[Q_DATA_OFFSET]= 0; /* Zero terminator for empty db */
5048 q+= Q_DATA_OFFSET + 1;
5049 }
5050 else
5051 {
5052 DBUG_ASSERT(data_len == LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN + 2);
5053 /* Put in an empty time_zone_str to take up the extra 2 bytes. */
5054 int2store(q + Q_STATUS_VARS_LEN_OFFSET, 2);
5055 q[Q_DATA_OFFSET]= Q_TIME_ZONE_CODE;
5056 q[Q_DATA_OFFSET+1]= 0; /* Zero length for empty time_zone_str */
5057 q[Q_DATA_OFFSET+2]= 0; /* Zero terminator for empty db */
5058 q+= Q_DATA_OFFSET + 3;
5059 }
5060 memcpy(q, "BEGIN", 5);
5061
5062 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
5063 {
5064 ha_checksum crc= my_checksum(0, p, data_len);
5065 int4store(p + data_len, crc);
5066 }
5067 return 0;
5068}
5069
5070
5071#ifdef MYSQL_CLIENT
5072/**
5073 Query_log_event::print().
5074
5075 @todo
5076 print the catalog ??
5077*/
5078bool Query_log_event::print_query_header(IO_CACHE* file,
5079 PRINT_EVENT_INFO* print_event_info)
5080{
5081 // TODO: print the catalog ??
5082 char buff[64], *end; // Enough for SET TIMESTAMP
5083 bool different_db= 1;
5084 uint32 tmp;
5085
5086 if (!print_event_info->short_form)
5087 {
5088 if (print_header(file, print_event_info, FALSE) ||
5089 my_b_printf(file,
5090 "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
5091 get_type_str(), (ulong) thread_id, (ulong) exec_time,
5092 error_code))
5093 goto err;
5094 }
5095
5096 if ((flags & LOG_EVENT_SUPPRESS_USE_F))
5097 {
5098 if (!is_trans_keyword())
5099 print_event_info->db[0]= '\0';
5100 }
5101 else if (db)
5102 {
5103 different_db= memcmp(print_event_info->db, db, db_len + 1);
5104 if (different_db)
5105 memcpy(print_event_info->db, db, db_len + 1);
5106 if (db[0] && different_db)
5107 if (my_b_printf(file, "use %`s%s\n", db, print_event_info->delimiter))
5108 goto err;
5109 }
5110
5111 end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
5112 if (when_sec_part && when_sec_part <= TIME_MAX_SECOND_PART)
5113 {
5114 *end++= '.';
5115 end=int10_to_str(when_sec_part, end, 10);
5116 }
5117 end= strmov(end, print_event_info->delimiter);
5118 *end++='\n';
5119 if (my_b_write(file, (uchar*) buff, (uint) (end-buff)))
5120 goto err;
5121 if ((!print_event_info->thread_id_printed ||
5122 ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
5123 thread_id != print_event_info->thread_id)))
5124 {
5125 // If --short-form, print deterministic value instead of pseudo_thread_id.
5126 if (my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
5127 short_form ? 999999999 : (ulong)thread_id,
5128 print_event_info->delimiter))
5129 goto err;
5130 print_event_info->thread_id= thread_id;
5131 print_event_info->thread_id_printed= 1;
5132 }
5133
5134 /*
5135 If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
5136 print (remember we don't produce mixed relay logs so there cannot be
5137 5.0 events before that one so there is nothing to reset).
5138 */
5139 if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
5140 {
5141 /* tmp is a bitmask of bits which have changed. */
5142 if (likely(print_event_info->flags2_inited))
5143 /* All bits which have changed */
5144 tmp= (print_event_info->flags2) ^ flags2;
5145 else /* that's the first Query event we read */
5146 {
5147 print_event_info->flags2_inited= 1;
5148 tmp= ~((uint32)0); /* all bits have changed */
5149 }
5150
5151 if (unlikely(tmp)) /* some bits have changed */
5152 {
5153 bool need_comma= 0;
5154 if (my_b_write_string(file, "SET ") ||
5155 print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
5156 "@@session.foreign_key_checks", &need_comma)||
5157 print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
5158 "@@session.sql_auto_is_null", &need_comma) ||
5159 print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
5160 "@@session.unique_checks", &need_comma) ||
5161 print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
5162 "@@session.autocommit", &need_comma) ||
5163 print_set_option(file, tmp, OPTION_NO_CHECK_CONSTRAINT_CHECKS,
5164 ~flags2,
5165 "@@session.check_constraint_checks", &need_comma) ||
5166 my_b_printf(file,"%s\n", print_event_info->delimiter))
5167 goto err;
5168 print_event_info->flags2= flags2;
5169 }
5170 }
5171
5172 /*
5173 Now the session variables;
5174 it's more efficient to pass SQL_MODE as a number instead of a
5175 comma-separated list.
5176 FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
5177 variables (they have no global version; they're not listed in
5178 sql_class.h), The tests below work for pure binlogs or pure relay
5179 logs. Won't work for mixed relay logs but we don't create mixed
5180 relay logs (that is, there is no relay log with a format change
5181 except within the 3 first events, which mysqlbinlog handles
5182 gracefully). So this code should always be good.
5183 */
5184
5185 if (likely(sql_mode_inited) &&
5186 (unlikely(print_event_info->sql_mode != sql_mode ||
5187 !print_event_info->sql_mode_inited)))
5188 {
5189 char llbuff[22];
5190 if (my_b_printf(file,"SET @@session.sql_mode=%s%s\n",
5191 ullstr(sql_mode, llbuff), print_event_info->delimiter))
5192 goto err;
5193 print_event_info->sql_mode= sql_mode;
5194 print_event_info->sql_mode_inited= 1;
5195 }
5196 if (print_event_info->auto_increment_increment != auto_increment_increment ||
5197 print_event_info->auto_increment_offset != auto_increment_offset)
5198 {
5199 if (my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
5200 auto_increment_increment,auto_increment_offset,
5201 print_event_info->delimiter))
5202 goto err;
5203 print_event_info->auto_increment_increment= auto_increment_increment;
5204 print_event_info->auto_increment_offset= auto_increment_offset;
5205 }
5206
5207 /* TODO: print the catalog when we feature SET CATALOG */
5208
5209 if (likely(charset_inited) &&
5210 (unlikely(!print_event_info->charset_inited ||
5211 memcmp(print_event_info->charset, charset, 6))))
5212 {
5213 CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
5214 if (cs_info)
5215 {
5216 /* for mysql client */
5217 if (my_b_printf(file, "/*!\\C %s */%s\n",
5218 cs_info->csname, print_event_info->delimiter))
5219 goto err;
5220 }
5221 if (my_b_printf(file,"SET "
5222 "@@session.character_set_client=%d,"
5223 "@@session.collation_connection=%d,"
5224 "@@session.collation_server=%d"
5225 "%s\n",
5226 uint2korr(charset),
5227 uint2korr(charset+2),
5228 uint2korr(charset+4),
5229 print_event_info->delimiter))
5230 goto err;
5231 memcpy(print_event_info->charset, charset, 6);
5232 print_event_info->charset_inited= 1;
5233 }
5234 if (time_zone_len)
5235 {
5236 if (memcmp(print_event_info->time_zone_str,
5237 time_zone_str, time_zone_len+1))
5238 {
5239 if (my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
5240 time_zone_str, print_event_info->delimiter))
5241 goto err;
5242 memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
5243 }
5244 }
5245 if (lc_time_names_number != print_event_info->lc_time_names_number)
5246 {
5247 if (my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
5248 lc_time_names_number, print_event_info->delimiter))
5249 goto err;
5250 print_event_info->lc_time_names_number= lc_time_names_number;
5251 }
5252 if (charset_database_number != print_event_info->charset_database_number)
5253 {
5254 if (charset_database_number)
5255 {
5256 if (my_b_printf(file, "SET @@session.collation_database=%d%s\n",
5257 charset_database_number, print_event_info->delimiter))
5258 goto err;
5259 }
5260 else if (my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
5261 print_event_info->delimiter))
5262 goto err;
5263 print_event_info->charset_database_number= charset_database_number;
5264 }
5265 return 0;
5266
5267err:
5268 return 1;
5269}
5270
5271
5272bool Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5273{
5274 Write_on_release_cache cache(&print_event_info->head_cache, file, 0, this);
5275
5276 /**
5277 reduce the size of io cache so that the write function is called
5278 for every call to my_b_write().
5279 */
5280 DBUG_EXECUTE_IF ("simulate_file_write_error",
5281 {(&cache)->write_pos= (&cache)->write_end- 500;});
5282 if (print_query_header(&cache, print_event_info))
5283 goto err;
5284 if (!is_flashback)
5285 {
5286 if (my_b_write(&cache, (uchar*) query, q_len) ||
5287 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
5288 goto err;
5289 }
5290 else // is_flashback == 1
5291 {
5292 if (strcmp("BEGIN", query) == 0)
5293 {
5294 if (my_b_write(&cache, (uchar*) "COMMIT", 6) ||
5295 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
5296 goto err;
5297 }
5298 else if (strcmp("COMMIT", query) == 0)
5299 {
5300 if (my_b_write(&cache, (uchar*) "BEGIN", 5) ||
5301 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
5302 goto err;
5303 }
5304 }
5305 return cache.flush_data();
5306err:
5307 return 1;
5308}
5309#endif /* MYSQL_CLIENT */
5310
5311
5312/*
5313 Query_log_event::do_apply_event()
5314*/
5315
5316#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5317
5318int Query_log_event::do_apply_event(rpl_group_info *rgi)
5319{
5320 return do_apply_event(rgi, query, q_len);
5321}
5322
5323/**
5324 Compare if two errors should be regarded as equal.
5325 This is to handle the case when you can get slightly different errors
5326 on master and slave for the same thing.
5327 @param
5328 expected_error Error we got on master
5329 actual_error Error we got on slave
5330
5331 @return
5332 1 Errors are equal
5333 0 Errors are different
5334*/
5335
5336bool test_if_equal_repl_errors(int expected_error, int actual_error)
5337{
5338 if (expected_error == actual_error)
5339 return 1;
5340 switch (expected_error) {
5341 case ER_DUP_ENTRY:
5342 case ER_DUP_ENTRY_WITH_KEY_NAME:
5343 case ER_DUP_KEY:
5344 case ER_AUTOINC_READ_FAILED:
5345 return (actual_error == ER_DUP_ENTRY ||
5346 actual_error == ER_DUP_ENTRY_WITH_KEY_NAME ||
5347 actual_error == ER_DUP_KEY ||
5348 actual_error == ER_AUTOINC_READ_FAILED ||
5349 actual_error == HA_ERR_AUTOINC_ERANGE);
5350 case ER_UNKNOWN_TABLE:
5351 return actual_error == ER_IT_IS_A_VIEW;
5352 default:
5353 break;
5354 }
5355 return 0;
5356}
5357
5358
5359/**
5360 @todo
5361 Compare the values of "affected rows" around here. Something
5362 like:
5363 @code
5364 if ((uint32) affected_in_event != (uint32) affected_on_slave)
5365 {
5366 sql_print_error("Slave: did not get the expected number of affected \
5367 rows running query from master - expected %d, got %d (this numbers \
5368 should have matched modulo 4294967296).", 0, ...);
5369 thd->query_error = 1;
5370 }
5371 @endcode
5372 We may also want an option to tell the slave to ignore "affected"
5373 mismatch. This mismatch could be implemented with a new ER_ code, and
5374 to ignore it you would use --slave-skip-errors...
5375*/
5376int Query_log_event::do_apply_event(rpl_group_info *rgi,
5377 const char *query_arg, uint32 q_len_arg)
5378{
5379 LEX_CSTRING new_db;
5380 int expected_error,actual_error= 0;
5381 Schema_specification_st db_options;
5382 uint64 sub_id= 0;
5383 void *hton= NULL;
5384 rpl_gtid gtid;
5385 Relay_log_info const *rli= rgi->rli;
5386 Rpl_filter *rpl_filter= rli->mi->rpl_filter;
5387 bool current_stmt_is_commit;
5388 DBUG_ENTER("Query_log_event::do_apply_event");
5389
5390 /*
5391 Colleagues: please never free(thd->catalog) in MySQL. This would
5392 lead to bugs as here thd->catalog is a part of an alloced block,
5393 not an entire alloced block (see
5394 Query_log_event::do_apply_event()). Same for thd->db. Thank
5395 you.
5396 */
5397 thd->catalog= catalog_len ? (char *) catalog : (char *)"";
5398
5399 size_t valid_len= Well_formed_prefix(system_charset_info,
5400 db, db_len, NAME_LEN).length();
5401
5402 if (valid_len != db_len)
5403 {
5404 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5405 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5406 "Invalid database name in Query event.");
5407 thd->is_slave_error= true;
5408 goto end;
5409 }
5410
5411 new_db.length= db_len;
5412 new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
5413 thd->set_db(&new_db); /* allocates a copy of 'db' */
5414
5415 /*
5416 Setting the character set and collation of the current database thd->db.
5417 */
5418 load_db_opt_by_name(thd, thd->db.str, &db_options);
5419 if (db_options.default_table_charset)
5420 thd->db_charset= db_options.default_table_charset;
5421 thd->variables.auto_increment_increment= auto_increment_increment;
5422 thd->variables.auto_increment_offset= auto_increment_offset;
5423
5424 DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
5425
5426 thd->clear_error(1);
5427 current_stmt_is_commit= is_commit();
5428
5429 DBUG_ASSERT(!current_stmt_is_commit || !rgi->tables_to_lock);
5430 rgi->slave_close_thread_tables(thd);
5431
5432 /*
5433 Note: We do not need to execute reset_one_shot_variables() if this
5434 db_ok() test fails.
5435 Reason: The db stored in binlog events is the same for SET and for
5436 its companion query. If the SET is ignored because of
5437 db_ok(), the companion query will also be ignored, and if
5438 the companion query is ignored in the db_ok() test of
5439 ::do_apply_event(), then the companion SET also have so
5440 we don't need to reset_one_shot_variables().
5441 */
5442 if (is_trans_keyword() || rpl_filter->db_ok(thd->db.str))
5443 {
5444 thd->set_time(when, when_sec_part);
5445 thd->set_query_and_id((char*)query_arg, q_len_arg,
5446 thd->charset(), next_query_id());
5447 thd->variables.pseudo_thread_id= thread_id; // for temp tables
5448 DBUG_PRINT("query",("%s", thd->query()));
5449
5450 if (unlikely(!(expected_error= error_code)) ||
5451 ignored_error_code(expected_error) ||
5452 !unexpected_error_code(expected_error))
5453 {
5454 thd->slave_expected_error= expected_error;
5455 if (flags2_inited)
5456 /*
5457 all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
5458 must take their value from flags2.
5459 */
5460 thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
5461 /*
5462 else, we are in a 3.23/4.0 binlog; we previously received a
5463 Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
5464 nothing to do.
5465 */
5466 /*
5467 We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
5468 slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
5469 force us to ignore the dir too. Imagine you are a ring of machines, and
5470 one has a disk problem so that you temporarily need
5471 MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
5472 elsewhere (you don't want all slaves to start ignoring the dirs).
5473 */
5474 if (sql_mode_inited)
5475 thd->variables.sql_mode=
5476 (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
5477 (sql_mode & ~(sql_mode_t) MODE_NO_DIR_IN_CREATE));
5478 if (charset_inited)
5479 {
5480 rpl_sql_thread_info *sql_info= thd->system_thread_info.rpl_sql_info;
5481 if (sql_info->cached_charset_compare(charset))
5482 {
5483 /* Verify that we support the charsets found in the event. */
5484 if (!(thd->variables.character_set_client=
5485 get_charset(uint2korr(charset), MYF(MY_WME))) ||
5486 !(thd->variables.collation_connection=
5487 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
5488 !(thd->variables.collation_server=
5489 get_charset(uint2korr(charset+4), MYF(MY_WME))))
5490 {
5491 /*
5492 We updated the thd->variables with nonsensical values (0). Let's
5493 set them to something safe (i.e. which avoids crash), and we'll
5494 stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
5495 ignore this error).
5496 */
5497 set_slave_thread_default_charset(thd, rgi);
5498 goto compare_errors;
5499 }
5500 thd->update_charset(); // for the charset change to take effect
5501 /*
5502 Reset thd->query_string.cs to the newly set value.
5503 Note, there is a small flaw here. For a very short time frame
5504 if the new charset is different from the old charset and
5505 if another thread executes "SHOW PROCESSLIST" after
5506 the above thd->set_query_and_id() and before this thd->set_query(),
5507 and if the current query has some non-ASCII characters,
5508 the another thread may see some '?' marks in the PROCESSLIST
5509 result. This should be acceptable now. This is a reminder
5510 to fix this if any refactoring happens here sometime.
5511 */
5512 thd->set_query((char*) query_arg, q_len_arg, thd->charset());
5513 }
5514 }
5515 if (time_zone_len)
5516 {
5517 String tmp(time_zone_str, time_zone_len, &my_charset_bin);
5518 if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
5519 {
5520 my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
5521 thd->variables.time_zone= global_system_variables.time_zone;
5522 goto compare_errors;
5523 }
5524 }
5525 if (lc_time_names_number)
5526 {
5527 if (!(thd->variables.lc_time_names=
5528 my_locale_by_number(lc_time_names_number)))
5529 {
5530 my_printf_error(ER_UNKNOWN_ERROR,
5531 "Unknown locale: '%d'", MYF(0), lc_time_names_number);
5532 thd->variables.lc_time_names= &my_locale_en_US;
5533 goto compare_errors;
5534 }
5535 }
5536 else
5537 thd->variables.lc_time_names= &my_locale_en_US;
5538 if (charset_database_number)
5539 {
5540 CHARSET_INFO *cs;
5541 if (!(cs= get_charset(charset_database_number, MYF(0))))
5542 {
5543 char buf[20];
5544 int10_to_str((int) charset_database_number, buf, -10);
5545 my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
5546 goto compare_errors;
5547 }
5548 thd->variables.collation_database= cs;
5549 }
5550 else
5551 thd->variables.collation_database= thd->db_charset;
5552
5553 {
5554 const CHARSET_INFO *cs= thd->charset();
5555 /*
5556 We cannot ask for parsing a statement using a character set
5557 without state_maps (parser internal data).
5558 */
5559 if (!cs->state_map)
5560 {
5561 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5562 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5563 "character_set cannot be parsed");
5564 thd->is_slave_error= true;
5565 goto end;
5566 }
5567 }
5568
5569 /*
5570 Record any GTID in the same transaction, so slave state is
5571 transactionally consistent.
5572 */
5573 if (current_stmt_is_commit)
5574 {
5575 thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
5576 if (rgi->gtid_pending)
5577 {
5578 sub_id= rgi->gtid_sub_id;
5579 rgi->gtid_pending= false;
5580
5581 gtid= rgi->current_gtid;
5582 if (unlikely(rpl_global_gtid_slave_state->record_gtid(thd, &gtid,
5583 sub_id,
5584 true, false,
5585 &hton)))
5586 {
5587 int errcode= thd->get_stmt_da()->sql_errno();
5588 if (!is_parallel_retry_error(rgi, errcode))
5589 rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE,
5590 rgi->gtid_info(),
5591 "Error during COMMIT: failed to update GTID state in "
5592 "%s.%s: %d: %s",
5593 "mysql", rpl_gtid_slave_state_table_name.str,
5594 errcode,
5595 thd->get_stmt_da()->message());
5596 sub_id= 0;
5597 thd->is_slave_error= 1;
5598 goto end;
5599 }
5600 }
5601 }
5602
5603 thd->table_map_for_update= (table_map)table_map_for_update;
5604 thd->set_invoker(&user, &host);
5605 /*
5606 Flag if we need to rollback the statement transaction on
5607 slave if it by chance succeeds.
5608 If we expected a non-zero error code and get nothing and,
5609 it is a concurrency issue or ignorable issue, effects
5610 of the statement should be rolled back.
5611 */
5612 if (unlikely(expected_error) &&
5613 (ignored_error_code(expected_error) ||
5614 concurrency_error_code(expected_error)))
5615 {
5616 thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
5617 thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
5618 }
5619 /* Execute the query (note that we bypass dispatch_command()) */
5620 Parser_state parser_state;
5621 if (!parser_state.init(thd, thd->query(), thd->query_length()))
5622 {
5623 DBUG_ASSERT(thd->m_digest == NULL);
5624 thd->m_digest= & thd->m_digest_state;
5625 DBUG_ASSERT(thd->m_statement_psi == NULL);
5626 thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
5627 stmt_info_rpl.m_key,
5628 thd->db.str, thd->db.length,
5629 thd->charset());
5630 THD_STAGE_INFO(thd, stage_init);
5631 MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), thd->query_length());
5632 if (thd->m_digest != NULL)
5633 thd->m_digest->reset(thd->m_token_array, max_digest_length);
5634
5635 if (thd->slave_thread)
5636 {
5637 /*
5638 To be compatible with previous releases, the slave thread uses the global
5639 log_slow_disabled_statements value, wich can be changed dynamically, so we
5640 have to set the sql_log_slow respectively.
5641 */
5642 thd->variables.sql_log_slow= !MY_TEST(global_system_variables.log_slow_disabled_statements & LOG_SLOW_DISABLE_SLAVE);
5643 }
5644
5645 mysql_parse(thd, thd->query(), thd->query_length(), &parser_state,
5646 FALSE, FALSE);
5647 /* Finalize server status flags after executing a statement. */
5648 thd->update_server_status();
5649 log_slow_statement(thd);
5650 thd->lex->restore_set_statement_var();
5651 }
5652
5653 thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
5654 }
5655 else
5656 {
5657 /*
5658 The query got a really bad error on the master (thread killed etc),
5659 which could be inconsistent. Parse it to test the table names: if the
5660 replicate-*-do|ignore-table rules say "this query must be ignored" then
5661 we exit gracefully; otherwise we warn about the bad error and tell DBA
5662 to check/fix it.
5663 */
5664 if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
5665 thd->clear_error(1);
5666 else
5667 {
5668 rli->report(ERROR_LEVEL, expected_error, rgi->gtid_info(),
5669 "\
5670Query partially completed on the master (error on master: %d) \
5671and was aborted. There is a chance that your master is inconsistent at this \
5672point. If you are sure that your master is ok, run this query manually on the \
5673slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
5674START SLAVE; . Query: '%s'", expected_error, thd->query());
5675 thd->is_slave_error= 1;
5676 }
5677 goto end;
5678 }
5679
5680 /* If the query was not ignored, it is printed to the general log */
5681 if (likely(!thd->is_error()) ||
5682 thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
5683 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
5684 else
5685 {
5686 /*
5687 Bug#54201: If we skip an INSERT query that uses auto_increment, then we
5688 should reset any @@INSERT_ID set by an Intvar_log_event associated with
5689 the query; otherwise the @@INSERT_ID will linger until the next INSERT
5690 that uses auto_increment and may affect extra triggers on the slave etc.
5691
5692 We reset INSERT_ID unconditionally; it is probably cheaper than
5693 checking if it is necessary.
5694 */
5695 thd->auto_inc_intervals_forced.empty();
5696 }
5697
5698compare_errors:
5699 /*
5700 In the slave thread, we may sometimes execute some DROP / * 40005
5701 TEMPORARY * / TABLE that come from parts of binlogs (likely if we
5702 use RESET SLAVE or CHANGE MASTER TO), while the temporary table
5703 has already been dropped. To ignore such irrelevant "table does
5704 not exist errors", we silently clear the error if TEMPORARY was used.
5705 */
5706 if ((thd->lex->sql_command == SQLCOM_DROP_TABLE ||
5707 thd->lex->sql_command == SQLCOM_DROP_SEQUENCE) &&
5708 thd->lex->tmp_table() &&
5709 thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
5710 !expected_error)
5711 thd->get_stmt_da()->reset_diagnostics_area();
5712 /*
5713 If we expected a non-zero error code, and we don't get the same error
5714 code, and it should be ignored or is related to a concurrency issue.
5715 */
5716 actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
5717 DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
5718 expected_error, actual_error));
5719
5720 if ((unlikely(expected_error) &&
5721 !test_if_equal_repl_errors(expected_error, actual_error) &&
5722 !concurrency_error_code(expected_error)) &&
5723 !ignored_error_code(actual_error) &&
5724 !ignored_error_code(expected_error))
5725 {
5726 rli->report(ERROR_LEVEL, 0, rgi->gtid_info(),
5727 "Query caused different errors on master and slave. "
5728 "Error on master: message (format)='%s' error code=%d ; "
5729 "Error on slave: actual message='%s', error code=%d. "
5730 "Default database: '%s'. Query: '%s'",
5731 ER_THD(thd, expected_error),
5732 expected_error,
5733 actual_error ? thd->get_stmt_da()->message() : "no error",
5734 actual_error,
5735 print_slave_db_safe(db), query_arg);
5736 thd->is_slave_error= 1;
5737 }
5738 /*
5739 If we get the same error code as expected and it is not a concurrency
5740 issue, or should be ignored.
5741 */
5742 else if ((test_if_equal_repl_errors(expected_error, actual_error) &&
5743 !concurrency_error_code(expected_error)) ||
5744 ignored_error_code(actual_error))
5745 {
5746 DBUG_PRINT("info",("error ignored"));
5747 thd->clear_error(1);
5748 if (actual_error == ER_QUERY_INTERRUPTED ||
5749 actual_error == ER_CONNECTION_KILLED)
5750 thd->reset_killed();
5751 }
5752 /*
5753 Other cases: mostly we expected no error and get one.
5754 */
5755 else if (unlikely(thd->is_slave_error || thd->is_fatal_error))
5756 {
5757 if (!is_parallel_retry_error(rgi, actual_error))
5758 rli->report(ERROR_LEVEL, actual_error, rgi->gtid_info(),
5759 "Error '%s' on query. Default database: '%s'. Query: '%s'",
5760 (actual_error ? thd->get_stmt_da()->message() :
5761 "unexpected success or fatal error"),
5762 thd->get_db(), query_arg);
5763 thd->is_slave_error= 1;
5764 }
5765
5766 /*
5767 TODO: compare the values of "affected rows" around here. Something
5768 like:
5769 if ((uint32) affected_in_event != (uint32) affected_on_slave)
5770 {
5771 sql_print_error("Slave: did not get the expected number of affected \
5772 rows running query from master - expected %d, got %d (this numbers \
5773 should have matched modulo 4294967296).", 0, ...);
5774 thd->is_slave_error = 1;
5775 }
5776 We may also want an option to tell the slave to ignore "affected"
5777 mismatch. This mismatch could be implemented with a new ER_ code, and
5778 to ignore it you would use --slave-skip-errors...
5779
5780 To do the comparison we need to know the value of "affected" which the
5781 above mysql_parse() computed. And we need to know the value of
5782 "affected" in the master's binlog. Both will be implemented later. The
5783 important thing is that we now have the format ready to log the values
5784 of "affected" in the binlog. So we can release 5.0.0 before effectively
5785 logging "affected" and effectively comparing it.
5786 */
5787 } /* End of if (db_ok(... */
5788
5789 {
5790 /**
5791 The following failure injecion works in cooperation with tests
5792 setting @@global.debug= 'd,stop_slave_middle_group'.
5793 The sql thread receives the killed status and will proceed
5794 to shutdown trying to finish incomplete events group.
5795 */
5796 DBUG_EXECUTE_IF("stop_slave_middle_group",
5797 if (!current_stmt_is_commit && is_begin() == 0)
5798 {
5799 if (thd->transaction.all.modified_non_trans_table)
5800 const_cast<Relay_log_info*>(rli)->abort_slave= 1;
5801 };);
5802 }
5803
5804end:
5805 if (unlikely(sub_id && !thd->is_slave_error))
5806 rpl_global_gtid_slave_state->update_state_hash(sub_id, &gtid, hton, rgi);
5807
5808 /*
5809 Probably we have set thd->query, thd->db, thd->catalog to point to places
5810 in the data_buf of this event. Now the event is going to be deleted
5811 probably, so data_buf will be freed, so the thd->... listed above will be
5812 pointers to freed memory.
5813 So we must set them to 0, so that those bad pointers values are not later
5814 used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
5815 don't suffer from these assignments to 0 as DROP TEMPORARY
5816 TABLE uses the db.table syntax.
5817 */
5818 thd->catalog= 0;
5819 thd->set_db(&null_clex_str); /* will free the current database */
5820 thd->reset_query();
5821 DBUG_PRINT("info", ("end: query= 0"));
5822
5823 /* Mark the statement completed. */
5824 MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
5825 thd->m_statement_psi= NULL;
5826 thd->m_digest= NULL;
5827
5828 /*
5829 As a disk space optimization, future masters will not log an event for
5830 LAST_INSERT_ID() if that function returned 0 (and thus they will be able
5831 to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
5832 variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
5833 resetting below we are ready to support that.
5834 */
5835 thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
5836 thd->first_successful_insert_id_in_prev_stmt= 0;
5837 thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5838 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5839 DBUG_RETURN(thd->is_slave_error);
5840}
5841
5842Log_event::enum_skip_reason
5843Query_log_event::do_shall_skip(rpl_group_info *rgi)
5844{
5845 Relay_log_info *rli= rgi->rli;
5846 DBUG_ENTER("Query_log_event::do_shall_skip");
5847 DBUG_PRINT("debug", ("query: '%s' q_len: %d", query, q_len));
5848 DBUG_ASSERT(query && q_len > 0);
5849 DBUG_ASSERT(thd == rgi->thd);
5850
5851 /*
5852 An event skipped due to @@skip_replication must not be counted towards the
5853 number of events to be skipped due to @@sql_slave_skip_counter.
5854 */
5855 if (flags & LOG_EVENT_SKIP_REPLICATION_F &&
5856 opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE)
5857 DBUG_RETURN(Log_event::EVENT_SKIP_IGNORE);
5858
5859 if (rli->slave_skip_counter > 0)
5860 {
5861 if (is_begin())
5862 {
5863 thd->variables.option_bits|= OPTION_BEGIN | OPTION_GTID_BEGIN;
5864 DBUG_RETURN(Log_event::continue_group(rgi));
5865 }
5866
5867 if (is_commit() || is_rollback())
5868 {
5869 thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN);
5870 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5871 }
5872 }
5873#ifdef WITH_WSREP
5874 else if (WSREP_ON && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
5875 thd->wsrep_mysql_replicated > 0 &&
5876 (is_begin() || is_commit()))
5877 {
5878 if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
5879 {
5880 WSREP_DEBUG("skipping wsrep commit %d", thd->wsrep_mysql_replicated);
5881 DBUG_RETURN(Log_event::EVENT_SKIP_IGNORE);
5882 }
5883 else
5884 {
5885 thd->wsrep_mysql_replicated = 0;
5886 }
5887 }
5888#endif
5889 DBUG_RETURN(Log_event::do_shall_skip(rgi));
5890}
5891
5892
5893bool
5894Query_log_event::peek_is_commit_rollback(const char *event_start,
5895 size_t event_len,
5896 enum enum_binlog_checksum_alg checksum_alg)
5897{
5898 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
5899 {
5900 if (event_len > BINLOG_CHECKSUM_LEN)
5901 event_len-= BINLOG_CHECKSUM_LEN;
5902 else
5903 event_len= 0;
5904 }
5905 else
5906 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
5907 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
5908
5909 if (event_len < LOG_EVENT_HEADER_LEN + QUERY_HEADER_LEN || event_len < 9)
5910 return false;
5911 return !memcmp(event_start + (event_len-7), "\0COMMIT", 7) ||
5912 !memcmp(event_start + (event_len-9), "\0ROLLBACK", 9);
5913}
5914
5915#endif
5916
5917
5918/**************************************************************************
5919 Start_log_event_v3 methods
5920**************************************************************************/
5921
5922#ifndef MYSQL_CLIENT
5923Start_log_event_v3::Start_log_event_v3()
5924 :Log_event(), created(0), binlog_version(BINLOG_VERSION),
5925 dont_set_created(0)
5926{
5927 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5928}
5929#endif
5930
5931/*
5932 Start_log_event_v3::pack_info()
5933*/
5934
5935#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5936void Start_log_event_v3::pack_info(Protocol *protocol)
5937{
5938 char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5939 pos= strmov(buf, "Server ver: ");
5940 pos= strmov(pos, server_version);
5941 pos= strmov(pos, ", Binlog ver: ");
5942 pos= int10_to_str(binlog_version, pos, 10);
5943 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5944}
5945#endif
5946
5947
5948/*
5949 Start_log_event_v3::print()
5950*/
5951
5952#ifdef MYSQL_CLIENT
5953bool Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5954{
5955 DBUG_ENTER("Start_log_event_v3::print");
5956
5957 Write_on_release_cache cache(&print_event_info->head_cache, file,
5958 Write_on_release_cache::FLUSH_F);
5959
5960 if (!print_event_info->short_form)
5961 {
5962 if (print_header(&cache, print_event_info, FALSE) ||
5963 my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
5964 binlog_version, server_version) ||
5965 print_timestamp(&cache))
5966 goto err;
5967 if (created)
5968 if (my_b_printf(&cache," at startup"))
5969 goto err;
5970 if (my_b_printf(&cache, "\n"))
5971 goto err;
5972 if (flags & LOG_EVENT_BINLOG_IN_USE_F)
5973 if (my_b_printf(&cache,
5974 "# Warning: this binlog is either in use or was not "
5975 "closed properly.\n"))
5976 goto err;
5977 }
5978 if (!is_artificial_event() && created)
5979 {
5980#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5981 /*
5982 This is for mysqlbinlog: like in replication, we want to delete the stale
5983 tmp files left by an unclean shutdown of mysqld (temporary tables)
5984 and rollback unfinished transaction.
5985 Probably this can be done with RESET CONNECTION (syntax to be defined).
5986 */
5987 if (my_b_printf(&cache,"RESET CONNECTION%s\n",
5988 print_event_info->delimiter))
5989 goto err;
5990#else
5991 if (my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter))
5992 goto err;
5993#endif
5994 }
5995 if (temp_buf &&
5996 print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5997 !print_event_info->short_form)
5998 {
5999 if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
6000 if (my_b_printf(&cache, "BINLOG '\n"))
6001 goto err;
6002 if (print_base64(&cache, print_event_info, FALSE))
6003 goto err;
6004 print_event_info->printed_fd_event= TRUE;
6005 }
6006 DBUG_RETURN(cache.flush_data());
6007err:
6008 DBUG_RETURN(1);
6009}
6010#endif /* MYSQL_CLIENT */
6011
6012/*
6013 Start_log_event_v3::Start_log_event_v3()
6014*/
6015
6016Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
6017 const Format_description_log_event
6018 *description_event)
6019 :Log_event(buf, description_event), binlog_version(BINLOG_VERSION)
6020{
6021 if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET)
6022 {
6023 server_version[0]= 0;
6024 return;
6025 }
6026 buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
6027 binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
6028 memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
6029 ST_SERVER_VER_LEN);
6030 // prevent overrun if log is corrupted on disk
6031 server_version[ST_SERVER_VER_LEN-1]= 0;
6032 created= uint4korr(buf+ST_CREATED_OFFSET);
6033 dont_set_created= 1;
6034}
6035
6036
6037/*
6038 Start_log_event_v3::write()
6039*/
6040
6041#ifndef MYSQL_CLIENT
6042bool Start_log_event_v3::write()
6043{
6044 char buff[START_V3_HEADER_LEN];
6045 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
6046 memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
6047 if (!dont_set_created)
6048 created= get_time(); // this sets when and when_sec_part as a side effect
6049 int4store(buff + ST_CREATED_OFFSET,created);
6050 return write_header(sizeof(buff)) ||
6051 write_data(buff, sizeof(buff)) ||
6052 write_footer();
6053}
6054#endif
6055
6056
6057#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6058
6059/**
6060 Start_log_event_v3::do_apply_event() .
6061 The master started
6062
6063 IMPLEMENTATION
6064 - To handle the case where the master died without having time to write
6065 DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
6066 TODO), we clean up all temporary tables that we got, if we are sure we
6067 can (see below).
6068
6069 @todo
6070 - Remove all active user locks.
6071 Guilhem 2003-06: this is true but not urgent: the worst it can cause is
6072 the use of a bit of memory for a user lock which will not be used
6073 anymore. If the user lock is later used, the old one will be released. In
6074 other words, no deadlock problem.
6075*/
6076
6077int Start_log_event_v3::do_apply_event(rpl_group_info *rgi)
6078{
6079 DBUG_ENTER("Start_log_event_v3::do_apply_event");
6080 int error= 0;
6081 Relay_log_info *rli= rgi->rli;
6082
6083 switch (binlog_version)
6084 {
6085 case 3:
6086 case 4:
6087 /*
6088 This can either be 4.x (then a Start_log_event_v3 is only at master
6089 startup so we are sure the master has restarted and cleared his temp
6090 tables; the event always has 'created'>0) or 5.0 (then we have to test
6091 'created').
6092 */
6093 if (created)
6094 {
6095 rli->close_temporary_tables();
6096
6097 /*
6098 The following is only false if we get here with a BINLOG statement
6099 */
6100 if (rli->mi)
6101 cleanup_load_tmpdir(&rli->mi->cmp_connection_name);
6102 }
6103 break;
6104
6105 /*
6106 Now the older formats; in that case load_tmpdir is cleaned up by the I/O
6107 thread.
6108 */
6109 case 1:
6110 if (strncmp(rli->relay_log.description_event_for_exec->server_version,
6111 "3.23.57",7) >= 0 && created)
6112 {
6113 /*
6114 Can distinguish, based on the value of 'created': this event was
6115 generated at master startup.
6116 */
6117 rli->close_temporary_tables();
6118 }
6119 /*
6120 Otherwise, can't distinguish a Start_log_event generated at
6121 master startup and one generated by master FLUSH LOGS, so cannot
6122 be sure temp tables have to be dropped. So do nothing.
6123 */
6124 break;
6125 default:
6126 /*
6127 This case is not expected. It can be either an event corruption or an
6128 unsupported binary log version.
6129 */
6130 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6131 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
6132 "Binlog version not supported");
6133 DBUG_RETURN(1);
6134 }
6135 DBUG_RETURN(error);
6136}
6137#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6138
6139/***************************************************************************
6140 Format_description_log_event methods
6141****************************************************************************/
6142
6143/**
6144 Format_description_log_event 1st ctor.
6145
6146 Ctor. Can be used to create the event to write to the binary log (when the
6147 server starts or when FLUSH LOGS), or to create artificial events to parse
6148 binlogs from MySQL 3.23 or 4.x.
6149 When in a client, only the 2nd use is possible.
6150
6151 @param binlog_version the binlog version for which we want to build
6152 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
6153 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
6154 old 4.0 (binlog version 2) is not supported;
6155 it should not be used for replication with
6156 5.0.
6157 @param server_ver a string containing the server version.
6158*/
6159
6160Format_description_log_event::
6161Format_description_log_event(uint8 binlog_ver, const char* server_ver)
6162 :Start_log_event_v3(), event_type_permutation(0)
6163{
6164 binlog_version= binlog_ver;
6165 switch (binlog_ver) {
6166 case 4: /* MySQL 5.0 */
6167 memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
6168 DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
6169 strmov(server_version, "5.0.34"););
6170 common_header_len= LOG_EVENT_HEADER_LEN;
6171 number_of_event_types= LOG_EVENT_TYPES;
6172 /* we'll catch my_malloc() error in is_valid() */
6173 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
6174 + BINLOG_CHECKSUM_ALG_DESC_LEN,
6175 MYF(0));
6176 /*
6177 This long list of assignments is not beautiful, but I see no way to
6178 make it nicer, as the right members are #defines, not array members, so
6179 it's impossible to write a loop.
6180 */
6181 if (post_header_len)
6182 {
6183#ifndef DBUG_OFF
6184 // Allows us to sanity-check that all events initialized their
6185 // events (see the end of this 'if' block).
6186 memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
6187#endif
6188
6189 /* Note: all event types must explicitly fill in their lengths here. */
6190 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
6191 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
6192 post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
6193 post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
6194 post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
6195 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
6196 post_header_len[SLAVE_EVENT-1]= SLAVE_HEADER_LEN;
6197 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
6198 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
6199 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
6200 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
6201 post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
6202 post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
6203 post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
6204 post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
6205 post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
6206 post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
6207 post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
6208 /*
6209 The PRE_GA events are never be written to any binlog, but
6210 their lengths are included in Format_description_log_event.
6211 Hence, we need to be assign some value here, to avoid reading
6212 uninitialized memory when the array is written to disk.
6213 */
6214 post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
6215 post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
6216 post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
6217
6218 post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
6219 post_header_len[WRITE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6220 post_header_len[UPDATE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6221 post_header_len[DELETE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6222 /*
6223 We here have the possibility to simulate a master of before we changed
6224 the table map id to be stored in 6 bytes: when it was stored in 4
6225 bytes (=> post_header_len was 6). This is used to test backward
6226 compatibility.
6227 This code can be removed after a few months (today is Dec 21st 2005),
6228 when we know that the 4-byte masters are not deployed anymore (check
6229 with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
6230 too.
6231 */
6232 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
6233 post_header_len[TABLE_MAP_EVENT-1]=
6234 post_header_len[WRITE_ROWS_EVENT_V1-1]=
6235 post_header_len[UPDATE_ROWS_EVENT_V1-1]=
6236 post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
6237 post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
6238 post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
6239 post_header_len[IGNORABLE_LOG_EVENT-1]= 0;
6240 post_header_len[ROWS_QUERY_LOG_EVENT-1]= 0;
6241 post_header_len[GTID_LOG_EVENT-1]= 0;
6242 post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]= 0;
6243 post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= 0;
6244 post_header_len[TRANSACTION_CONTEXT_EVENT-1]= 0;
6245 post_header_len[VIEW_CHANGE_EVENT-1]= 0;
6246 post_header_len[XA_PREPARE_LOG_EVENT-1]= 0;
6247 post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
6248 post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
6249 post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
6250
6251 // Set header length of the reserved events to 0
6252 memset(post_header_len + MYSQL_EVENTS_END - 1, 0,
6253 (MARIA_EVENTS_BEGIN - MYSQL_EVENTS_END)*sizeof(uint8));
6254
6255 // Set header lengths of Maria events
6256 post_header_len[ANNOTATE_ROWS_EVENT-1]= ANNOTATE_ROWS_HEADER_LEN;
6257 post_header_len[BINLOG_CHECKPOINT_EVENT-1]=
6258 BINLOG_CHECKPOINT_HEADER_LEN;
6259 post_header_len[GTID_EVENT-1]= GTID_HEADER_LEN;
6260 post_header_len[GTID_LIST_EVENT-1]= GTID_LIST_HEADER_LEN;
6261 post_header_len[START_ENCRYPTION_EVENT-1]= START_ENCRYPTION_HEADER_LEN;
6262
6263 //compressed event
6264 post_header_len[QUERY_COMPRESSED_EVENT-1]= QUERY_HEADER_LEN;
6265 post_header_len[WRITE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2;
6266 post_header_len[UPDATE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2;
6267 post_header_len[DELETE_ROWS_COMPRESSED_EVENT-1]= ROWS_HEADER_LEN_V2;
6268 post_header_len[WRITE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6269 post_header_len[UPDATE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6270 post_header_len[DELETE_ROWS_COMPRESSED_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
6271
6272 // Sanity-check that all post header lengths are initialized.
6273 int i;
6274 for (i=0; i<number_of_event_types; i++)
6275 DBUG_ASSERT(post_header_len[i] != 255);
6276 }
6277 break;
6278
6279 case 1: /* 3.23 */
6280 case 3: /* 4.0.x x>=2 */
6281 /*
6282 We build an artificial (i.e. not sent by the master) event, which
6283 describes what those old master versions send.
6284 */
6285 if (binlog_ver==1)
6286 strmov(server_version, server_ver ? server_ver : "3.23");
6287 else
6288 strmov(server_version, server_ver ? server_ver : "4.0");
6289 common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
6290 LOG_EVENT_MINIMAL_HEADER_LEN;
6291 /*
6292 The first new event in binlog version 4 is Format_desc. So any event type
6293 after that does not exist in older versions. We use the events known by
6294 version 3, even if version 1 had only a subset of them (this is not a
6295 problem: it uses a few bytes for nothing but unifies code; it does not
6296 make the slave detect less corruptions).
6297 */
6298 number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
6299 post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
6300 MYF(0));
6301 if (post_header_len)
6302 {
6303 post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
6304 post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
6305 post_header_len[STOP_EVENT-1]= 0;
6306 post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
6307 post_header_len[INTVAR_EVENT-1]= 0;
6308 post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
6309 post_header_len[SLAVE_EVENT-1]= 0;
6310 post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
6311 post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
6312 post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
6313 post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
6314 post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
6315 post_header_len[RAND_EVENT-1]= 0;
6316 post_header_len[USER_VAR_EVENT-1]= 0;
6317 }
6318 break;
6319 default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
6320 post_header_len= 0; /* will make is_valid() fail */
6321 break;
6322 }
6323 calc_server_version_split();
6324 checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
6325 reset_crypto();
6326}
6327
6328
6329/**
6330 The problem with this constructor is that the fixed header may have a
6331 length different from this version, but we don't know this length as we
6332 have not read the Format_description_log_event which says it, yet. This
6333 length is in the post-header of the event, but we don't know where the
6334 post-header starts.
6335
6336 So this type of event HAS to:
6337 - either have the header's length at the beginning (in the header, at a
6338 fixed position which will never be changed), not in the post-header. That
6339 would make the header be "shifted" compared to other events.
6340 - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
6341 versions, so that we know for sure.
6342
6343 I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
6344 it is sent before Format_description_log_event).
6345*/
6346
6347Format_description_log_event::
6348Format_description_log_event(const char* buf,
6349 uint event_len,
6350 const
6351 Format_description_log_event*
6352 description_event)
6353 :Start_log_event_v3(buf, event_len, description_event),
6354 common_header_len(0), post_header_len(NULL), event_type_permutation(0)
6355{
6356 DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
6357 if (!Start_log_event_v3::is_valid())
6358 DBUG_VOID_RETURN; /* sanity check */
6359 buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
6360 if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
6361 DBUG_VOID_RETURN; /* sanity check */
6362 number_of_event_types=
6363 event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
6364 DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
6365 common_header_len, number_of_event_types));
6366 /* If alloc fails, we'll detect it in is_valid() */
6367
6368 post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
6369 number_of_event_types*
6370 sizeof(*post_header_len),
6371 MYF(0));
6372 calc_server_version_split();
6373 if (!is_version_before_checksum(&server_version_split))
6374 {
6375 /* the last bytes are the checksum alg desc and value (or value's room) */
6376 number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
6377 checksum_alg= (enum_binlog_checksum_alg)post_header_len[number_of_event_types];
6378 }
6379 else
6380 {
6381 checksum_alg= BINLOG_CHECKSUM_ALG_UNDEF;
6382 }
6383 reset_crypto();
6384
6385 DBUG_VOID_RETURN;
6386}
6387
6388#ifndef MYSQL_CLIENT
6389bool Format_description_log_event::write()
6390{
6391 bool ret;
6392 bool no_checksum;
6393 /*
6394 We don't call Start_log_event_v3::write() because this would make 2
6395 my_b_safe_write().
6396 */
6397 uchar buff[START_V3_HEADER_LEN+1];
6398 size_t rec_size= sizeof(buff) + BINLOG_CHECKSUM_ALG_DESC_LEN +
6399 number_of_event_types;
6400 int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
6401 memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
6402 if (!dont_set_created)
6403 created= get_time();
6404 int4store(buff + ST_CREATED_OFFSET,created);
6405 buff[ST_COMMON_HEADER_LEN_OFFSET]= common_header_len;
6406 /*
6407 if checksum is requested
6408 record the checksum-algorithm descriptor next to
6409 post_header_len vector which will be followed by the checksum value.
6410 Master is supposed to trigger checksum computing by binlog_checksum_options,
6411 slave does it via marking the event according to
6412 FD_queue checksum_alg value.
6413 */
6414 compile_time_assert(BINLOG_CHECKSUM_ALG_DESC_LEN == 1);
6415#ifdef DBUG_ASSERT_EXISTS
6416 data_written= 0; // to prepare for need_checksum assert
6417#endif
6418 uint8 checksum_byte= (uint8)
6419 (need_checksum() ? checksum_alg : BINLOG_CHECKSUM_ALG_OFF);
6420 /*
6421 FD of checksum-aware server is always checksum-equipped, (V) is in,
6422 regardless of @@global.binlog_checksum policy.
6423 Thereby a combination of (A) == 0, (V) != 0 means
6424 it's the checksum-aware server's FD event that heads checksum-free binlog
6425 file.
6426 Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
6427 A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
6428 heading the checksummed binlog.
6429 (A), (V) presence in FD of the checksum-aware server makes the event
6430 1 + 4 bytes bigger comparing to the former FD.
6431 */
6432
6433 if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
6434 {
6435 checksum_alg= BINLOG_CHECKSUM_ALG_CRC32; // Forcing (V) room to fill anyway
6436 }
6437 ret= write_header(rec_size) ||
6438 write_data(buff, sizeof(buff)) ||
6439 write_data(post_header_len, number_of_event_types) ||
6440 write_data(&checksum_byte, sizeof(checksum_byte)) ||
6441 write_footer();
6442 if (no_checksum)
6443 checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
6444 return ret;
6445}
6446#endif
6447
6448#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6449int Format_description_log_event::do_apply_event(rpl_group_info *rgi)
6450{
6451 int ret= 0;
6452 Relay_log_info *rli= rgi->rli;
6453 DBUG_ENTER("Format_description_log_event::do_apply_event");
6454
6455 /*
6456 As a transaction NEVER spans on 2 or more binlogs:
6457 if we have an active transaction at this point, the master died
6458 while writing the transaction to the binary log, i.e. while
6459 flushing the binlog cache to the binlog. XA guarantees that master has
6460 rolled back. So we roll back.
6461 Note: this event could be sent by the master to inform us of the
6462 format of its binlog; in other words maybe it is not at its
6463 original place when it comes to us; we'll know this by checking
6464 log_pos ("artificial" events have log_pos == 0).
6465 */
6466 if (!is_artificial_event() && created && thd->transaction.all.ha_list)
6467 {
6468 /* This is not an error (XA is safe), just an information */
6469 rli->report(INFORMATION_LEVEL, 0, NULL,
6470 "Rolling back unfinished transaction (no COMMIT "
6471 "or ROLLBACK in relay log). A probable cause is that "
6472 "the master died while writing the transaction to "
6473 "its binary log, thus rolled back too.");
6474 rgi->cleanup_context(thd, 1);
6475 }
6476
6477 /*
6478 If this event comes from ourselves, there is no cleaning task to
6479 perform, we don't call Start_log_event_v3::do_apply_event()
6480 (this was just to update the log's description event).
6481 */
6482 if (server_id != (uint32) global_system_variables.server_id)
6483 {
6484 /*
6485 If the event was not requested by the slave i.e. the master sent
6486 it while the slave asked for a position >4, the event will make
6487 rli->group_master_log_pos advance. Say that the slave asked for
6488 position 1000, and the Format_desc event's end is 96. Then in
6489 the beginning of replication rli->group_master_log_pos will be
6490 0, then 96, then jump to first really asked event (which is
6491 >96). So this is ok.
6492 */
6493 ret= Start_log_event_v3::do_apply_event(rgi);
6494 }
6495
6496 if (!ret)
6497 {
6498 /* Save the information describing this binlog */
6499 copy_crypto_data(rli->relay_log.description_event_for_exec);
6500 delete rli->relay_log.description_event_for_exec;
6501 rli->relay_log.description_event_for_exec= this;
6502 }
6503
6504 DBUG_RETURN(ret);
6505}
6506
6507int Format_description_log_event::do_update_pos(rpl_group_info *rgi)
6508{
6509 if (server_id == (uint32) global_system_variables.server_id)
6510 {
6511 /*
6512 We only increase the relay log position if we are skipping
6513 events and do not touch any group_* variables, nor flush the
6514 relay log info. If there is a crash, we will have to re-skip
6515 the events again, but that is a minor issue.
6516
6517 If we do not skip stepping the group log position (and the
6518 server id was changed when restarting the server), it might well
6519 be that we start executing at a position that is invalid, e.g.,
6520 at a Rows_log_event or a Query_log_event preceeded by a
6521 Intvar_log_event instead of starting at a Table_map_log_event or
6522 the Intvar_log_event respectively.
6523 */
6524 rgi->inc_event_relay_log_pos();
6525 return 0;
6526 }
6527 else
6528 {
6529 return Log_event::do_update_pos(rgi);
6530 }
6531}
6532
6533Log_event::enum_skip_reason
6534Format_description_log_event::do_shall_skip(rpl_group_info *rgi)
6535{
6536 return Log_event::EVENT_SKIP_NOT;
6537}
6538
6539#endif
6540
6541bool Format_description_log_event::start_decryption(Start_encryption_log_event* sele)
6542{
6543 DBUG_ASSERT(crypto_data.scheme == 0);
6544
6545 if (!sele->is_valid())
6546 return 1;
6547
6548 memcpy(crypto_data.nonce, sele->nonce, BINLOG_NONCE_LENGTH);
6549 return crypto_data.init(sele->crypto_scheme, sele->key_version);
6550}
6551
6552static inline void
6553do_server_version_split(char* version,
6554 Format_description_log_event::master_version_split *split_versions)
6555{
6556 char *p= version, *r;
6557 ulong number;
6558 for (uint i= 0; i<=2; i++)
6559 {
6560 number= strtoul(p, &r, 10);
6561 /*
6562 It is an invalid version if any version number greater than 255 or
6563 first number is not followed by '.'.
6564 */
6565 if (number < 256 && (*r == '.' || i != 0))
6566 split_versions->ver[i]= (uchar) number;
6567 else
6568 {
6569 split_versions->ver[0]= 0;
6570 split_versions->ver[1]= 0;
6571 split_versions->ver[2]= 0;
6572 break;
6573 }
6574
6575 p= r;
6576 if (*r == '.')
6577 p++; // skip the dot
6578 }
6579 if (strstr(p, "MariaDB") != 0 || strstr(p, "-maria-") != 0)
6580 split_versions->kind=
6581 Format_description_log_event::master_version_split::KIND_MARIADB;
6582 else
6583 split_versions->kind=
6584 Format_description_log_event::master_version_split::KIND_MYSQL;
6585}
6586
6587
6588/**
6589 Splits the event's 'server_version' string into three numeric pieces stored
6590 into 'server_version_split':
6591 X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
6592 X.Yabc -> {X,Y,0}
6593 'server_version_split' is then used for lookups to find if the server which
6594 created this event has some known bug.
6595*/
6596void Format_description_log_event::calc_server_version_split()
6597{
6598 do_server_version_split(server_version, &server_version_split);
6599
6600 DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
6601 " '%s' %d %d %d", server_version,
6602 server_version_split.ver[0],
6603 server_version_split.ver[1], server_version_split.ver[2]));
6604}
6605
6606static inline ulong
6607version_product(const Format_description_log_event::master_version_split* version_split)
6608{
6609 return ((version_split->ver[0] * 256 + version_split->ver[1]) * 256
6610 + version_split->ver[2]);
6611}
6612
6613/**
6614 @return TRUE is the event's version is earlier than one that introduced
6615 the replication event checksum. FALSE otherwise.
6616*/
6617bool
6618Format_description_log_event::is_version_before_checksum(const master_version_split
6619 *version_split)
6620{
6621 return version_product(version_split) <
6622 (version_split->kind == master_version_split::KIND_MARIADB ?
6623 checksum_version_product_mariadb : checksum_version_product_mysql);
6624}
6625
6626/**
6627 @param buf buffer holding serialized FD event
6628 @param len netto (possible checksum is stripped off) length of the event buf
6629
6630 @return the version-safe checksum alg descriptor where zero
6631 designates no checksum, 255 - the orginator is
6632 checksum-unaware (effectively no checksum) and the actuall
6633 [1-254] range alg descriptor.
6634*/
6635enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
6636{
6637 enum enum_binlog_checksum_alg ret;
6638 char version[ST_SERVER_VER_LEN];
6639 Format_description_log_event::master_version_split version_split;
6640
6641 DBUG_ENTER("get_checksum_alg");
6642 DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
6643
6644 memcpy(version,
6645 buf + LOG_EVENT_MINIMAL_HEADER_LEN + ST_SERVER_VER_OFFSET,
6646 ST_SERVER_VER_LEN);
6647 version[ST_SERVER_VER_LEN - 1]= 0;
6648
6649 do_server_version_split(version, &version_split);
6650 ret= Format_description_log_event::is_version_before_checksum(&version_split)
6651 ? BINLOG_CHECKSUM_ALG_UNDEF
6652 : (enum_binlog_checksum_alg)buf[len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN];
6653 DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
6654 ret == BINLOG_CHECKSUM_ALG_UNDEF ||
6655 ret == BINLOG_CHECKSUM_ALG_CRC32);
6656 DBUG_RETURN(ret);
6657}
6658
6659Start_encryption_log_event::Start_encryption_log_event(
6660 const char* buf, uint event_len,
6661 const Format_description_log_event* description_event)
6662 :Log_event(buf, description_event)
6663{
6664 if ((int)event_len ==
6665 LOG_EVENT_MINIMAL_HEADER_LEN + Start_encryption_log_event::get_data_size())
6666 {
6667 buf += LOG_EVENT_MINIMAL_HEADER_LEN;
6668 crypto_scheme = *(uchar*)buf;
6669 key_version = uint4korr(buf + BINLOG_CRYPTO_SCHEME_LENGTH);
6670 memcpy(nonce,
6671 buf + BINLOG_CRYPTO_SCHEME_LENGTH + BINLOG_KEY_VERSION_LENGTH,
6672 BINLOG_NONCE_LENGTH);
6673 }
6674 else
6675 crypto_scheme= ~0; // invalid
6676}
6677
6678#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6679int Start_encryption_log_event::do_apply_event(rpl_group_info* rgi)
6680{
6681 return rgi->rli->relay_log.description_event_for_exec->start_decryption(this);
6682}
6683
6684int Start_encryption_log_event::do_update_pos(rpl_group_info *rgi)
6685{
6686 /*
6687 master never sends Start_encryption_log_event, any SELE that a slave
6688 might see was created locally in MYSQL_BIN_LOG::open() on the slave
6689 */
6690 rgi->inc_event_relay_log_pos();
6691 return 0;
6692}
6693
6694#endif
6695
6696#ifndef MYSQL_SERVER
6697bool Start_encryption_log_event::print(FILE* file,
6698 PRINT_EVENT_INFO* print_event_info)
6699{
6700 Write_on_release_cache cache(&print_event_info->head_cache, file);
6701 StringBuffer<1024> buf;
6702 buf.append(STRING_WITH_LEN("# Encryption scheme: "));
6703 buf.append_ulonglong(crypto_scheme);
6704 buf.append(STRING_WITH_LEN(", key_version: "));
6705 buf.append_ulonglong(key_version);
6706 buf.append(STRING_WITH_LEN(", nonce: "));
6707 buf.append_hex(nonce, BINLOG_NONCE_LENGTH);
6708 buf.append(STRING_WITH_LEN("\n# The rest of the binlog is encrypted!\n"));
6709 if (my_b_write(&cache, (uchar*)buf.ptr(), buf.length()))
6710 return 1;
6711 return (cache.flush_data());
6712}
6713#endif
6714 /**************************************************************************
6715 Load_log_event methods
6716 General note about Load_log_event: the binlogging of LOAD DATA INFILE is
6717 going to be changed in 5.0 (or maybe in 5.1; not decided yet).
6718 However, the 5.0 slave could still have to read such events (from a 4.x
6719 master), convert them (which just means maybe expand the header, when 5.0
6720 servers have a UID in events) (remember that whatever is after the header
6721 will be like in 4.x, as this event's format is not modified in 5.0 as we
6722 will use new types of events to log the new LOAD DATA INFILE features).
6723 To be able to read/convert, we just need to not assume that the common
6724 header is of length LOG_EVENT_HEADER_LEN (we must use the description
6725 event).
6726 Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
6727 between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
6728 positions displayed in SHOW SLAVE STATUS then are fine too).
6729 **************************************************************************/
6730
6731/*
6732 Load_log_event::print_query()
6733*/
6734
6735#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6736bool Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
6737 String *buf, my_off_t *fn_start,
6738 my_off_t *fn_end, const char *qualify_db)
6739{
6740 if (need_db && db && db_len)
6741 {
6742 buf->append(STRING_WITH_LEN("use "));
6743 append_identifier(thd, buf, db, db_len);
6744 buf->append(STRING_WITH_LEN("; "));
6745 }
6746
6747 buf->append(STRING_WITH_LEN("LOAD DATA "));
6748
6749 if (is_concurrent)
6750 buf->append(STRING_WITH_LEN("CONCURRENT "));
6751
6752 if (fn_start)
6753 *fn_start= buf->length();
6754
6755 if (check_fname_outside_temp_buf())
6756 buf->append(STRING_WITH_LEN("LOCAL "));
6757 buf->append(STRING_WITH_LEN("INFILE '"));
6758 buf->append_for_single_quote(fname, fname_len);
6759 buf->append(STRING_WITH_LEN("' "));
6760
6761 if (sql_ex.opt_flags & REPLACE_FLAG)
6762 buf->append(STRING_WITH_LEN("REPLACE "));
6763 else if (sql_ex.opt_flags & IGNORE_FLAG)
6764 buf->append(STRING_WITH_LEN("IGNORE "));
6765
6766 buf->append(STRING_WITH_LEN("INTO"));
6767
6768 if (fn_end)
6769 *fn_end= buf->length();
6770
6771 buf->append(STRING_WITH_LEN(" TABLE "));
6772 if (qualify_db)
6773 {
6774 append_identifier(thd, buf, qualify_db, strlen(qualify_db));
6775 buf->append(STRING_WITH_LEN("."));
6776 }
6777 append_identifier(thd, buf, table_name, table_name_len);
6778
6779 if (cs != NULL)
6780 {
6781 buf->append(STRING_WITH_LEN(" CHARACTER SET "));
6782 buf->append(cs, strlen(cs));
6783 }
6784
6785 /* We have to create all optional fields as the default is not empty */
6786 buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
6787 pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
6788 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6789 buf->append(STRING_WITH_LEN(" OPTIONALLY "));
6790 buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
6791 pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
6792
6793 buf->append(STRING_WITH_LEN(" ESCAPED BY "));
6794 pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
6795
6796 buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
6797 pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
6798 if (sql_ex.line_start_len)
6799 {
6800 buf->append(STRING_WITH_LEN(" STARTING BY "));
6801 pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
6802 }
6803
6804 if ((long) skip_lines > 0)
6805 {
6806 buf->append(STRING_WITH_LEN(" IGNORE "));
6807 buf->append_ulonglong(skip_lines);
6808 buf->append(STRING_WITH_LEN(" LINES "));
6809 }
6810
6811 if (num_fields)
6812 {
6813 uint i;
6814 const char *field= fields;
6815 buf->append(STRING_WITH_LEN(" ("));
6816 for (i = 0; i < num_fields; i++)
6817 {
6818 if (i)
6819 {
6820 /*
6821 Yes, the space and comma is reversed here. But this is mostly dead
6822 code, at most used when reading really old binlogs from old servers,
6823 so better just leave it as is...
6824 */
6825 buf->append(STRING_WITH_LEN(" ,"));
6826 }
6827 append_identifier(thd, buf, field, field_lens[i]);
6828 field+= field_lens[i] + 1;
6829 }
6830 buf->append(STRING_WITH_LEN(")"));
6831 }
6832 return 0;
6833}
6834
6835
6836void Load_log_event::pack_info(Protocol *protocol)
6837{
6838 char query_buffer[1024];
6839 String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
6840
6841 query_str.length(0);
6842 print_query(protocol->thd, TRUE, NULL, &query_str, 0, 0, NULL);
6843 protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
6844}
6845#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6846
6847
6848#ifndef MYSQL_CLIENT
6849
6850/*
6851 Load_log_event::write_data_header()
6852*/
6853
6854bool Load_log_event::write_data_header()
6855{
6856 char buf[LOAD_HEADER_LEN];
6857 int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
6858 int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
6859 int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
6860 buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
6861 buf[L_DB_LEN_OFFSET] = (char)db_len;
6862 int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
6863 return write_data(buf, LOAD_HEADER_LEN) != 0;
6864}
6865
6866
6867/*
6868 Load_log_event::write_data_body()
6869*/
6870
6871bool Load_log_event::write_data_body()
6872{
6873 if (sql_ex.write_data(writer))
6874 return 1;
6875 if (num_fields && fields && field_lens)
6876 {
6877 if (write_data(field_lens, num_fields) ||
6878 write_data(fields, field_block_len))
6879 return 1;
6880 }
6881 return (write_data(table_name, table_name_len + 1) ||
6882 write_data(db, db_len + 1) ||
6883 write_data(fname, fname_len));
6884}
6885
6886
6887/*
6888 Load_log_event::Load_log_event()
6889*/
6890
6891Load_log_event::Load_log_event(THD *thd_arg, const sql_exchange *ex,
6892 const char *db_arg, const char *table_name_arg,
6893 List<Item> &fields_arg,
6894 bool is_concurrent_arg,
6895 enum enum_duplicates handle_dup,
6896 bool ignore, bool using_trans)
6897 :Log_event(thd_arg,
6898 thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
6899 using_trans),
6900 thread_id(thd_arg->thread_id),
6901 slave_proxy_id((ulong)thd_arg->variables.pseudo_thread_id),
6902 num_fields(0),fields(0),
6903 field_lens(0),field_block_len(0),
6904 table_name(table_name_arg ? table_name_arg : ""),
6905 db(db_arg), fname(ex->file_name), local_fname(FALSE),
6906 is_concurrent(is_concurrent_arg)
6907{
6908 time_t end_time;
6909 time(&end_time);
6910 exec_time = (ulong) (end_time - thd_arg->start_time);
6911 /* db can never be a zero pointer in 4.0 */
6912 db_len = (uint32) strlen(db);
6913 table_name_len = (uint32) strlen(table_name);
6914 fname_len = (fname) ? (uint) strlen(fname) : 0;
6915 sql_ex.field_term = ex->field_term->ptr();
6916 sql_ex.field_term_len = (uint8) ex->field_term->length();
6917 sql_ex.enclosed = ex->enclosed->ptr();
6918 sql_ex.enclosed_len = (uint8) ex->enclosed->length();
6919 sql_ex.line_term = ex->line_term->ptr();
6920 sql_ex.line_term_len = (uint8) ex->line_term->length();
6921 sql_ex.line_start = ex->line_start->ptr();
6922 sql_ex.line_start_len = (uint8) ex->line_start->length();
6923 sql_ex.escaped = ex->escaped->ptr();
6924 sql_ex.escaped_len = (uint8) ex->escaped->length();
6925 sql_ex.opt_flags = 0;
6926 sql_ex.cached_new_format = -1;
6927
6928 if (ex->dumpfile)
6929 sql_ex.opt_flags|= DUMPFILE_FLAG;
6930 if (ex->opt_enclosed)
6931 sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
6932
6933 sql_ex.empty_flags= 0;
6934
6935 switch (handle_dup) {
6936 case DUP_REPLACE:
6937 sql_ex.opt_flags|= REPLACE_FLAG;
6938 break;
6939 case DUP_UPDATE: // Impossible here
6940 case DUP_ERROR:
6941 break;
6942 }
6943 if (ignore)
6944 sql_ex.opt_flags|= IGNORE_FLAG;
6945
6946 if (!ex->field_term->length())
6947 sql_ex.empty_flags |= FIELD_TERM_EMPTY;
6948 if (!ex->enclosed->length())
6949 sql_ex.empty_flags |= ENCLOSED_EMPTY;
6950 if (!ex->line_term->length())
6951 sql_ex.empty_flags |= LINE_TERM_EMPTY;
6952 if (!ex->line_start->length())
6953 sql_ex.empty_flags |= LINE_START_EMPTY;
6954 if (!ex->escaped->length())
6955 sql_ex.empty_flags |= ESCAPED_EMPTY;
6956
6957 skip_lines = ex->skip_lines;
6958
6959 List_iterator<Item> li(fields_arg);
6960 field_lens_buf.length(0);
6961 fields_buf.length(0);
6962 Item* item;
6963 while ((item = li++))
6964 {
6965 num_fields++;
6966 uchar len= (uchar) item->name.length;
6967 field_block_len += len + 1;
6968 fields_buf.append(item->name.str, len + 1);
6969 field_lens_buf.append((char*)&len, 1);
6970 }
6971
6972 field_lens = (const uchar*)field_lens_buf.ptr();
6973 fields = fields_buf.ptr();
6974}
6975#endif /* !MYSQL_CLIENT */
6976
6977
6978/**
6979 @note
6980 The caller must do buf[event_len] = 0 before he starts using the
6981 constructed event.
6982*/
6983Load_log_event::Load_log_event(const char *buf, uint event_len,
6984 const Format_description_log_event *description_event)
6985 :Log_event(buf, description_event), num_fields(0), fields(0),
6986 field_lens(0),field_block_len(0),
6987 table_name(0), db(0), fname(0), local_fname(FALSE),
6988 /*
6989 Load_log_event which comes from the binary log does not contain
6990 information about the type of insert which was used on the master.
6991 Assume that it was an ordinary, non-concurrent LOAD DATA.
6992 */
6993 is_concurrent(FALSE)
6994{
6995 DBUG_ENTER("Load_log_event");
6996 /*
6997 I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6998 4.0->5.0 and 5.0->5.0 and it works.
6999 */
7000 if (event_len)
7001 copy_log_event(buf, event_len,
7002 (((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
7003 LOAD_HEADER_LEN +
7004 description_event->common_header_len :
7005 LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
7006 description_event);
7007 /* otherwise it's a derived class, will call copy_log_event() itself */
7008 DBUG_VOID_RETURN;
7009}
7010
7011
7012/*
7013 Load_log_event::copy_log_event()
7014*/
7015
7016int Load_log_event::copy_log_event(const char *buf, ulong event_len,
7017 int body_offset,
7018 const Format_description_log_event *description_event)
7019{
7020 DBUG_ENTER("Load_log_event::copy_log_event");
7021 uint data_len;
7022 char* buf_end = (char*)buf + event_len;
7023 /* this is the beginning of the post-header */
7024 const char* data_head = buf + description_event->common_header_len;
7025 thread_id= slave_proxy_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
7026 exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
7027 skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
7028 table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
7029 db_len = (uint)data_head[L_DB_LEN_OFFSET];
7030 num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
7031
7032 if ((int) event_len < body_offset)
7033 DBUG_RETURN(1);
7034 /*
7035 Sql_ex.init() on success returns the pointer to the first byte after
7036 the sql_ex structure, which is the start of field lengths array.
7037 */
7038 if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
7039 buf_end,
7040 (uchar)buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
7041 DBUG_RETURN(1);
7042
7043 data_len = event_len - body_offset;
7044 if (num_fields > data_len) // simple sanity check against corruption
7045 DBUG_RETURN(1);
7046 for (uint i = 0; i < num_fields; i++)
7047 field_block_len += (uint)field_lens[i] + 1;
7048
7049 fields = (char*)field_lens + num_fields;
7050 table_name = fields + field_block_len;
7051 if (strlen(table_name) > NAME_LEN)
7052 goto err;
7053
7054 db = table_name + table_name_len + 1;
7055 DBUG_EXECUTE_IF ("simulate_invalid_address",
7056 db_len = data_len;);
7057 fname = db + db_len + 1;
7058 if ((db_len > data_len) || (fname > buf_end))
7059 goto err;
7060 fname_len = (uint) strlen(fname);
7061 if ((fname_len > data_len) || (fname + fname_len > buf_end))
7062 goto err;
7063 // null termination is accomplished by the caller doing buf[event_len]=0
7064
7065 DBUG_RETURN(0);
7066
7067err:
7068 // Invalid event.
7069 table_name = 0;
7070 DBUG_RETURN(1);
7071}
7072
7073
7074/*
7075 Load_log_event::print()
7076*/
7077
7078#ifdef MYSQL_CLIENT
7079bool Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7080{
7081 return print(file, print_event_info, 0);
7082}
7083
7084
7085bool Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
7086 bool commented)
7087{
7088 Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
7089 bool different_db= 1;
7090 DBUG_ENTER("Load_log_event::print");
7091
7092 if (!print_event_info->short_form)
7093 {
7094 if (print_header(&cache, print_event_info, FALSE) ||
7095 my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
7096 thread_id, exec_time))
7097 goto err;
7098 }
7099
7100 if (db)
7101 {
7102 /*
7103 If the database is different from the one of the previous statement, we
7104 need to print the "use" command, and we update the last_db.
7105 But if commented, the "use" is going to be commented so we should not
7106 update the last_db.
7107 */
7108 if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
7109 !commented)
7110 memcpy(print_event_info->db, db, db_len + 1);
7111 }
7112
7113 if (db && db[0] && different_db)
7114 if (my_b_printf(&cache, "%suse %`s%s\n",
7115 commented ? "# " : "",
7116 db, print_event_info->delimiter))
7117 goto err;
7118
7119 if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
7120 if (my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
7121 commented ? "# " : "", (ulong)thread_id,
7122 print_event_info->delimiter))
7123 goto err;
7124 if (my_b_printf(&cache, "%sLOAD DATA ",
7125 commented ? "# " : ""))
7126 goto err;
7127 if (check_fname_outside_temp_buf())
7128 if (my_b_write_string(&cache, "LOCAL "))
7129 goto err;
7130 if (my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname))
7131 goto err;
7132
7133 if (sql_ex.opt_flags & REPLACE_FLAG)
7134 {
7135 if (my_b_write_string(&cache, "REPLACE "))
7136 goto err;
7137 }
7138 else if (sql_ex.opt_flags & IGNORE_FLAG)
7139 if (my_b_write_string(&cache, "IGNORE "))
7140 goto err;
7141
7142 if (my_b_printf(&cache, "INTO TABLE `%s`", table_name) ||
7143 my_b_write_string(&cache, " FIELDS TERMINATED BY ") ||
7144 pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len))
7145 goto err;
7146
7147 if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
7148 if (my_b_write_string(&cache, " OPTIONALLY "))
7149 goto err;
7150 if (my_b_write_string(&cache, " ENCLOSED BY ") ||
7151 pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len) ||
7152 my_b_write_string(&cache, " ESCAPED BY ") ||
7153 pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len) ||
7154 my_b_write_string(&cache, " LINES TERMINATED BY ") ||
7155 pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len))
7156 goto err;
7157
7158 if (sql_ex.line_start)
7159 {
7160 if (my_b_write_string(&cache," STARTING BY ") ||
7161 pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len))
7162 goto err;
7163 }
7164 if ((long) skip_lines > 0)
7165 if (my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines))
7166 goto err;
7167
7168 if (num_fields)
7169 {
7170 uint i;
7171 const char* field = fields;
7172 if (my_b_write_string(&cache, " ("))
7173 goto err;
7174 for (i = 0; i < num_fields; i++)
7175 {
7176 if (i)
7177 if (my_b_write_byte(&cache, ','))
7178 goto err;
7179 if (my_b_printf(&cache, "%`s", field))
7180 goto err;
7181 field += field_lens[i] + 1;
7182 }
7183 if (my_b_write_byte(&cache, ')'))
7184 goto err;
7185 }
7186
7187 if (my_b_printf(&cache, "%s\n", print_event_info->delimiter))
7188 goto err;
7189 DBUG_RETURN(cache.flush_data());
7190err:
7191 DBUG_RETURN(1);
7192}
7193#endif /* MYSQL_CLIENT */
7194
7195#ifndef MYSQL_CLIENT
7196
7197/**
7198 Load_log_event::set_fields()
7199
7200 @note
7201 This function can not use the member variable
7202 for the database, since LOAD DATA INFILE on the slave
7203 can be for a different database than the current one.
7204 This is the reason for the affected_db argument to this method.
7205*/
7206
7207void Load_log_event::set_fields(const char* affected_db,
7208 List<Item> &field_list,
7209 Name_resolution_context *context)
7210{
7211 uint i;
7212 const char* field = fields;
7213 for (i= 0; i < num_fields; i++)
7214 {
7215 LEX_CSTRING field_name= {field, field_lens[i] };
7216 field_list.push_back(new (thd->mem_root)
7217 Item_field(thd, context, affected_db, table_name,
7218 &field_name),
7219 thd->mem_root);
7220 field+= field_lens[i] + 1;
7221 }
7222}
7223#endif /* !MYSQL_CLIENT */
7224
7225
7226#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7227/**
7228 Does the data loading job when executing a LOAD DATA on the slave.
7229
7230 @param net
7231 @param rli
7232 @param use_rli_only_for_errors If set to 1, rli is provided to
7233 Load_log_event::exec_event only for this
7234 function to have RPL_LOG_NAME and
7235 rli->last_slave_error, both being used by
7236 error reports. rli's position advancing
7237 is skipped (done by the caller which is
7238 Execute_load_log_event::exec_event).
7239 If set to 0, rli is provided for full use,
7240 i.e. for error reports and position
7241 advancing.
7242
7243 @todo
7244 fix this; this can be done by testing rules in
7245 Create_file_log_event::exec_event() and then discarding Append_block and
7246 al.
7247 @todo
7248 this is a bug - this needs to be moved to the I/O thread
7249
7250 @retval
7251 0 Success
7252 @retval
7253 1 Failure
7254*/
7255
7256int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
7257 bool use_rli_only_for_errors)
7258{
7259 LEX_CSTRING new_db;
7260 Relay_log_info const *rli= rgi->rli;
7261 Rpl_filter *rpl_filter= rli->mi->rpl_filter;
7262 DBUG_ENTER("Load_log_event::do_apply_event");
7263
7264 new_db.length= db_len;
7265 new_db.str= rpl_filter->get_rewrite_db(db, &new_db.length);
7266 thd->set_db(&new_db);
7267 DBUG_ASSERT(thd->query() == 0);
7268 thd->clear_error(1);
7269
7270 /* see Query_log_event::do_apply_event() and BUG#13360 */
7271 DBUG_ASSERT(!rgi->m_table_map.count());
7272 /*
7273 Usually lex_start() is called by mysql_parse(), but we need it here
7274 as the present method does not call mysql_parse().
7275 */
7276 lex_start(thd);
7277 thd->lex->local_file= local_fname;
7278 thd->reset_for_next_command(0); // Errors are cleared above
7279
7280 /*
7281 We test replicate_*_db rules. Note that we have already prepared
7282 the file to load, even if we are going to ignore and delete it
7283 now. So it is possible that we did a lot of disk writes for
7284 nothing. In other words, a big LOAD DATA INFILE on the master will
7285 still consume a lot of space on the slave (space in the relay log
7286 + space of temp files: twice the space of the file to load...)
7287 even if it will finally be ignored. TODO: fix this; this can be
7288 done by testing rules in Create_file_log_event::do_apply_event()
7289 and then discarding Append_block and al. Another way is do the
7290 filtering in the I/O thread (more efficient: no disk writes at
7291 all).
7292
7293
7294 Note: We do not need to execute reset_one_shot_variables() if this
7295 db_ok() test fails.
7296 Reason: The db stored in binlog events is the same for SET and for
7297 its companion query. If the SET is ignored because of
7298 db_ok(), the companion query will also be ignored, and if
7299 the companion query is ignored in the db_ok() test of
7300 ::do_apply_event(), then the companion SET also have so
7301 we don't need to reset_one_shot_variables().
7302 */
7303 if (rpl_filter->db_ok(thd->db.str))
7304 {
7305 thd->set_time(when, when_sec_part);
7306 thd->set_query_id(next_query_id());
7307 thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
7308
7309 TABLE_LIST tables;
7310 LEX_CSTRING db_name= { thd->strmake(thd->db.str, thd->db.length), thd->db.length };
7311 LEX_CSTRING tbl_name= { table_name, strlen(table_name) };
7312 tables.init_one_table(&db_name, &tbl_name, 0, TL_WRITE);
7313 tables.updating= 1;
7314
7315 // the table will be opened in mysql_load
7316 if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db.str, &tables))
7317 {
7318 // TODO: this is a bug - this needs to be moved to the I/O thread
7319 if (net)
7320 skip_load_data_infile(net);
7321 }
7322 else
7323 {
7324 enum enum_duplicates handle_dup;
7325 bool ignore= 0;
7326 char query_buffer[1024];
7327 String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
7328 char *load_data_query;
7329
7330 query_str.length(0);
7331 /*
7332 Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
7333 and written to slave's binlog if binlogging is on.
7334 */
7335 print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
7336 if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
7337 query_str.length())))
7338 {
7339 /*
7340 This will set thd->fatal_error in case of OOM. So we surely will notice
7341 that something is wrong.
7342 */
7343 goto error;
7344 }
7345
7346 thd->set_query(load_data_query, (uint) (query_str.length()));
7347
7348 if (sql_ex.opt_flags & REPLACE_FLAG)
7349 handle_dup= DUP_REPLACE;
7350 else if (sql_ex.opt_flags & IGNORE_FLAG)
7351 {
7352 ignore= 1;
7353 handle_dup= DUP_ERROR;
7354 }
7355 else
7356 {
7357 /*
7358 When replication is running fine, if it was DUP_ERROR on the
7359 master then we could choose IGNORE here, because if DUP_ERROR
7360 suceeded on master, and data is identical on the master and slave,
7361 then there should be no uniqueness errors on slave, so IGNORE is
7362 the same as DUP_ERROR. But in the unlikely case of uniqueness errors
7363 (because the data on the master and slave happen to be different
7364 (user error or bug), we want LOAD DATA to print an error message on
7365 the slave to discover the problem.
7366
7367 If reading from net (a 3.23 master), mysql_load() will change this
7368 to IGNORE.
7369 */
7370 handle_dup= DUP_ERROR;
7371 }
7372 /*
7373 We need to set thd->lex->sql_command and thd->lex->duplicates
7374 since InnoDB tests these variables to decide if this is a LOAD
7375 DATA ... REPLACE INTO ... statement even though mysql_parse()
7376 is not called. This is not needed in 5.0 since there the LOAD
7377 DATA ... statement is replicated using mysql_parse(), which
7378 sets the thd->lex fields correctly.
7379 */
7380 thd->lex->sql_command= SQLCOM_LOAD;
7381 thd->lex->duplicates= handle_dup;
7382
7383 sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
7384 String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
7385 String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
7386 String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
7387 String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
7388 String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
7389 ex.field_term= &field_term;
7390 ex.enclosed= &enclosed;
7391 ex.line_term= &line_term;
7392 ex.line_start= &line_start;
7393 ex.escaped= &escaped;
7394
7395 ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
7396 if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
7397 ex.field_term->length(0);
7398
7399 ex.skip_lines = skip_lines;
7400 List<Item> field_list;
7401 thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
7402 set_fields(tables.db.str, field_list, &thd->lex->select_lex.context);
7403 thd->variables.pseudo_thread_id= thread_id;
7404 if (net)
7405 {
7406 // mysql_load will use thd->net to read the file
7407 thd->net.vio = net->vio;
7408 // Make sure the client does not get confused about the packet sequence
7409 thd->net.pkt_nr = net->pkt_nr;
7410 }
7411 /*
7412 It is safe to use tmp_list twice because we are not going to
7413 update it inside mysql_load().
7414 */
7415 List<Item> tmp_list;
7416 if (thd->open_temporary_tables(&tables) ||
7417 mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
7418 handle_dup, ignore, net != 0))
7419 thd->is_slave_error= 1;
7420 if (thd->cuted_fields)
7421 {
7422 /* log_pos is the position of the LOAD event in the master log */
7423 sql_print_warning("Slave: load data infile on table '%s' at "
7424 "log position %llu in log '%s' produced %ld "
7425 "warning(s). Default database: '%s'",
7426 (char*) table_name, log_pos, RPL_LOG_NAME,
7427 (ulong) thd->cuted_fields,
7428 thd->get_db());
7429 }
7430 if (net)
7431 net->pkt_nr= thd->net.pkt_nr;
7432 }
7433 }
7434 else
7435 {
7436 /*
7437 We will just ask the master to send us /dev/null if we do not
7438 want to load the data.
7439 TODO: this a bug - needs to be done in I/O thread
7440 */
7441 if (net)
7442 skip_load_data_infile(net);
7443 }
7444
7445error:
7446 thd->net.vio = 0;
7447 const char *remember_db= thd->get_db();
7448 thd->catalog= 0;
7449 thd->set_db(&null_clex_str); /* will free the current database */
7450 thd->reset_query();
7451 thd->get_stmt_da()->set_overwrite_status(true);
7452 thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
7453 thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN);
7454 thd->get_stmt_da()->set_overwrite_status(false);
7455 close_thread_tables(thd);
7456 /*
7457 - If transaction rollback was requested due to deadlock
7458 perform it and release metadata locks.
7459 - If inside a multi-statement transaction,
7460 defer the release of metadata locks until the current
7461 transaction is either committed or rolled back. This prevents
7462 other statements from modifying the table for the entire
7463 duration of this transaction. This provides commit ordering
7464 and guarantees serializability across multiple transactions.
7465 - If in autocommit mode, or outside a transactional context,
7466 automatically release metadata locks of the current statement.
7467 */
7468 if (thd->transaction_rollback_request)
7469 {
7470 trans_rollback_implicit(thd);
7471 thd->mdl_context.release_transactional_locks();
7472 }
7473 else if (! thd->in_multi_stmt_transaction_mode())
7474 thd->mdl_context.release_transactional_locks();
7475 else
7476 thd->mdl_context.release_statement_locks();
7477
7478 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
7479 thd->is_slave_error= 0; thd->is_fatal_error= 1;);
7480
7481 if (unlikely(thd->is_slave_error))
7482 {
7483 /* this err/sql_errno code is copy-paste from net_send_error() */
7484 const char *err;
7485 int sql_errno;
7486 if (thd->is_error())
7487 {
7488 err= thd->get_stmt_da()->message();
7489 sql_errno= thd->get_stmt_da()->sql_errno();
7490 }
7491 else
7492 {
7493 sql_errno=ER_UNKNOWN_ERROR;
7494 err= ER_THD(thd, sql_errno);
7495 }
7496 rli->report(ERROR_LEVEL, sql_errno, rgi->gtid_info(), "\
7497Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
7498 err, (char*)table_name, remember_db);
7499 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
7500 DBUG_RETURN(1);
7501 }
7502 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
7503
7504 if (unlikely(thd->is_fatal_error))
7505 {
7506 char buf[256];
7507 my_snprintf(buf, sizeof(buf),
7508 "Running LOAD DATA INFILE on table '%-.64s'."
7509 " Default database: '%-.64s'",
7510 (char*)table_name,
7511 remember_db);
7512
7513 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(),
7514 ER_THD(thd, ER_SLAVE_FATAL_ERROR), buf);
7515 DBUG_RETURN(1);
7516 }
7517
7518 DBUG_RETURN( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rgi) );
7519}
7520#endif
7521
7522
7523/**************************************************************************
7524 Rotate_log_event methods
7525**************************************************************************/
7526
7527/*
7528 Rotate_log_event::pack_info()
7529*/
7530
7531#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7532void Rotate_log_event::pack_info(Protocol *protocol)
7533{
7534 StringBuffer<256> tmp(log_cs);
7535 tmp.length(0);
7536 tmp.append(new_log_ident, ident_len);
7537 tmp.append(STRING_WITH_LEN(";pos="));
7538 tmp.append_ulonglong(pos);
7539 protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
7540}
7541#endif
7542
7543
7544/*
7545 Rotate_log_event::print()
7546*/
7547
7548#ifdef MYSQL_CLIENT
7549bool Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7550{
7551 if (print_event_info->short_form)
7552 return 0;
7553
7554 char buf[22];
7555 Write_on_release_cache cache(&print_event_info->head_cache, file,
7556 Write_on_release_cache::FLUSH_F);
7557 if (print_header(&cache, print_event_info, FALSE) ||
7558 my_b_write_string(&cache, "\tRotate to "))
7559 goto err;
7560 if (new_log_ident)
7561 if (my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len))
7562 goto err;
7563 if (my_b_printf(&cache, " pos: %s\n", llstr(pos, buf)))
7564 goto err;
7565 return cache.flush_data();
7566err:
7567 return 1;
7568}
7569#endif /* MYSQL_CLIENT */
7570
7571
7572
7573/*
7574 Rotate_log_event::Rotate_log_event() (2 constructors)
7575*/
7576
7577
7578#ifndef MYSQL_CLIENT
7579Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
7580 uint ident_len_arg, ulonglong pos_arg,
7581 uint flags_arg)
7582 :Log_event(), new_log_ident(new_log_ident_arg),
7583 pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
7584 (uint) strlen(new_log_ident_arg)), flags(flags_arg)
7585{
7586 DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
7587 DBUG_PRINT("enter",("new_log_ident: %s pos: %llu flags: %lu", new_log_ident_arg,
7588 pos_arg, (ulong) flags));
7589 cache_type= EVENT_NO_CACHE;
7590 if (flags & DUP_NAME)
7591 new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
7592 if (flags & RELAY_LOG)
7593 set_relay_log_event();
7594 DBUG_VOID_RETURN;
7595}
7596#endif
7597
7598
7599Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
7600 const Format_description_log_event* description_event)
7601 :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
7602{
7603 DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
7604 // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
7605 uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
7606 uint ident_offset;
7607 if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN)
7608 DBUG_VOID_RETURN;
7609 buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
7610 pos= post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
7611 ident_len= (uint)(event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + post_header_len));
7612 ident_offset= post_header_len;
7613 set_if_smaller(ident_len,FN_REFLEN-1);
7614 new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
7615 DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
7616 DBUG_VOID_RETURN;
7617}
7618
7619
7620/*
7621 Rotate_log_event::write()
7622*/
7623
7624#ifndef MYSQL_CLIENT
7625bool Rotate_log_event::write()
7626{
7627 char buf[ROTATE_HEADER_LEN];
7628 int8store(buf + R_POS_OFFSET, pos);
7629 return (write_header(ROTATE_HEADER_LEN + ident_len) ||
7630 write_data(buf, ROTATE_HEADER_LEN) ||
7631 write_data(new_log_ident, (uint) ident_len) ||
7632 write_footer());
7633}
7634#endif
7635
7636
7637#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7638
7639/*
7640 Got a rotate log event from the master.
7641
7642 This is mainly used so that we can later figure out the logname and
7643 position for the master.
7644
7645 We can't rotate the slave's BINlog as this will cause infinitive rotations
7646 in a A -> B -> A setup.
7647 The NOTES below is a wrong comment which will disappear when 4.1 is merged.
7648
7649 This must only be called from the Slave SQL thread, since it calls
7650 Relay_log_info::flush().
7651
7652 @retval
7653 0 ok
7654 1 error
7655*/
7656int Rotate_log_event::do_update_pos(rpl_group_info *rgi)
7657{
7658 int error= 0;
7659 Relay_log_info *rli= rgi->rli;
7660 DBUG_ENTER("Rotate_log_event::do_update_pos");
7661
7662 DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
7663 (ulong) this->server_id, (ulong) global_system_variables.server_id));
7664 DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
7665 DBUG_PRINT("info", ("pos: %llu", this->pos));
7666
7667 /*
7668 If we are in a transaction or in a group: the only normal case is
7669 when the I/O thread was copying a big transaction, then it was
7670 stopped and restarted: we have this in the relay log:
7671
7672 BEGIN
7673 ...
7674 ROTATE (a fake one)
7675 ...
7676 COMMIT or ROLLBACK
7677
7678 In that case, we don't want to touch the coordinates which
7679 correspond to the beginning of the transaction. Starting from
7680 5.0.0, there also are some rotates from the slave itself, in the
7681 relay log, which shall not change the group positions.
7682
7683 In parallel replication, rotate event is executed out-of-band with normal
7684 events, so we cannot update group_master_log_name or _pos here, it will
7685 be updated with the next normal event instead.
7686 */
7687 if ((server_id != global_system_variables.server_id ||
7688 rli->replicate_same_server_id) &&
7689 !is_relay_log_event() &&
7690 !rli->is_in_group() &&
7691 !rgi->is_parallel_exec)
7692 {
7693 mysql_mutex_lock(&rli->data_lock);
7694 DBUG_PRINT("info", ("old group_master_log_name: '%s' "
7695 "old group_master_log_pos: %lu",
7696 rli->group_master_log_name,
7697 (ulong) rli->group_master_log_pos));
7698 memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
7699 rli->notify_group_master_log_name_update();
7700 rli->inc_group_relay_log_pos(pos, rgi, TRUE /* skip_lock */);
7701 DBUG_PRINT("info", ("new group_master_log_name: '%s' "
7702 "new group_master_log_pos: %lu",
7703 rli->group_master_log_name,
7704 (ulong) rli->group_master_log_pos));
7705 mysql_mutex_unlock(&rli->data_lock);
7706 rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
7707 error= rli->flush();
7708
7709 /*
7710 Reset thd->variables.option_bits and sql_mode etc, because this could
7711 be the signal of a master's downgrade from 5.0 to 4.0.
7712 However, no need to reset description_event_for_exec: indeed, if the next
7713 master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
7714 master is 4.0 then the events are in the slave's format (conversion).
7715 */
7716 set_slave_thread_options(thd);
7717 set_slave_thread_default_charset(thd, rgi);
7718 thd->variables.sql_mode= global_system_variables.sql_mode;
7719 thd->variables.auto_increment_increment=
7720 thd->variables.auto_increment_offset= 1;
7721 }
7722 else
7723 rgi->inc_event_relay_log_pos();
7724
7725 DBUG_RETURN(error);
7726}
7727
7728
7729Log_event::enum_skip_reason
7730Rotate_log_event::do_shall_skip(rpl_group_info *rgi)
7731{
7732 enum_skip_reason reason= Log_event::do_shall_skip(rgi);
7733
7734 switch (reason) {
7735 case Log_event::EVENT_SKIP_NOT:
7736 case Log_event::EVENT_SKIP_COUNT:
7737 return Log_event::EVENT_SKIP_NOT;
7738
7739 case Log_event::EVENT_SKIP_IGNORE:
7740 return Log_event::EVENT_SKIP_IGNORE;
7741 }
7742 DBUG_ASSERT(0);
7743 return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
7744}
7745
7746#endif
7747
7748
7749/**************************************************************************
7750 Binlog_checkpoint_log_event methods
7751**************************************************************************/
7752
7753#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7754void Binlog_checkpoint_log_event::pack_info(Protocol *protocol)
7755{
7756 protocol->store(binlog_file_name, binlog_file_len, &my_charset_bin);
7757}
7758
7759
7760Log_event::enum_skip_reason
7761Binlog_checkpoint_log_event::do_shall_skip(rpl_group_info *rgi)
7762{
7763 enum_skip_reason reason= Log_event::do_shall_skip(rgi);
7764 if (reason == EVENT_SKIP_COUNT)
7765 reason= EVENT_SKIP_NOT;
7766 return reason;
7767}
7768#endif
7769
7770
7771#ifdef MYSQL_CLIENT
7772bool Binlog_checkpoint_log_event::print(FILE *file,
7773 PRINT_EVENT_INFO *print_event_info)
7774{
7775 if (print_event_info->short_form)
7776 return 0;
7777
7778 Write_on_release_cache cache(&print_event_info->head_cache, file,
7779 Write_on_release_cache::FLUSH_F);
7780
7781 if (print_header(&cache, print_event_info, FALSE) ||
7782 my_b_write_string(&cache, "\tBinlog checkpoint ") ||
7783 my_b_write(&cache, (uchar*)binlog_file_name, binlog_file_len) ||
7784 my_b_write_byte(&cache, '\n'))
7785 return 1;
7786 return cache.flush_data();
7787}
7788#endif /* MYSQL_CLIENT */
7789
7790
7791#ifdef MYSQL_SERVER
7792Binlog_checkpoint_log_event::Binlog_checkpoint_log_event(
7793 const char *binlog_file_name_arg,
7794 uint binlog_file_len_arg)
7795 :Log_event(),
7796 binlog_file_name(my_strndup(binlog_file_name_arg, binlog_file_len_arg,
7797 MYF(MY_WME))),
7798 binlog_file_len(binlog_file_len_arg)
7799{
7800 cache_type= EVENT_NO_CACHE;
7801}
7802#endif /* MYSQL_SERVER */
7803
7804
7805Binlog_checkpoint_log_event::Binlog_checkpoint_log_event(
7806 const char *buf, uint event_len,
7807 const Format_description_log_event *description_event)
7808 :Log_event(buf, description_event), binlog_file_name(0)
7809{
7810 uint8 header_size= description_event->common_header_len;
7811 uint8 post_header_len=
7812 description_event->post_header_len[BINLOG_CHECKPOINT_EVENT-1];
7813 if (event_len < (uint) header_size + (uint) post_header_len ||
7814 post_header_len < BINLOG_CHECKPOINT_HEADER_LEN)
7815 return;
7816 buf+= header_size;
7817 /* See uint4korr and int4store below */
7818 compile_time_assert(BINLOG_CHECKPOINT_HEADER_LEN == 4);
7819 binlog_file_len= uint4korr(buf);
7820 if (event_len - (header_size + post_header_len) < binlog_file_len)
7821 return;
7822 binlog_file_name= my_strndup(buf + post_header_len, binlog_file_len,
7823 MYF(MY_WME));
7824 return;
7825}
7826
7827
7828#ifndef MYSQL_CLIENT
7829bool Binlog_checkpoint_log_event::write()
7830{
7831 uchar buf[BINLOG_CHECKPOINT_HEADER_LEN];
7832 int4store(buf, binlog_file_len);
7833 return write_header(BINLOG_CHECKPOINT_HEADER_LEN + binlog_file_len) ||
7834 write_data(buf, BINLOG_CHECKPOINT_HEADER_LEN) ||
7835 write_data(binlog_file_name, binlog_file_len) ||
7836 write_footer();
7837}
7838#endif /* MYSQL_CLIENT */
7839
7840
7841/**************************************************************************
7842 Global transaction ID stuff
7843**************************************************************************/
7844
7845Gtid_log_event::Gtid_log_event(const char *buf, uint event_len,
7846 const Format_description_log_event *description_event)
7847 : Log_event(buf, description_event), seq_no(0), commit_id(0)
7848{
7849 uint8 header_size= description_event->common_header_len;
7850 uint8 post_header_len= description_event->post_header_len[GTID_EVENT-1];
7851 if (event_len < (uint) header_size + (uint) post_header_len ||
7852 post_header_len < GTID_HEADER_LEN)
7853 return;
7854
7855 buf+= header_size;
7856 seq_no= uint8korr(buf);
7857 buf+= 8;
7858 domain_id= uint4korr(buf);
7859 buf+= 4;
7860 flags2= *buf;
7861 if (flags2 & FL_GROUP_COMMIT_ID)
7862 {
7863 if (event_len < (uint)header_size + GTID_HEADER_LEN + 2)
7864 {
7865 seq_no= 0; // So is_valid() returns false
7866 return;
7867 }
7868 ++buf;
7869 commit_id= uint8korr(buf);
7870 }
7871}
7872
7873
7874#ifdef MYSQL_SERVER
7875
7876Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg,
7877 uint32 domain_id_arg, bool standalone,
7878 uint16 flags_arg, bool is_transactional,
7879 uint64 commit_id_arg)
7880 : Log_event(thd_arg, flags_arg, is_transactional),
7881 seq_no(seq_no_arg), commit_id(commit_id_arg), domain_id(domain_id_arg),
7882 flags2((standalone ? FL_STANDALONE : 0) | (commit_id_arg ? FL_GROUP_COMMIT_ID : 0))
7883{
7884 cache_type= Log_event::EVENT_NO_CACHE;
7885 if (thd_arg->transaction.stmt.trans_did_wait() ||
7886 thd_arg->transaction.all.trans_did_wait())
7887 flags2|= FL_WAITED;
7888 if (thd_arg->transaction.stmt.trans_did_ddl() ||
7889 thd_arg->transaction.stmt.has_created_dropped_temp_table() ||
7890 thd_arg->transaction.all.trans_did_ddl() ||
7891 thd_arg->transaction.all.has_created_dropped_temp_table())
7892 flags2|= FL_DDL;
7893 else if (is_transactional)
7894 flags2|= FL_TRANSACTIONAL;
7895 if (!(thd_arg->variables.option_bits & OPTION_RPL_SKIP_PARALLEL))
7896 flags2|= FL_ALLOW_PARALLEL;
7897 /* Preserve any DDL or WAITED flag in the slave's binlog. */
7898 if (thd_arg->rgi_slave)
7899 flags2|= (thd_arg->rgi_slave->gtid_ev_flags2 & (FL_DDL|FL_WAITED));
7900}
7901
7902
7903/*
7904 Used to record GTID while sending binlog to slave, without having to
7905 fully contruct every Gtid_log_event() needlessly.
7906*/
7907bool
7908Gtid_log_event::peek(const char *event_start, size_t event_len,
7909 enum enum_binlog_checksum_alg checksum_alg,
7910 uint32 *domain_id, uint32 *server_id, uint64 *seq_no,
7911 uchar *flags2, const Format_description_log_event *fdev)
7912{
7913 const char *p;
7914
7915 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
7916 {
7917 if (event_len > BINLOG_CHECKSUM_LEN)
7918 event_len-= BINLOG_CHECKSUM_LEN;
7919 else
7920 event_len= 0;
7921 }
7922 else
7923 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
7924 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
7925
7926 if (event_len < (uint32)fdev->common_header_len + GTID_HEADER_LEN)
7927 return true;
7928 *server_id= uint4korr(event_start + SERVER_ID_OFFSET);
7929 p= event_start + fdev->common_header_len;
7930 *seq_no= uint8korr(p);
7931 p+= 8;
7932 *domain_id= uint4korr(p);
7933 p+= 4;
7934 *flags2= (uchar)*p;
7935 return false;
7936}
7937
7938
7939bool
7940Gtid_log_event::write()
7941{
7942 uchar buf[GTID_HEADER_LEN+2];
7943 size_t write_len;
7944
7945 int8store(buf, seq_no);
7946 int4store(buf+8, domain_id);
7947 buf[12]= flags2;
7948 if (flags2 & FL_GROUP_COMMIT_ID)
7949 {
7950 int8store(buf+13, commit_id);
7951 write_len= GTID_HEADER_LEN + 2;
7952 }
7953 else
7954 {
7955 bzero(buf+13, GTID_HEADER_LEN-13);
7956 write_len= GTID_HEADER_LEN;
7957 }
7958 return write_header(write_len) ||
7959 write_data(buf, write_len) ||
7960 write_footer();
7961}
7962
7963
7964/*
7965 Replace a GTID event with either a BEGIN event, dummy event, or nothing, as
7966 appropriate to work with old slave that does not know global transaction id.
7967
7968 The need_dummy_event argument is an IN/OUT argument. It is passed as TRUE
7969 if slave has capability lower than MARIA_SLAVE_CAPABILITY_TOLERATE_HOLES.
7970 It is returned TRUE if we return a BEGIN (or dummy) event to be sent to the
7971 slave, FALSE if event should be skipped completely.
7972*/
7973int
7974Gtid_log_event::make_compatible_event(String *packet, bool *need_dummy_event,
7975 ulong ev_offset,
7976 enum enum_binlog_checksum_alg checksum_alg)
7977{
7978 uchar flags2;
7979 if (packet->length() - ev_offset < LOG_EVENT_HEADER_LEN + GTID_HEADER_LEN)
7980 return 1;
7981 flags2= (*packet)[ev_offset + LOG_EVENT_HEADER_LEN + 12];
7982 if (flags2 & FL_STANDALONE)
7983 {
7984 if (*need_dummy_event)
7985 return Query_log_event::dummy_event(packet, ev_offset, checksum_alg);
7986 return 0;
7987 }
7988
7989 *need_dummy_event= true;
7990 return Query_log_event::begin_event(packet, ev_offset, checksum_alg);
7991}
7992
7993
7994#ifdef HAVE_REPLICATION
7995void
7996Gtid_log_event::pack_info(Protocol *protocol)
7997{
7998 char buf[6+5+10+1+10+1+20+1+4+20+1];
7999 char *p;
8000 p = strmov(buf, (flags2 & FL_STANDALONE ? "GTID " : "BEGIN GTID "));
8001 p= longlong10_to_str(domain_id, p, 10);
8002 *p++= '-';
8003 p= longlong10_to_str(server_id, p, 10);
8004 *p++= '-';
8005 p= longlong10_to_str(seq_no, p, 10);
8006 if (flags2 & FL_GROUP_COMMIT_ID)
8007 {
8008 p= strmov(p, " cid=");
8009 p= longlong10_to_str(commit_id, p, 10);
8010 }
8011
8012 protocol->store(buf, p-buf, &my_charset_bin);
8013}
8014
8015static char gtid_begin_string[] = "BEGIN";
8016
8017int
8018Gtid_log_event::do_apply_event(rpl_group_info *rgi)
8019{
8020 ulonglong bits= thd->variables.option_bits;
8021 thd->variables.server_id= this->server_id;
8022 thd->variables.gtid_domain_id= this->domain_id;
8023 thd->variables.gtid_seq_no= this->seq_no;
8024 rgi->gtid_ev_flags2= flags2;
8025 thd->reset_for_next_command();
8026
8027 if (opt_gtid_strict_mode && opt_bin_log && opt_log_slave_updates)
8028 {
8029 if (mysql_bin_log.check_strict_gtid_sequence(this->domain_id,
8030 this->server_id, this->seq_no))
8031 return 1;
8032 }
8033
8034 DBUG_ASSERT((bits & OPTION_GTID_BEGIN) == 0);
8035
8036 Master_info *mi=rgi->rli->mi;
8037 switch (flags2 & (FL_DDL | FL_TRANSACTIONAL))
8038 {
8039 case FL_TRANSACTIONAL:
8040 my_atomic_add64_explicit((volatile int64 *)&mi->total_trans_groups, 1,
8041 MY_MEMORY_ORDER_RELAXED);
8042 break;
8043 case FL_DDL:
8044 my_atomic_add64_explicit((volatile int64 *)&mi->total_ddl_groups, 1,
8045 MY_MEMORY_ORDER_RELAXED);
8046 break;
8047 default:
8048 my_atomic_add64_explicit((volatile int64 *)&mi->total_non_trans_groups, 1,
8049 MY_MEMORY_ORDER_RELAXED);
8050 }
8051
8052 if (flags2 & FL_STANDALONE)
8053 return 0;
8054
8055 /* Execute this like a BEGIN query event. */
8056 bits|= OPTION_GTID_BEGIN;
8057 if (flags2 & FL_ALLOW_PARALLEL)
8058 bits&= ~(ulonglong)OPTION_RPL_SKIP_PARALLEL;
8059 else
8060 bits|= (ulonglong)OPTION_RPL_SKIP_PARALLEL;
8061 thd->variables.option_bits= bits;
8062 DBUG_PRINT("info", ("Set OPTION_GTID_BEGIN"));
8063 thd->set_query_and_id(gtid_begin_string, sizeof(gtid_begin_string)-1,
8064 &my_charset_bin, next_query_id());
8065 thd->lex->sql_command= SQLCOM_BEGIN;
8066 thd->is_slave_error= 0;
8067 status_var_increment(thd->status_var.com_stat[thd->lex->sql_command]);
8068 if (trans_begin(thd, 0))
8069 {
8070 DBUG_PRINT("error", ("trans_begin() failed"));
8071 thd->is_slave_error= 1;
8072 }
8073 thd->update_stats();
8074
8075 if (likely(!thd->is_slave_error))
8076 general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
8077
8078 thd->reset_query();
8079 free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
8080 return thd->is_slave_error;
8081}
8082
8083
8084int
8085Gtid_log_event::do_update_pos(rpl_group_info *rgi)
8086{
8087 rgi->inc_event_relay_log_pos();
8088 return 0;
8089}
8090
8091
8092Log_event::enum_skip_reason
8093Gtid_log_event::do_shall_skip(rpl_group_info *rgi)
8094{
8095 Relay_log_info *rli= rgi->rli;
8096 /*
8097 An event skipped due to @@skip_replication must not be counted towards the
8098 number of events to be skipped due to @@sql_slave_skip_counter.
8099 */
8100 if (flags & LOG_EVENT_SKIP_REPLICATION_F &&
8101 opt_replicate_events_marked_for_skip != RPL_SKIP_REPLICATE)
8102 return Log_event::EVENT_SKIP_IGNORE;
8103
8104 if (rli->slave_skip_counter > 0)
8105 {
8106 if (!(flags2 & FL_STANDALONE))
8107 {
8108 thd->variables.option_bits|= OPTION_BEGIN;
8109 DBUG_ASSERT(rgi->rli->get_flag(Relay_log_info::IN_TRANSACTION));
8110 }
8111 return Log_event::continue_group(rgi);
8112 }
8113 return Log_event::do_shall_skip(rgi);
8114}
8115
8116
8117#endif /* HAVE_REPLICATION */
8118
8119#else /* !MYSQL_SERVER */
8120
8121bool
8122Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
8123{
8124 Write_on_release_cache cache(&print_event_info->head_cache, file,
8125 Write_on_release_cache::FLUSH_F, this);
8126 char buf[21];
8127 char buf2[21];
8128
8129 if (!print_event_info->short_form && !is_flashback)
8130 {
8131 print_header(&cache, print_event_info, FALSE);
8132 longlong10_to_str(seq_no, buf, 10);
8133 if (my_b_printf(&cache, "\tGTID %u-%u-%s", domain_id, server_id, buf))
8134 goto err;
8135 if (flags2 & FL_GROUP_COMMIT_ID)
8136 {
8137 longlong10_to_str(commit_id, buf2, 10);
8138 if (my_b_printf(&cache, " cid=%s", buf2))
8139 goto err;
8140 }
8141 if (flags2 & FL_DDL)
8142 if (my_b_write_string(&cache, " ddl"))
8143 goto err;
8144 if (flags2 & FL_TRANSACTIONAL)
8145 if (my_b_write_string(&cache, " trans"))
8146 goto err;
8147 if (flags2 & FL_WAITED)
8148 if (my_b_write_string(&cache, " waited"))
8149 goto err;
8150 if (my_b_printf(&cache, "\n"))
8151 goto err;
8152
8153 if (!print_event_info->allow_parallel_printed ||
8154 print_event_info->allow_parallel != !!(flags2 & FL_ALLOW_PARALLEL))
8155 {
8156 if (my_b_printf(&cache,
8157 "/*!100101 SET @@session.skip_parallel_replication=%u*/%s\n",
8158 !(flags2 & FL_ALLOW_PARALLEL),
8159 print_event_info->delimiter))
8160 goto err;
8161 print_event_info->allow_parallel= !!(flags2 & FL_ALLOW_PARALLEL);
8162 print_event_info->allow_parallel_printed= true;
8163 }
8164
8165 if (!print_event_info->domain_id_printed ||
8166 print_event_info->domain_id != domain_id)
8167 {
8168 if (my_b_printf(&cache,
8169 "/*!100001 SET @@session.gtid_domain_id=%u*/%s\n",
8170 domain_id, print_event_info->delimiter))
8171 goto err;
8172 print_event_info->domain_id= domain_id;
8173 print_event_info->domain_id_printed= true;
8174 }
8175
8176 if (!print_event_info->server_id_printed ||
8177 print_event_info->server_id != server_id)
8178 {
8179 if (my_b_printf(&cache, "/*!100001 SET @@session.server_id=%u*/%s\n",
8180 server_id, print_event_info->delimiter))
8181 goto err;
8182 print_event_info->server_id= server_id;
8183 print_event_info->server_id_printed= true;
8184 }
8185
8186 if (!is_flashback)
8187 if (my_b_printf(&cache, "/*!100001 SET @@session.gtid_seq_no=%s*/%s\n",
8188 buf, print_event_info->delimiter))
8189 goto err;
8190 }
8191 if (!(flags2 & FL_STANDALONE))
8192 if (my_b_printf(&cache, is_flashback ? "COMMIT\n%s\n" : "BEGIN\n%s\n", print_event_info->delimiter))
8193 goto err;
8194
8195 return cache.flush_data();
8196err:
8197 return 1;
8198}
8199
8200#endif /* MYSQL_SERVER */
8201
8202
8203/* GTID list. */
8204
8205Gtid_list_log_event::Gtid_list_log_event(const char *buf, uint event_len,
8206 const Format_description_log_event *description_event)
8207 : Log_event(buf, description_event), count(0), list(0), sub_id_list(0)
8208{
8209 uint32 i;
8210 uint32 val;
8211 uint8 header_size= description_event->common_header_len;
8212 uint8 post_header_len= description_event->post_header_len[GTID_LIST_EVENT-1];
8213 if (event_len < (uint) header_size + (uint) post_header_len ||
8214 post_header_len < GTID_LIST_HEADER_LEN)
8215 return;
8216
8217 buf+= header_size;
8218 val= uint4korr(buf);
8219 count= val & ((1<<28)-1);
8220 gl_flags= val & ((uint32)0xf << 28);
8221 buf+= 4;
8222 if (event_len - (header_size + post_header_len) < count*element_size ||
8223 (!(list= (rpl_gtid *)my_malloc(count*sizeof(*list) + (count == 0),
8224 MYF(MY_WME)))))
8225 return;
8226
8227 for (i= 0; i < count; ++i)
8228 {
8229 list[i].domain_id= uint4korr(buf);
8230 buf+= 4;
8231 list[i].server_id= uint4korr(buf);
8232 buf+= 4;
8233 list[i].seq_no= uint8korr(buf);
8234 buf+= 8;
8235 }
8236
8237#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8238 if ((gl_flags & FLAG_IGN_GTIDS))
8239 {
8240 uint32 i;
8241 if (!(sub_id_list= (uint64 *)my_malloc(count*sizeof(uint64), MYF(MY_WME))))
8242 {
8243 my_free(list);
8244 list= NULL;
8245 return;
8246 }
8247 for (i= 0; i < count; ++i)
8248 {
8249 if (!(sub_id_list[i]=
8250 rpl_global_gtid_slave_state->next_sub_id(list[i].domain_id)))
8251 {
8252 my_free(list);
8253 my_free(sub_id_list);
8254 list= NULL;
8255 sub_id_list= NULL;
8256 return;
8257 }
8258 }
8259 }
8260#endif
8261}
8262
8263
8264#ifdef MYSQL_SERVER
8265
8266Gtid_list_log_event::Gtid_list_log_event(rpl_binlog_state *gtid_set,
8267 uint32 gl_flags_)
8268 : count(gtid_set->count()), gl_flags(gl_flags_), list(0), sub_id_list(0)
8269{
8270 cache_type= EVENT_NO_CACHE;
8271 /* Failure to allocate memory will be caught by is_valid() returning false. */
8272 if (count < (1<<28) &&
8273 (list = (rpl_gtid *)my_malloc(count * sizeof(*list) + (count == 0),
8274 MYF(MY_WME))))
8275 gtid_set->get_gtid_list(list, count);
8276}
8277
8278
8279Gtid_list_log_event::Gtid_list_log_event(slave_connection_state *gtid_set,
8280 uint32 gl_flags_)
8281 : count(gtid_set->count()), gl_flags(gl_flags_), list(0), sub_id_list(0)
8282{
8283 cache_type= EVENT_NO_CACHE;
8284 /* Failure to allocate memory will be caught by is_valid() returning false. */
8285 if (count < (1<<28) &&
8286 (list = (rpl_gtid *)my_malloc(count * sizeof(*list) + (count == 0),
8287 MYF(MY_WME))))
8288 {
8289 gtid_set->get_gtid_list(list, count);
8290#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8291 if (gl_flags & FLAG_IGN_GTIDS)
8292 {
8293 uint32 i;
8294
8295 if (!(sub_id_list= (uint64 *)my_malloc(count * sizeof(uint64),
8296 MYF(MY_WME))))
8297 {
8298 my_free(list);
8299 list= NULL;
8300 return;
8301 }
8302 for (i= 0; i < count; ++i)
8303 {
8304 if (!(sub_id_list[i]=
8305 rpl_global_gtid_slave_state->next_sub_id(list[i].domain_id)))
8306 {
8307 my_free(list);
8308 my_free(sub_id_list);
8309 list= NULL;
8310 sub_id_list= NULL;
8311 return;
8312 }
8313 }
8314 }
8315#endif
8316 }
8317}
8318
8319
8320#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8321bool
8322Gtid_list_log_event::to_packet(String *packet)
8323{
8324 uint32 i;
8325 uchar *p;
8326 uint32 needed_length;
8327
8328 DBUG_ASSERT(count < 1<<28);
8329
8330 needed_length= packet->length() + get_data_size();
8331 if (packet->reserve(needed_length))
8332 return true;
8333 p= (uchar *)packet->ptr() + packet->length();;
8334 packet->length(needed_length);
8335 int4store(p, (count & ((1<<28)-1)) | gl_flags);
8336 p += 4;
8337 /* Initialise the padding for empty Gtid_list. */
8338 if (count == 0)
8339 int2store(p, 0);
8340 for (i= 0; i < count; ++i)
8341 {
8342 int4store(p, list[i].domain_id);
8343 int4store(p+4, list[i].server_id);
8344 int8store(p+8, list[i].seq_no);
8345 p += 16;
8346 }
8347
8348 return false;
8349}
8350
8351
8352bool
8353Gtid_list_log_event::write()
8354{
8355 char buf[128];
8356 String packet(buf, sizeof(buf), system_charset_info);
8357
8358 packet.length(0);
8359 if (to_packet(&packet))
8360 return true;
8361 return write_header(get_data_size()) ||
8362 write_data(packet.ptr(), packet.length()) ||
8363 write_footer();
8364}
8365
8366
8367int
8368Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
8369{
8370 Relay_log_info *rli= const_cast<Relay_log_info*>(rgi->rli);
8371 int ret;
8372 if (gl_flags & FLAG_IGN_GTIDS)
8373 {
8374 void *hton= NULL;
8375 uint32 i;
8376
8377 for (i= 0; i < count; ++i)
8378 {
8379 if ((ret= rpl_global_gtid_slave_state->record_gtid(thd, &list[i],
8380 sub_id_list[i],
8381 false, false, &hton)))
8382 return ret;
8383 rpl_global_gtid_slave_state->update_state_hash(sub_id_list[i], &list[i],
8384 hton, NULL);
8385 }
8386 }
8387 ret= Log_event::do_apply_event(rgi);
8388 if (rli->until_condition == Relay_log_info::UNTIL_GTID &&
8389 (gl_flags & FLAG_UNTIL_REACHED))
8390 {
8391 char str_buf[128];
8392 String str(str_buf, sizeof(str_buf), system_charset_info);
8393 rli->until_gtid_pos.to_string(&str);
8394 sql_print_information("Slave SQL thread stops because it reached its"
8395 " UNTIL master_gtid_pos %s", str.c_ptr_safe());
8396 rli->abort_slave= true;
8397 rli->stop_for_until= true;
8398 }
8399 free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
8400 return ret;
8401}
8402
8403
8404Log_event::enum_skip_reason
8405Gtid_list_log_event::do_shall_skip(rpl_group_info *rgi)
8406{
8407 enum_skip_reason reason= Log_event::do_shall_skip(rgi);
8408 if (reason == EVENT_SKIP_COUNT)
8409 reason= EVENT_SKIP_NOT;
8410 return reason;
8411}
8412
8413
8414void
8415Gtid_list_log_event::pack_info(Protocol *protocol)
8416{
8417 char buf_mem[1024];
8418 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
8419 uint32 i;
8420 bool first;
8421
8422 buf.length(0);
8423 buf.append(STRING_WITH_LEN("["));
8424 first= true;
8425 for (i= 0; i < count; ++i)
8426 rpl_slave_state_tostring_helper(&buf, &list[i], &first);
8427 buf.append(STRING_WITH_LEN("]"));
8428
8429 protocol->store(&buf);
8430}
8431#endif /* HAVE_REPLICATION */
8432
8433#else /* !MYSQL_SERVER */
8434
8435bool
8436Gtid_list_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
8437{
8438 if (print_event_info->short_form)
8439 return 0;
8440
8441 Write_on_release_cache cache(&print_event_info->head_cache, file,
8442 Write_on_release_cache::FLUSH_F);
8443 char buf[21];
8444 uint32 i;
8445
8446 if (print_header(&cache, print_event_info, FALSE) ||
8447 my_b_printf(&cache, "\tGtid list ["))
8448 goto err;
8449
8450 for (i= 0; i < count; ++i)
8451 {
8452 longlong10_to_str(list[i].seq_no, buf, 10);
8453 if (my_b_printf(&cache, "%u-%u-%s", list[i].domain_id,
8454 list[i].server_id, buf))
8455 goto err;
8456 if (i < count-1)
8457 if (my_b_printf(&cache, ",\n# "))
8458 goto err;
8459 }
8460 if (my_b_printf(&cache, "]\n"))
8461 goto err;
8462
8463 return cache.flush_data();
8464err:
8465 return 1;
8466}
8467
8468#endif /* MYSQL_SERVER */
8469
8470
8471/*
8472 Used to record gtid_list event while sending binlog to slave, without having to
8473 fully contruct the event object.
8474*/
8475bool
8476Gtid_list_log_event::peek(const char *event_start, size_t event_len,
8477 enum enum_binlog_checksum_alg checksum_alg,
8478 rpl_gtid **out_gtid_list, uint32 *out_list_len,
8479 const Format_description_log_event *fdev)
8480{
8481 const char *p;
8482 uint32 count_field, count;
8483 rpl_gtid *gtid_list;
8484
8485 if (checksum_alg == BINLOG_CHECKSUM_ALG_CRC32)
8486 {
8487 if (event_len > BINLOG_CHECKSUM_LEN)
8488 event_len-= BINLOG_CHECKSUM_LEN;
8489 else
8490 event_len= 0;
8491 }
8492 else
8493 DBUG_ASSERT(checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF ||
8494 checksum_alg == BINLOG_CHECKSUM_ALG_OFF);
8495
8496 if (event_len < (uint32)fdev->common_header_len + GTID_LIST_HEADER_LEN)
8497 return true;
8498 p= event_start + fdev->common_header_len;
8499 count_field= uint4korr(p);
8500 p+= 4;
8501 count= count_field & ((1<<28)-1);
8502 if (event_len < (uint32)fdev->common_header_len + GTID_LIST_HEADER_LEN +
8503 16 * count)
8504 return true;
8505 if (!(gtid_list= (rpl_gtid *)my_malloc(sizeof(rpl_gtid)*count + (count == 0),
8506 MYF(MY_WME))))
8507 return true;
8508 *out_gtid_list= gtid_list;
8509 *out_list_len= count;
8510 while (count--)
8511 {
8512 gtid_list->domain_id= uint4korr(p);
8513 p+= 4;
8514 gtid_list->server_id= uint4korr(p);
8515 p+= 4;
8516 gtid_list->seq_no= uint8korr(p);
8517 p+= 8;
8518 ++gtid_list;
8519 }
8520
8521 return false;
8522}
8523
8524
8525/**************************************************************************
8526 Intvar_log_event methods
8527**************************************************************************/
8528
8529/*
8530 Intvar_log_event::pack_info()
8531*/
8532
8533#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8534void Intvar_log_event::pack_info(Protocol *protocol)
8535{
8536 char buf[256], *pos;
8537 pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
8538 *pos++= '=';
8539 pos= longlong10_to_str(val, pos, -10);
8540 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8541}
8542#endif
8543
8544
8545/*
8546 Intvar_log_event::Intvar_log_event()
8547*/
8548
8549Intvar_log_event::Intvar_log_event(const char* buf,
8550 const Format_description_log_event* description_event)
8551 :Log_event(buf, description_event)
8552{
8553 /* The Post-Header is empty. The Varible Data part begins immediately. */
8554 buf+= description_event->common_header_len +
8555 description_event->post_header_len[INTVAR_EVENT-1];
8556 type= buf[I_TYPE_OFFSET];
8557 val= uint8korr(buf+I_VAL_OFFSET);
8558}
8559
8560
8561/*
8562 Intvar_log_event::get_var_type_name()
8563*/
8564
8565const char* Intvar_log_event::get_var_type_name()
8566{
8567 switch(type) {
8568 case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
8569 case INSERT_ID_EVENT: return "INSERT_ID";
8570 default: /* impossible */ return "UNKNOWN";
8571 }
8572}
8573
8574
8575/*
8576 Intvar_log_event::write()
8577*/
8578
8579#ifndef MYSQL_CLIENT
8580bool Intvar_log_event::write()
8581{
8582 uchar buf[9];
8583 buf[I_TYPE_OFFSET]= (uchar) type;
8584 int8store(buf + I_VAL_OFFSET, val);
8585 return write_header(sizeof(buf)) ||
8586 write_data(buf, sizeof(buf)) ||
8587 write_footer();
8588}
8589#endif
8590
8591
8592/*
8593 Intvar_log_event::print()
8594*/
8595
8596#ifdef MYSQL_CLIENT
8597bool Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8598{
8599 char llbuff[22];
8600 const char *UNINIT_VAR(msg);
8601 Write_on_release_cache cache(&print_event_info->head_cache, file,
8602 Write_on_release_cache::FLUSH_F);
8603
8604 if (!print_event_info->short_form)
8605 {
8606 if (print_header(&cache, print_event_info, FALSE) ||
8607 my_b_write_string(&cache, "\tIntvar\n"))
8608 goto err;
8609 }
8610
8611 if (my_b_printf(&cache, "SET "))
8612 goto err;
8613 switch (type) {
8614 case LAST_INSERT_ID_EVENT:
8615 msg="LAST_INSERT_ID";
8616 break;
8617 case INSERT_ID_EVENT:
8618 msg="INSERT_ID";
8619 break;
8620 case INVALID_INT_EVENT:
8621 default: // cannot happen
8622 msg="INVALID_INT";
8623 break;
8624 }
8625 if (my_b_printf(&cache, "%s=%s%s\n",
8626 msg, llstr(val,llbuff), print_event_info->delimiter))
8627 goto err;
8628
8629 return cache.flush_data();
8630err:
8631 return 1;
8632}
8633#endif
8634
8635
8636#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
8637
8638/*
8639 Intvar_log_event::do_apply_event()
8640*/
8641
8642int Intvar_log_event::do_apply_event(rpl_group_info *rgi)
8643{
8644 DBUG_ENTER("Intvar_log_event::do_apply_event");
8645 if (rgi->deferred_events_collecting)
8646 {
8647 DBUG_PRINT("info",("deferring event"));
8648 DBUG_RETURN(rgi->deferred_events->add(this));
8649 }
8650
8651 switch (type) {
8652 case LAST_INSERT_ID_EVENT:
8653 thd->first_successful_insert_id_in_prev_stmt= val;
8654 DBUG_PRINT("info",("last_insert_id_event: %ld", (long) val));
8655 break;
8656 case INSERT_ID_EVENT:
8657 thd->force_one_auto_inc_interval(val);
8658 break;
8659 }
8660 DBUG_RETURN(0);
8661}
8662
8663int Intvar_log_event::do_update_pos(rpl_group_info *rgi)
8664{
8665 rgi->inc_event_relay_log_pos();
8666 return 0;
8667}
8668
8669
8670Log_event::enum_skip_reason
8671Intvar_log_event::do_shall_skip(rpl_group_info *rgi)
8672{
8673 /*
8674 It is a common error to set the slave skip counter to 1 instead of
8675 2 when recovering from an insert which used a auto increment,
8676 rand, or user var. Therefore, if the slave skip counter is 1, we
8677 just say that this event should be skipped by ignoring it, meaning
8678 that we do not change the value of the slave skip counter since it
8679 will be decreased by the following insert event.
8680 */
8681 return continue_group(rgi);
8682}
8683
8684#endif
8685
8686
8687/**************************************************************************
8688 Rand_log_event methods
8689**************************************************************************/
8690
8691#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8692void Rand_log_event::pack_info(Protocol *protocol)
8693{
8694 char buf1[256], *pos;
8695 pos= strmov(buf1,"rand_seed1=");
8696 pos= int10_to_str((long) seed1, pos, 10);
8697 pos= strmov(pos, ",rand_seed2=");
8698 pos= int10_to_str((long) seed2, pos, 10);
8699 protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
8700}
8701#endif
8702
8703
8704Rand_log_event::Rand_log_event(const char* buf,
8705 const Format_description_log_event* description_event)
8706 :Log_event(buf, description_event)
8707{
8708 /* The Post-Header is empty. The Variable Data part begins immediately. */
8709 buf+= description_event->common_header_len +
8710 description_event->post_header_len[RAND_EVENT-1];
8711 seed1= uint8korr(buf+RAND_SEED1_OFFSET);
8712 seed2= uint8korr(buf+RAND_SEED2_OFFSET);
8713}
8714
8715
8716#ifndef MYSQL_CLIENT
8717bool Rand_log_event::write()
8718{
8719 uchar buf[16];
8720 int8store(buf + RAND_SEED1_OFFSET, seed1);
8721 int8store(buf + RAND_SEED2_OFFSET, seed2);
8722 return write_header(sizeof(buf)) ||
8723 write_data(buf, sizeof(buf)) ||
8724 write_footer();
8725}
8726#endif
8727
8728
8729#ifdef MYSQL_CLIENT
8730bool Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8731{
8732 Write_on_release_cache cache(&print_event_info->head_cache, file,
8733 Write_on_release_cache::FLUSH_F);
8734
8735 char llbuff[22],llbuff2[22];
8736 if (!print_event_info->short_form)
8737 {
8738 if (print_header(&cache, print_event_info, FALSE) ||
8739 my_b_write_string(&cache, "\tRand\n"))
8740 goto err;
8741 }
8742 if (my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
8743 llstr(seed1, llbuff),llstr(seed2, llbuff2),
8744 print_event_info->delimiter))
8745 goto err;
8746
8747 return cache.flush_data();
8748err:
8749 return 1;
8750}
8751#endif /* MYSQL_CLIENT */
8752
8753
8754#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8755int Rand_log_event::do_apply_event(rpl_group_info *rgi)
8756{
8757 if (rgi->deferred_events_collecting)
8758 return rgi->deferred_events->add(this);
8759
8760 thd->rand.seed1= (ulong) seed1;
8761 thd->rand.seed2= (ulong) seed2;
8762 return 0;
8763}
8764
8765int Rand_log_event::do_update_pos(rpl_group_info *rgi)
8766{
8767 rgi->inc_event_relay_log_pos();
8768 return 0;
8769}
8770
8771
8772Log_event::enum_skip_reason
8773Rand_log_event::do_shall_skip(rpl_group_info *rgi)
8774{
8775 /*
8776 It is a common error to set the slave skip counter to 1 instead of
8777 2 when recovering from an insert which used a auto increment,
8778 rand, or user var. Therefore, if the slave skip counter is 1, we
8779 just say that this event should be skipped by ignoring it, meaning
8780 that we do not change the value of the slave skip counter since it
8781 will be decreased by the following insert event.
8782 */
8783 return continue_group(rgi);
8784}
8785
8786/**
8787 Exec deferred Int-, Rand- and User- var events prefixing
8788 a Query-log-event event.
8789
8790 @param thd THD handle
8791
8792 @return false on success, true if a failure in an event applying occurred.
8793*/
8794bool slave_execute_deferred_events(THD *thd)
8795{
8796 bool res= false;
8797 rpl_group_info *rgi= thd->rgi_slave;
8798
8799 DBUG_ASSERT(rgi && (!rgi->deferred_events_collecting || rgi->deferred_events));
8800
8801 if (!rgi->deferred_events_collecting || rgi->deferred_events->is_empty())
8802 return res;
8803
8804 res= rgi->deferred_events->execute(rgi);
8805 rgi->deferred_events->rewind();
8806
8807 return res;
8808}
8809
8810#endif /* !MYSQL_CLIENT */
8811
8812
8813/**************************************************************************
8814 Xid_log_event methods
8815**************************************************************************/
8816
8817#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8818void Xid_log_event::pack_info(Protocol *protocol)
8819{
8820 char buf[128], *pos;
8821 pos= strmov(buf, "COMMIT /* xid=");
8822 pos= longlong10_to_str(xid, pos, 10);
8823 pos= strmov(pos, " */");
8824 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8825}
8826#endif
8827
8828/**
8829 @note
8830 It's ok not to use int8store here,
8831 as long as xid_t::set(ulonglong) and
8832 xid_t::get_my_xid doesn't do it either.
8833 We don't care about actual values of xids as long as
8834 identical numbers compare identically
8835*/
8836
8837Xid_log_event::
8838Xid_log_event(const char* buf,
8839 const Format_description_log_event *description_event)
8840 :Log_event(buf, description_event)
8841{
8842 /* The Post-Header is empty. The Variable Data part begins immediately. */
8843 buf+= description_event->common_header_len +
8844 description_event->post_header_len[XID_EVENT-1];
8845 memcpy((char*) &xid, buf, sizeof(xid));
8846}
8847
8848
8849#ifndef MYSQL_CLIENT
8850bool Xid_log_event::write()
8851{
8852 DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
8853 return write_header(sizeof(xid)) ||
8854 write_data((uchar*)&xid, sizeof(xid)) ||
8855 write_footer();
8856}
8857#endif
8858
8859
8860#ifdef MYSQL_CLIENT
8861bool Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8862{
8863 Write_on_release_cache cache(&print_event_info->head_cache, file,
8864 Write_on_release_cache::FLUSH_F, this);
8865
8866 if (!print_event_info->short_form)
8867 {
8868 char buf[64];
8869 longlong10_to_str(xid, buf, 10);
8870
8871 if (print_header(&cache, print_event_info, FALSE) ||
8872 my_b_printf(&cache, "\tXid = %s\n", buf))
8873 goto err;
8874 }
8875 if (my_b_printf(&cache, is_flashback ? "BEGIN%s\n" : "COMMIT%s\n",
8876 print_event_info->delimiter))
8877 goto err;
8878
8879 return cache.flush_data();
8880err:
8881 return 1;
8882}
8883#endif /* MYSQL_CLIENT */
8884
8885
8886#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8887int Xid_log_event::do_apply_event(rpl_group_info *rgi)
8888{
8889 bool res;
8890 int err;
8891 rpl_gtid gtid;
8892 uint64 sub_id= 0;
8893 Relay_log_info const *rli= rgi->rli;
8894 void *hton= NULL;
8895
8896 /*
8897 XID_EVENT works like a COMMIT statement. And it also updates the
8898 mysql.gtid_slave_pos table with the GTID of the current transaction.
8899
8900 Therefore, it acts much like a normal SQL statement, so we need to do
8901 THD::reset_for_next_command() as if starting a new statement.
8902 */
8903 thd->reset_for_next_command();
8904 /*
8905 Record any GTID in the same transaction, so slave state is transactionally
8906 consistent.
8907 */
8908#ifdef WITH_WSREP
8909 thd->wsrep_affected_rows= 0;
8910#endif
8911
8912 if (rgi->gtid_pending)
8913 {
8914 sub_id= rgi->gtid_sub_id;
8915 rgi->gtid_pending= false;
8916
8917 gtid= rgi->current_gtid;
8918 err= rpl_global_gtid_slave_state->record_gtid(thd, &gtid, sub_id, true,
8919 false, &hton);
8920 if (unlikely(err))
8921 {
8922 int ec= thd->get_stmt_da()->sql_errno();
8923 /*
8924 Do not report an error if this is really a kill due to a deadlock.
8925 In this case, the transaction will be re-tried instead.
8926 */
8927 if (!is_parallel_retry_error(rgi, ec))
8928 rli->report(ERROR_LEVEL, ER_CANNOT_UPDATE_GTID_STATE, rgi->gtid_info(),
8929 "Error during XID COMMIT: failed to update GTID state in "
8930 "%s.%s: %d: %s",
8931 "mysql", rpl_gtid_slave_state_table_name.str, ec,
8932 thd->get_stmt_da()->message());
8933 thd->is_slave_error= 1;
8934 return err;
8935 }
8936
8937 DBUG_EXECUTE_IF("gtid_fail_after_record_gtid",
8938 { my_error(ER_ERROR_DURING_COMMIT, MYF(0), HA_ERR_WRONG_COMMAND);
8939 thd->is_slave_error= 1;
8940 return 1;
8941 });
8942 }
8943
8944 /* For a slave Xid_log_event is COMMIT */
8945 general_log_print(thd, COM_QUERY,
8946 "COMMIT /* implicit, from Xid_log_event */");
8947 thd->variables.option_bits&= ~OPTION_GTID_BEGIN;
8948 res= trans_commit(thd); /* Automatically rolls back on error. */
8949 thd->mdl_context.release_transactional_locks();
8950
8951 if (likely(!res) && sub_id)
8952 rpl_global_gtid_slave_state->update_state_hash(sub_id, &gtid, hton, rgi);
8953
8954 /*
8955 Increment the global status commit count variable
8956 */
8957 status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
8958
8959 return res;
8960}
8961
8962Log_event::enum_skip_reason
8963Xid_log_event::do_shall_skip(rpl_group_info *rgi)
8964{
8965 DBUG_ENTER("Xid_log_event::do_shall_skip");
8966 if (rgi->rli->slave_skip_counter > 0)
8967 {
8968 DBUG_ASSERT(!rgi->rli->get_flag(Relay_log_info::IN_TRANSACTION));
8969 thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_GTID_BEGIN);
8970 DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
8971 }
8972#ifdef WITH_WSREP
8973 else if (wsrep_mysql_replication_bundle && WSREP_ON &&
8974 opt_slave_domain_parallel_threads == 0)
8975 {
8976 if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
8977 {
8978 WSREP_DEBUG("skipping wsrep commit %d", thd->wsrep_mysql_replicated);
8979 DBUG_RETURN(Log_event::EVENT_SKIP_IGNORE);
8980 }
8981 else
8982 {
8983 thd->wsrep_mysql_replicated = 0;
8984 }
8985 }
8986#endif
8987 DBUG_RETURN(Log_event::do_shall_skip(rgi));
8988}
8989#endif /* !MYSQL_CLIENT */
8990
8991
8992/**************************************************************************
8993 User_var_log_event methods
8994**************************************************************************/
8995
8996#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8997static bool
8998user_var_append_name_part(THD *thd, String *buf,
8999 const char *name, size_t name_len)
9000{
9001 return buf->append("@") ||
9002 append_identifier(thd, buf, name, name_len) ||
9003 buf->append("=");
9004}
9005
9006void User_var_log_event::pack_info(Protocol* protocol)
9007{
9008 if (is_null)
9009 {
9010 char buf_mem[FN_REFLEN+7];
9011 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
9012 buf.length(0);
9013 if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
9014 buf.append("NULL"))
9015 return;
9016 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
9017 }
9018 else
9019 {
9020 switch (type) {
9021 case REAL_RESULT:
9022 {
9023 double real_val;
9024 char buf2[MY_GCVT_MAX_FIELD_WIDTH+1];
9025 char buf_mem[FN_REFLEN + MY_GCVT_MAX_FIELD_WIDTH + 1];
9026 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
9027 float8get(real_val, val);
9028 buf.length(0);
9029 if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
9030 buf.append(buf2, my_gcvt(real_val, MY_GCVT_ARG_DOUBLE,
9031 MY_GCVT_MAX_FIELD_WIDTH, buf2, NULL)))
9032 return;
9033 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
9034 break;
9035 }
9036 case INT_RESULT:
9037 {
9038 char buf2[22];
9039 char buf_mem[FN_REFLEN + 22];
9040 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
9041 buf.length(0);
9042 if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
9043 buf.append(buf2,
9044 longlong10_to_str(uint8korr(val), buf2,
9045 ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10))-buf2))
9046 return;
9047 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
9048 break;
9049 }
9050 case DECIMAL_RESULT:
9051 {
9052 char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH];
9053 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
9054 char buf2[DECIMAL_MAX_STR_LENGTH+1];
9055 String str(buf2, sizeof(buf2), &my_charset_bin);
9056 my_decimal dec;
9057 buf.length(0);
9058 binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
9059 val[1]);
9060 my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
9061 if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
9062 buf.append(buf2))
9063 return;
9064 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
9065 break;
9066 }
9067 case STRING_RESULT:
9068 {
9069 /* 15 is for 'COLLATE' and other chars */
9070 char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15];
9071 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
9072 CHARSET_INFO *cs;
9073 buf.length(0);
9074 if (!(cs= get_charset(charset_number, MYF(0))))
9075 {
9076 if (buf.append("???"))
9077 return;
9078 }
9079 else
9080 {
9081 size_t old_len;
9082 char *beg, *end;
9083 if (user_var_append_name_part(protocol->thd, &buf, name, name_len) ||
9084 buf.append("_") ||
9085 buf.append(cs->csname) ||
9086 buf.append(" "))
9087 return;
9088 old_len= buf.length();
9089 if (buf.reserve(old_len + val_len * 2 + 3 + sizeof(" COLLATE ") +
9090 MY_CS_NAME_SIZE))
9091 return;
9092 beg= const_cast<char *>(buf.ptr()) + old_len;
9093 end= str_to_hex(beg, val, val_len);
9094 buf.length(old_len + (end - beg));
9095 if (buf.append(" COLLATE ") ||
9096 buf.append(cs->name))
9097 return;
9098 }
9099 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
9100 break;
9101 }
9102 case ROW_RESULT:
9103 default:
9104 DBUG_ASSERT(0);
9105 return;
9106 }
9107 }
9108}
9109#endif /* !MYSQL_CLIENT */
9110
9111
9112User_var_log_event::
9113User_var_log_event(const char* buf, uint event_len,
9114 const Format_description_log_event* description_event)
9115 :Log_event(buf, description_event)
9116#ifndef MYSQL_CLIENT
9117 , deferred(false), query_id(0)
9118#endif
9119{
9120 bool error= false;
9121 const char* buf_start= buf, *buf_end= buf + event_len;
9122
9123 /* The Post-Header is empty. The Variable Data part begins immediately. */
9124 buf+= description_event->common_header_len +
9125 description_event->post_header_len[USER_VAR_EVENT-1];
9126 name_len= uint4korr(buf);
9127 /* Avoid reading out of buffer */
9128 if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
9129 {
9130 error= true;
9131 goto err;
9132 }
9133
9134 name= (char *) buf + UV_NAME_LEN_SIZE;
9135
9136 /*
9137 We don't know yet is_null value, so we must assume that name_len
9138 may have the bigger value possible, is_null= True and there is no
9139 payload for val, or even that name_len is 0.
9140 */
9141 if (name + name_len + UV_VAL_IS_NULL > buf_end)
9142 {
9143 error= true;
9144 goto err;
9145 }
9146
9147 buf+= UV_NAME_LEN_SIZE + name_len;
9148 is_null= (bool) *buf;
9149 flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
9150 if (is_null)
9151 {
9152 type= STRING_RESULT;
9153 charset_number= my_charset_bin.number;
9154 val_len= 0;
9155 val= 0;
9156 }
9157 else
9158 {
9159 val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
9160 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
9161
9162 if (val > buf_end)
9163 {
9164 error= true;
9165 goto err;
9166 }
9167
9168 type= (Item_result) buf[UV_VAL_IS_NULL];
9169 charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
9170 val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
9171 UV_CHARSET_NUMBER_SIZE);
9172
9173 if (val + val_len > buf_end)
9174 {
9175 error= true;
9176 goto err;
9177 }
9178
9179 /**
9180 We need to check if this is from an old server
9181 that did not pack information for flags.
9182 We do this by checking if there are extra bytes
9183 after the packed value. If there are we take the
9184 extra byte and it's value is assumed to contain
9185 the flags value.
9186
9187 Old events will not have this extra byte, thence,
9188 we keep the flags set to UNDEF_F.
9189 */
9190 size_t bytes_read= (val + val_len) - buf_start;
9191 if (bytes_read > size_t(event_len))
9192 {
9193 error= true;
9194 goto err;
9195 }
9196 if ((data_written - bytes_read) > 0)
9197 {
9198 flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
9199 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
9200 val_len);
9201 }
9202 }
9203
9204err:
9205 if (unlikely(error))
9206 name= 0;
9207}
9208
9209
9210#ifndef MYSQL_CLIENT
9211bool User_var_log_event::write()
9212{
9213 char buf[UV_NAME_LEN_SIZE];
9214 char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
9215 UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
9216 uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
9217 uint unsigned_len= 0;
9218 uint buf1_length;
9219 size_t event_length;
9220
9221 int4store(buf, name_len);
9222
9223 if ((buf1[0]= is_null))
9224 {
9225 buf1_length= 1;
9226 val_len= 0; // Length of 'pos'
9227 }
9228 else
9229 {
9230 buf1[1]= type;
9231 int4store(buf1 + 2, charset_number);
9232
9233 switch (type) {
9234 case REAL_RESULT:
9235 float8store(buf2, *(double*) val);
9236 break;
9237 case INT_RESULT:
9238 int8store(buf2, *(longlong*) val);
9239 unsigned_len= 1;
9240 break;
9241 case DECIMAL_RESULT:
9242 {
9243 my_decimal *dec= (my_decimal *)val;
9244 dec->fix_buffer_pointer();
9245 buf2[0]= (char)(dec->intg + dec->frac);
9246 buf2[1]= (char)dec->frac;
9247 decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
9248 val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
9249 break;
9250 }
9251 case STRING_RESULT:
9252 pos= (uchar*) val;
9253 break;
9254 case ROW_RESULT:
9255 default:
9256 DBUG_ASSERT(0);
9257 return 0;
9258 }
9259 int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
9260 buf1_length= 10;
9261 }
9262
9263 /* Length of the whole event */
9264 event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
9265
9266 return write_header(event_length) ||
9267 write_data(buf, sizeof(buf)) ||
9268 write_data(name, name_len) ||
9269 write_data(buf1, buf1_length) ||
9270 write_data(pos, val_len) ||
9271 write_data(&flags, unsigned_len) ||
9272 write_footer();
9273}
9274#endif
9275
9276
9277/*
9278 User_var_log_event::print()
9279*/
9280
9281#ifdef MYSQL_CLIENT
9282bool User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
9283{
9284 Write_on_release_cache cache(&print_event_info->head_cache, file,
9285 Write_on_release_cache::FLUSH_F);
9286
9287 if (!print_event_info->short_form)
9288 {
9289 if (print_header(&cache, print_event_info, FALSE) ||
9290 my_b_write_string(&cache, "\tUser_var\n"))
9291 goto err;
9292 }
9293
9294 if (my_b_write_string(&cache, "SET @") ||
9295 my_b_write_backtick_quote(&cache, name, name_len))
9296 goto err;
9297
9298 if (is_null)
9299 {
9300 if (my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter))
9301 goto err;
9302 }
9303 else
9304 {
9305 switch (type) {
9306 case REAL_RESULT:
9307 double real_val;
9308 char real_buf[FMT_G_BUFSIZE(14)];
9309 float8get(real_val, val);
9310 sprintf(real_buf, "%.14g", real_val);
9311 if (my_b_printf(&cache, ":=%s%s\n", real_buf,
9312 print_event_info->delimiter))
9313 goto err;
9314 break;
9315 case INT_RESULT:
9316 char int_buf[22];
9317 longlong10_to_str(uint8korr(val), int_buf,
9318 ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
9319 if (my_b_printf(&cache, ":=%s%s\n", int_buf,
9320 print_event_info->delimiter))
9321 goto err;
9322 break;
9323 case DECIMAL_RESULT:
9324 {
9325 char str_buf[200];
9326 int str_len= sizeof(str_buf) - 1;
9327 int precision= (int)val[0];
9328 int scale= (int)val[1];
9329 decimal_digit_t dec_buf[10];
9330 decimal_t dec;
9331 dec.len= 10;
9332 dec.buf= dec_buf;
9333
9334 bin2decimal((uchar*) val+2, &dec, precision, scale);
9335 decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
9336 str_buf[str_len]= 0;
9337 if (my_b_printf(&cache, ":=%s%s\n", str_buf,
9338 print_event_info->delimiter))
9339 goto err;
9340 break;
9341 }
9342 case STRING_RESULT:
9343 {
9344 /*
9345 Let's express the string in hex. That's the most robust way. If we
9346 print it in character form instead, we need to escape it with
9347 character_set_client which we don't know (we will know it in 5.0, but
9348 in 4.1 we don't know it easily when we are printing
9349 User_var_log_event). Explanation why we would need to bother with
9350 character_set_client (quoting Bar):
9351 > Note, the parser doesn't switch to another unescaping mode after
9352 > it has met a character set introducer.
9353 > For example, if an SJIS client says something like:
9354 > SET @a= _ucs2 \0a\0b'
9355 > the string constant is still unescaped according to SJIS, not
9356 > according to UCS2.
9357 */
9358 char *hex_str;
9359 CHARSET_INFO *cs;
9360 bool error;
9361
9362 // 2 hex digits / byte
9363 hex_str= (char *) my_malloc(2 * val_len + 1 + 3, MYF(MY_WME));
9364 if (!hex_str)
9365 goto err;
9366 str_to_hex(hex_str, val, val_len);
9367 /*
9368 For proper behaviour when mysqlbinlog|mysql, we need to explicitly
9369 specify the variable's collation. It will however cause problems when
9370 people want to mysqlbinlog|mysql into another server not supporting the
9371 character set. But there's not much to do about this and it's unlikely.
9372 */
9373 if (!(cs= get_charset(charset_number, MYF(0))))
9374 { /*
9375 Generate an unusable command (=> syntax error) is probably the best
9376 thing we can do here.
9377 */
9378 error= my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
9379 }
9380 else
9381 error= my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
9382 cs->csname, hex_str, cs->name,
9383 print_event_info->delimiter);
9384 my_free(hex_str);
9385 if (unlikely(error))
9386 goto err;
9387 break;
9388 }
9389 case ROW_RESULT:
9390 default:
9391 DBUG_ASSERT(0);
9392 break;
9393 }
9394 }
9395
9396 return cache.flush_data();
9397err:
9398 return 1;
9399}
9400#endif
9401
9402
9403/*
9404 User_var_log_event::do_apply_event()
9405*/
9406
9407#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
9408int User_var_log_event::do_apply_event(rpl_group_info *rgi)
9409{
9410 Item *it= 0;
9411 CHARSET_INFO *charset;
9412 DBUG_ENTER("User_var_log_event::do_apply_event");
9413 query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
9414
9415 if (rgi->deferred_events_collecting)
9416 {
9417 set_deferred(current_thd->query_id);
9418 DBUG_RETURN(rgi->deferred_events->add(this));
9419 }
9420 else if (is_deferred())
9421 {
9422 sav_query_id= current_thd->query_id;
9423 current_thd->query_id= query_id; /* recreating original time context */
9424 }
9425
9426 if (!(charset= get_charset(charset_number, MYF(MY_WME))))
9427 {
9428 rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9429 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
9430 "Invalid character set for User var event");
9431 DBUG_RETURN(1);
9432 }
9433 LEX_CSTRING user_var_name;
9434 user_var_name.str= name;
9435 user_var_name.length= name_len;
9436 double real_val;
9437 longlong int_val;
9438
9439 if (is_null)
9440 {
9441 it= new (thd->mem_root) Item_null(thd);
9442 }
9443 else
9444 {
9445 switch (type) {
9446 case REAL_RESULT:
9447 if (val_len != 8)
9448 {
9449 rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9450 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
9451 "Invalid variable length at User var event");
9452 return 1;
9453 }
9454 float8get(real_val, val);
9455 it= new (thd->mem_root) Item_float(thd, real_val, 0);
9456 val= (char*) &real_val; // Pointer to value in native format
9457 val_len= 8;
9458 break;
9459 case INT_RESULT:
9460 if (val_len != 8)
9461 {
9462 rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9463 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
9464 "Invalid variable length at User var event");
9465 return 1;
9466 }
9467 int_val= (longlong) uint8korr(val);
9468 it= new (thd->mem_root) Item_int(thd, int_val);
9469 val= (char*) &int_val; // Pointer to value in native format
9470 val_len= 8;
9471 break;
9472 case DECIMAL_RESULT:
9473 {
9474 if (val_len < 3)
9475 {
9476 rgi->rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9477 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
9478 "Invalid variable length at User var event");
9479 return 1;
9480 }
9481 Item_decimal *dec= new (thd->mem_root) Item_decimal(thd, (uchar*) val+2, val[0], val[1]);
9482 it= dec;
9483 val= (char *)dec->val_decimal(NULL);
9484 val_len= sizeof(my_decimal);
9485 break;
9486 }
9487 case STRING_RESULT:
9488 it= new (thd->mem_root) Item_string(thd, val, (uint)val_len, charset);
9489 break;
9490 case ROW_RESULT:
9491 default:
9492 DBUG_ASSERT(0);
9493 DBUG_RETURN(0);
9494 }
9495 }
9496
9497 Item_func_set_user_var *e= new (thd->mem_root) Item_func_set_user_var(thd, &user_var_name, it);
9498 /*
9499 Item_func_set_user_var can't substitute something else on its place =>
9500 0 can be passed as last argument (reference on item)
9501
9502 Fix_fields() can fail, in which case a call of update_hash() might
9503 crash the server, so if fix fields fails, we just return with an
9504 error.
9505 */
9506 if (e->fix_fields(thd, 0))
9507 DBUG_RETURN(1);
9508
9509 /*
9510 A variable can just be considered as a table with
9511 a single record and with a single column. Thus, like
9512 a column value, it could always have IMPLICIT derivation.
9513 */
9514 e->update_hash((void*) val, val_len, type, charset,
9515 (flags & User_var_log_event::UNSIGNED_F));
9516 if (!is_deferred())
9517 free_root(thd->mem_root, 0);
9518 else
9519 current_thd->query_id= sav_query_id; /* restore current query's context */
9520
9521 DBUG_RETURN(0);
9522}
9523
9524int User_var_log_event::do_update_pos(rpl_group_info *rgi)
9525{
9526 rgi->inc_event_relay_log_pos();
9527 return 0;
9528}
9529
9530Log_event::enum_skip_reason
9531User_var_log_event::do_shall_skip(rpl_group_info *rgi)
9532{
9533 /*
9534 It is a common error to set the slave skip counter to 1 instead
9535 of 2 when recovering from an insert which used a auto increment,
9536 rand, or user var. Therefore, if the slave skip counter is 1, we
9537 just say that this event should be skipped by ignoring it, meaning
9538 that we do not change the value of the slave skip counter since it
9539 will be decreased by the following insert event.
9540 */
9541 return continue_group(rgi);
9542}
9543#endif /* !MYSQL_CLIENT */
9544
9545#ifdef HAVE_REPLICATION
9546#ifdef MYSQL_CLIENT
9547bool Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
9548{
9549 if (print_event_info->short_form)
9550 return 0;
9551
9552 Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
9553
9554 if (what != ENCRYPTED)
9555 {
9556 if (print_header(&cache, print_event_info, FALSE) ||
9557 my_b_printf(&cache, "\n# Unknown event\n"))
9558 goto err;
9559 }
9560 else if (my_b_printf(&cache, "# Encrypted event\n"))
9561 goto err;
9562
9563 return cache.flush_data();
9564err:
9565 return 1;
9566}
9567#endif
9568
9569/**************************************************************************
9570 Stop_log_event methods
9571**************************************************************************/
9572
9573/*
9574 Stop_log_event::print()
9575*/
9576
9577#ifdef MYSQL_CLIENT
9578bool Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
9579{
9580 if (print_event_info->short_form)
9581 return 0;
9582
9583 Write_on_release_cache cache(&print_event_info->head_cache, file,
9584 Write_on_release_cache::FLUSH_F, this);
9585
9586 if (print_header(&cache, print_event_info, FALSE) ||
9587 my_b_write_string(&cache, "\tStop\n"))
9588 return 1;
9589 return cache.flush_data();
9590}
9591#endif /* MYSQL_CLIENT */
9592
9593
9594#ifndef MYSQL_CLIENT
9595/*
9596 The master stopped. We used to clean up all temporary tables but
9597 this is useless as, as the master has shut down properly, it has
9598 written all DROP TEMPORARY TABLE (prepared statements' deletion is
9599 TODO only when we binlog prep stmts). We used to clean up
9600 slave_load_tmpdir, but this is useless as it has been cleared at the
9601 end of LOAD DATA INFILE. So we have nothing to do here. The place
9602 were we must do this cleaning is in
9603 Start_log_event_v3::do_apply_event(), not here. Because if we come
9604 here, the master was sane.
9605
9606 This must only be called from the Slave SQL thread, since it calls
9607 Relay_log_info::flush().
9608*/
9609
9610int Stop_log_event::do_update_pos(rpl_group_info *rgi)
9611{
9612 int error= 0;
9613 Relay_log_info *rli= rgi->rli;
9614 DBUG_ENTER("Stop_log_event::do_update_pos");
9615 /*
9616 We do not want to update master_log pos because we get a rotate event
9617 before stop, so by now group_master_log_name is set to the next log.
9618 If we updated it, we will have incorrect master coordinates and this
9619 could give false triggers in MASTER_POS_WAIT() that we have reached
9620 the target position when in fact we have not.
9621 */
9622 if (rli->get_flag(Relay_log_info::IN_TRANSACTION))
9623 rgi->inc_event_relay_log_pos();
9624 else if (!rgi->is_parallel_exec)
9625 {
9626 rpl_global_gtid_slave_state->record_and_update_gtid(thd, rgi);
9627 rli->inc_group_relay_log_pos(0, rgi);
9628 if (rli->flush())
9629 error= 1;
9630 }
9631 DBUG_RETURN(error);
9632}
9633
9634#endif /* !MYSQL_CLIENT */
9635#endif /* HAVE_REPLICATION */
9636
9637
9638/**************************************************************************
9639 Create_file_log_event methods
9640**************************************************************************/
9641
9642/*
9643 Create_file_log_event ctor
9644*/
9645
9646#ifndef MYSQL_CLIENT
9647Create_file_log_event::
9648Create_file_log_event(THD* thd_arg, sql_exchange* ex,
9649 const char* db_arg, const char* table_name_arg,
9650 List<Item>& fields_arg,
9651 bool is_concurrent_arg,
9652 enum enum_duplicates handle_dup,
9653 bool ignore,
9654 uchar* block_arg, uint block_len_arg, bool using_trans)
9655 :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
9656 is_concurrent_arg,
9657 handle_dup, ignore, using_trans),
9658 fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
9659 file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
9660{
9661 DBUG_ENTER("Create_file_log_event");
9662 sql_ex.force_new_format();
9663 DBUG_VOID_RETURN;
9664}
9665
9666
9667/*
9668 Create_file_log_event::write_data_body()
9669*/
9670
9671bool Create_file_log_event::write_data_body()
9672{
9673 bool res;
9674 if ((res= Load_log_event::write_data_body()) || fake_base)
9675 return res;
9676 return write_data("", 1) ||
9677 write_data(block, block_len);
9678}
9679
9680
9681/*
9682 Create_file_log_event::write_data_header()
9683*/
9684
9685bool Create_file_log_event::write_data_header()
9686{
9687 bool res;
9688 uchar buf[CREATE_FILE_HEADER_LEN];
9689 if ((res= Load_log_event::write_data_header()) || fake_base)
9690 return res;
9691 int4store(buf + CF_FILE_ID_OFFSET, file_id);
9692 return write_data(buf, CREATE_FILE_HEADER_LEN) != 0;
9693}
9694
9695
9696/*
9697 Create_file_log_event::write_base()
9698*/
9699
9700bool Create_file_log_event::write_base()
9701{
9702 bool res;
9703 fake_base= 1; // pretend we are Load event
9704 res= write();
9705 fake_base= 0;
9706 return res;
9707}
9708
9709#endif /* !MYSQL_CLIENT */
9710
9711/*
9712 Create_file_log_event ctor
9713*/
9714
9715Create_file_log_event::Create_file_log_event(const char* buf, uint len,
9716 const Format_description_log_event* description_event)
9717 :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
9718{
9719 DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
9720 uint block_offset;
9721 uint header_len= description_event->common_header_len;
9722 uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
9723 uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
9724 if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
9725 copy_log_event(event_buf,len,
9726 (((uchar)buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
9727 load_header_len + header_len :
9728 (fake_base ? (header_len+load_header_len) :
9729 (header_len+load_header_len) +
9730 create_file_header_len)),
9731 description_event))
9732 DBUG_VOID_RETURN;
9733 if (description_event->binlog_version!=1)
9734 {
9735 file_id= uint4korr(buf +
9736 header_len +
9737 load_header_len + CF_FILE_ID_OFFSET);
9738 /*
9739 Note that it's ok to use get_data_size() below, because it is computed
9740 with values we have already read from this event (because we called
9741 copy_log_event()); we are not using slave's format info to decode
9742 master's format, we are really using master's format info.
9743 Anyway, both formats should be identical (except the common_header_len)
9744 as these Load events are not changed between 4.0 and 5.0 (as logging of
9745 LOAD DATA INFILE does not use Load_log_event in 5.0).
9746
9747 The + 1 is for \0 terminating fname
9748 */
9749 block_offset= (description_event->common_header_len +
9750 Load_log_event::get_data_size() +
9751 create_file_header_len + 1);
9752 if (len < block_offset)
9753 DBUG_VOID_RETURN;
9754 block = (uchar*)buf + block_offset;
9755 block_len = len - block_offset;
9756 }
9757 else
9758 {
9759 sql_ex.force_new_format();
9760 inited_from_old = 1;
9761 }
9762 DBUG_VOID_RETURN;
9763}
9764
9765
9766/*
9767 Create_file_log_event::print()
9768*/
9769
9770#ifdef MYSQL_CLIENT
9771bool Create_file_log_event::print(FILE* file,
9772 PRINT_EVENT_INFO* print_event_info,
9773 bool enable_local)
9774{
9775 if (print_event_info->short_form)
9776 {
9777 if (enable_local && check_fname_outside_temp_buf())
9778 return Load_log_event::print(file, print_event_info);
9779 return 0;
9780 }
9781
9782 Write_on_release_cache cache(&print_event_info->head_cache, file);
9783
9784 if (enable_local)
9785 {
9786 if (Load_log_event::print(file, print_event_info,
9787 !check_fname_outside_temp_buf()))
9788 goto err;
9789
9790 /**
9791 reduce the size of io cache so that the write function is called
9792 for every call to my_b_printf().
9793 */
9794 DBUG_EXECUTE_IF ("simulate_create_event_write_error",
9795 {(&cache)->write_pos= (&cache)->write_end;
9796 DBUG_SET("+d,simulate_file_write_error");});
9797 /*
9798 That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
9799 SHOW BINLOG EVENTS we don't.
9800 */
9801 if (my_b_write_byte(&cache, '#'))
9802 goto err;
9803 }
9804
9805 if (my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len))
9806 goto err;
9807
9808 return cache.flush_data();
9809err:
9810 return 1;
9811
9812}
9813
9814
9815bool Create_file_log_event::print(FILE* file,
9816 PRINT_EVENT_INFO* print_event_info)
9817{
9818 return print(file, print_event_info, 0);
9819}
9820#endif /* MYSQL_CLIENT */
9821
9822
9823/*
9824 Create_file_log_event::pack_info()
9825*/
9826
9827#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
9828void Create_file_log_event::pack_info(Protocol *protocol)
9829{
9830 char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
9831 pos= strmov(buf, "db=");
9832 memcpy(pos, db, db_len);
9833 pos= strmov(pos + db_len, ";table=");
9834 memcpy(pos, table_name, table_name_len);
9835 pos= strmov(pos + table_name_len, ";file_id=");
9836 pos= int10_to_str((long) file_id, pos, 10);
9837 pos= strmov(pos, ";block_len=");
9838 pos= int10_to_str((long) block_len, pos, 10);
9839 protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
9840}
9841#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9842
9843
9844/**
9845 Create_file_log_event::do_apply_event()
9846 Constructor for Create_file_log_event to intantiate an event
9847 from the relay log on the slave.
9848
9849 @retval
9850 0 Success
9851 @retval
9852 1 Failure
9853*/
9854
9855#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
9856int Create_file_log_event::do_apply_event(rpl_group_info *rgi)
9857{
9858 char fname_buf[FN_REFLEN];
9859 char *ext;
9860 int fd = -1;
9861 IO_CACHE file;
9862 Log_event_writer lew(&file, 0);
9863 int error = 1;
9864 Relay_log_info const *rli= rgi->rli;
9865
9866 THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
9867 bzero((char*)&file, sizeof(file));
9868 ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info",
9869 &rli->mi->connection_name);
9870 /* old copy may exist already */
9871 mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
9872 if ((fd= mysql_file_create(key_file_log_event_info,
9873 fname_buf, CREATE_MODE,
9874 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
9875 MYF(MY_WME))) < 0 ||
9876 init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
9877 MYF(MY_WME|MY_NABP)))
9878 {
9879 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
9880 "Error in Create_file event: could not open file '%s'",
9881 fname_buf);
9882 goto err;
9883 }
9884
9885 // a trick to avoid allocating another buffer
9886 fname= fname_buf;
9887 fname_len= (uint) (strmov(ext, ".data") - fname);
9888 writer= &lew;
9889 if (write_base())
9890 {
9891 strmov(ext, ".info"); // to have it right in the error message
9892 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
9893 "Error in Create_file event: could not write to file '%s'",
9894 fname_buf);
9895 goto err;
9896 }
9897 end_io_cache(&file);
9898 mysql_file_close(fd, MYF(0));
9899
9900 // fname_buf now already has .data, not .info, because we did our trick
9901 /* old copy may exist already */
9902 mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
9903 if ((fd= mysql_file_create(key_file_log_event_data,
9904 fname_buf, CREATE_MODE,
9905 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
9906 MYF(MY_WME))) < 0)
9907 {
9908 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
9909 "Error in Create_file event: could not open file '%s'",
9910 fname_buf);
9911 goto err;
9912 }
9913 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
9914 {
9915 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
9916 "Error in Create_file event: write to '%s' failed",
9917 fname_buf);
9918 goto err;
9919 }
9920 error=0; // Everything is ok
9921
9922err:
9923 if (unlikely(error))
9924 end_io_cache(&file);
9925 if (likely(fd >= 0))
9926 mysql_file_close(fd, MYF(0));
9927 return error != 0;
9928}
9929#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9930
9931
9932/**************************************************************************
9933 Append_block_log_event methods
9934**************************************************************************/
9935
9936/*
9937 Append_block_log_event ctor
9938*/
9939
9940#ifndef MYSQL_CLIENT
9941Append_block_log_event::Append_block_log_event(THD *thd_arg,
9942 const char *db_arg,
9943 uchar *block_arg,
9944 uint block_len_arg,
9945 bool using_trans)
9946 :Log_event(thd_arg,0, using_trans), block(block_arg),
9947 block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
9948{
9949}
9950#endif
9951
9952
9953/*
9954 Append_block_log_event ctor
9955*/
9956
9957Append_block_log_event::Append_block_log_event(const char* buf, uint len,
9958 const Format_description_log_event* description_event)
9959 :Log_event(buf, description_event),block(0)
9960{
9961 DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
9962 uint8 common_header_len= description_event->common_header_len;
9963 uint8 append_block_header_len=
9964 description_event->post_header_len[APPEND_BLOCK_EVENT-1];
9965 uint total_header_len= common_header_len+append_block_header_len;
9966 if (len < total_header_len)
9967 DBUG_VOID_RETURN;
9968 file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
9969 block= (uchar*)buf + total_header_len;
9970 block_len= len - total_header_len;
9971 DBUG_VOID_RETURN;
9972}
9973
9974
9975/*
9976 Append_block_log_event::write()
9977*/
9978
9979#ifndef MYSQL_CLIENT
9980bool Append_block_log_event::write()
9981{
9982 uchar buf[APPEND_BLOCK_HEADER_LEN];
9983 int4store(buf + AB_FILE_ID_OFFSET, file_id);
9984 return write_header(APPEND_BLOCK_HEADER_LEN + block_len) ||
9985 write_data(buf, APPEND_BLOCK_HEADER_LEN) ||
9986 write_data(block, block_len) ||
9987 write_footer();
9988}
9989#endif
9990
9991
9992/*
9993 Append_block_log_event::print()
9994*/
9995
9996#ifdef MYSQL_CLIENT
9997bool Append_block_log_event::print(FILE* file,
9998 PRINT_EVENT_INFO* print_event_info)
9999{
10000 if (print_event_info->short_form)
10001 return 0;
10002
10003 Write_on_release_cache cache(&print_event_info->head_cache, file);
10004
10005 if (print_header(&cache, print_event_info, FALSE) ||
10006 my_b_printf(&cache, "\n#%s: file_id: %d block_len: %d\n",
10007 get_type_str(), file_id, block_len))
10008 goto err;
10009
10010 return cache.flush_data();
10011err:
10012 return 1;
10013}
10014#endif /* MYSQL_CLIENT */
10015
10016
10017/*
10018 Append_block_log_event::pack_info()
10019*/
10020
10021#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10022void Append_block_log_event::pack_info(Protocol *protocol)
10023{
10024 char buf[256];
10025 uint length;
10026 length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id, block_len);
10027 protocol->store(buf, length, &my_charset_bin);
10028}
10029
10030
10031/*
10032 Append_block_log_event::get_create_or_append()
10033*/
10034
10035int Append_block_log_event::get_create_or_append() const
10036{
10037 return 0; /* append to the file, fail if not exists */
10038}
10039
10040/*
10041 Append_block_log_event::do_apply_event()
10042*/
10043
10044int Append_block_log_event::do_apply_event(rpl_group_info *rgi)
10045{
10046 char fname[FN_REFLEN];
10047 int fd;
10048 int error = 1;
10049 Relay_log_info const *rli= rgi->rli;
10050 DBUG_ENTER("Append_block_log_event::do_apply_event");
10051
10052 THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
10053 slave_load_file_stem(fname, file_id, server_id, ".data",
10054 &rli->mi->cmp_connection_name);
10055 if (get_create_or_append())
10056 {
10057 /*
10058 Usually lex_start() is called by mysql_parse(), but we need it here
10059 as the present method does not call mysql_parse().
10060 */
10061 lex_start(thd);
10062 thd->reset_for_next_command();
10063 /* old copy may exist already */
10064 mysql_file_delete(key_file_log_event_data, fname, MYF(0));
10065 if ((fd= mysql_file_create(key_file_log_event_data,
10066 fname, CREATE_MODE,
10067 O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
10068 MYF(MY_WME))) < 0)
10069 {
10070 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
10071 "Error in %s event: could not create file '%s'",
10072 get_type_str(), fname);
10073 goto err;
10074 }
10075 }
10076 else if ((fd= mysql_file_open(key_file_log_event_data,
10077 fname,
10078 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
10079 MYF(MY_WME))) < 0)
10080 {
10081 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
10082 "Error in %s event: could not open file '%s'",
10083 get_type_str(), fname);
10084 goto err;
10085 }
10086
10087 DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
10088 {
10089 my_delete(fname, MYF(0));
10090 });
10091
10092 if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
10093 {
10094 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
10095 "Error in %s event: write to '%s' failed",
10096 get_type_str(), fname);
10097 goto err;
10098 }
10099 error=0;
10100
10101err:
10102 if (fd >= 0)
10103 mysql_file_close(fd, MYF(0));
10104 DBUG_RETURN(error);
10105}
10106#endif
10107
10108
10109/**************************************************************************
10110 Delete_file_log_event methods
10111**************************************************************************/
10112
10113/*
10114 Delete_file_log_event ctor
10115*/
10116
10117#ifndef MYSQL_CLIENT
10118Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
10119 bool using_trans)
10120 :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
10121{
10122}
10123#endif
10124
10125/*
10126 Delete_file_log_event ctor
10127*/
10128
10129Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
10130 const Format_description_log_event* description_event)
10131 :Log_event(buf, description_event),file_id(0)
10132{
10133 uint8 common_header_len= description_event->common_header_len;
10134 uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
10135 if (len < (uint)(common_header_len + delete_file_header_len))
10136 return;
10137 file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
10138}
10139
10140
10141/*
10142 Delete_file_log_event::write()
10143*/
10144
10145#ifndef MYSQL_CLIENT
10146bool Delete_file_log_event::write()
10147{
10148 uchar buf[DELETE_FILE_HEADER_LEN];
10149 int4store(buf + DF_FILE_ID_OFFSET, file_id);
10150 return write_header(sizeof(buf)) ||
10151 write_data(buf, sizeof(buf)) ||
10152 write_footer();
10153}
10154#endif
10155
10156
10157/*
10158 Delete_file_log_event::print()
10159*/
10160
10161#ifdef MYSQL_CLIENT
10162bool Delete_file_log_event::print(FILE* file,
10163 PRINT_EVENT_INFO* print_event_info)
10164{
10165 if (print_event_info->short_form)
10166 return 0;
10167
10168 Write_on_release_cache cache(&print_event_info->head_cache, file);
10169
10170 if (print_header(&cache, print_event_info, FALSE) ||
10171 my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id))
10172 return 1;
10173
10174 return cache.flush_data();
10175}
10176#endif /* MYSQL_CLIENT */
10177
10178/*
10179 Delete_file_log_event::pack_info()
10180*/
10181
10182#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10183void Delete_file_log_event::pack_info(Protocol *protocol)
10184{
10185 char buf[64];
10186 uint length;
10187 length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
10188 protocol->store(buf, (int32) length, &my_charset_bin);
10189}
10190#endif
10191
10192/*
10193 Delete_file_log_event::do_apply_event()
10194*/
10195
10196#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10197int Delete_file_log_event::do_apply_event(rpl_group_info *rgi)
10198{
10199 char fname[FN_REFLEN+10];
10200 Relay_log_info const *rli= rgi->rli;
10201 char *ext= slave_load_file_stem(fname, file_id, server_id, ".data",
10202 &rli->mi->cmp_connection_name);
10203 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
10204 strmov(ext, ".info");
10205 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
10206 return 0;
10207}
10208#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
10209
10210
10211/**************************************************************************
10212 Execute_load_log_event methods
10213**************************************************************************/
10214
10215/*
10216 Execute_load_log_event ctor
10217*/
10218
10219#ifndef MYSQL_CLIENT
10220Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
10221 const char* db_arg,
10222 bool using_trans)
10223 :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
10224{
10225}
10226#endif
10227
10228
10229/*
10230 Execute_load_log_event ctor
10231*/
10232
10233Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
10234 const Format_description_log_event* description_event)
10235 :Log_event(buf, description_event), file_id(0)
10236{
10237 uint8 common_header_len= description_event->common_header_len;
10238 uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
10239 if (len < (uint)(common_header_len+exec_load_header_len))
10240 return;
10241 file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
10242}
10243
10244
10245/*
10246 Execute_load_log_event::write()
10247*/
10248
10249#ifndef MYSQL_CLIENT
10250bool Execute_load_log_event::write()
10251{
10252 uchar buf[EXEC_LOAD_HEADER_LEN];
10253 int4store(buf + EL_FILE_ID_OFFSET, file_id);
10254 return write_header(sizeof(buf)) ||
10255 write_data(buf, sizeof(buf)) ||
10256 write_footer();
10257}
10258#endif
10259
10260
10261/*
10262 Execute_load_log_event::print()
10263*/
10264
10265#ifdef MYSQL_CLIENT
10266bool Execute_load_log_event::print(FILE* file,
10267 PRINT_EVENT_INFO* print_event_info)
10268{
10269 if (print_event_info->short_form)
10270 return 0;
10271
10272 Write_on_release_cache cache(&print_event_info->head_cache, file);
10273
10274 if (print_header(&cache, print_event_info, FALSE) ||
10275 my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
10276 file_id))
10277 return 1;
10278
10279 return cache.flush_data();
10280}
10281#endif
10282
10283/*
10284 Execute_load_log_event::pack_info()
10285*/
10286
10287#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10288void Execute_load_log_event::pack_info(Protocol *protocol)
10289{
10290 char buf[64];
10291 uint length;
10292 length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
10293 protocol->store(buf, (int32) length, &my_charset_bin);
10294}
10295
10296
10297/*
10298 Execute_load_log_event::do_apply_event()
10299*/
10300
10301int Execute_load_log_event::do_apply_event(rpl_group_info *rgi)
10302{
10303 char fname[FN_REFLEN+10];
10304 char *ext;
10305 int fd;
10306 int error= 1;
10307 IO_CACHE file;
10308 Load_log_event *lev= 0;
10309 Relay_log_info const *rli= rgi->rli;
10310
10311 ext= slave_load_file_stem(fname, file_id, server_id, ".info",
10312 &rli->mi->cmp_connection_name);
10313 if ((fd= mysql_file_open(key_file_log_event_info,
10314 fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
10315 MYF(MY_WME))) < 0 ||
10316 init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
10317 MYF(MY_WME|MY_NABP)))
10318 {
10319 rli->report(ERROR_LEVEL, my_errno, rgi->gtid_info(),
10320 "Error in Exec_load event: could not open file '%s'",
10321 fname);
10322 goto err;
10323 }
10324 if (!(lev= (Load_log_event*)
10325 Log_event::read_log_event(&file,
10326 rli->relay_log.description_event_for_exec,
10327 opt_slave_sql_verify_checksum)) ||
10328 lev->get_type_code() != NEW_LOAD_EVENT)
10329 {
10330 rli->report(ERROR_LEVEL, 0, rgi->gtid_info(), "Error in Exec_load event: "
10331 "file '%s' appears corrupted", fname);
10332 goto err;
10333 }
10334 lev->thd = thd;
10335 /*
10336 lev->do_apply_event should use rli only for errors i.e. should
10337 not advance rli's position.
10338
10339 lev->do_apply_event is the place where the table is loaded (it
10340 calls mysql_load()).
10341 */
10342
10343 if (lev->do_apply_event(0,rgi,1))
10344 {
10345 /*
10346 We want to indicate the name of the file that could not be loaded
10347 (SQL_LOADxxx).
10348 But as we are here we are sure the error is in rli->last_slave_error and
10349 rli->last_slave_errno (example of error: duplicate entry for key), so we
10350 don't want to overwrite it with the filename.
10351 What we want instead is add the filename to the current error message.
10352 */
10353 char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
10354 if (tmp)
10355 {
10356 rli->report(ERROR_LEVEL, rli->last_error().number, rgi->gtid_info(),
10357 "%s. Failed executing load from '%s'", tmp, fname);
10358 my_free(tmp);
10359 }
10360 goto err;
10361 }
10362 /*
10363 We have an open file descriptor to the .info file; we need to close it
10364 or Windows will refuse to delete the file in mysql_file_delete().
10365 */
10366 if (fd >= 0)
10367 {
10368 mysql_file_close(fd, MYF(0));
10369 end_io_cache(&file);
10370 fd= -1;
10371 }
10372 mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
10373 memcpy(ext, ".data", 6);
10374 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
10375 error = 0;
10376
10377err:
10378 delete lev;
10379 if (fd >= 0)
10380 {
10381 mysql_file_close(fd, MYF(0));
10382 end_io_cache(&file);
10383 }
10384 return error;
10385}
10386
10387#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
10388
10389
10390/**************************************************************************
10391 Begin_load_query_log_event methods
10392**************************************************************************/
10393
10394#ifndef MYSQL_CLIENT
10395Begin_load_query_log_event::
10396Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
10397 uint block_len_arg, bool using_trans)
10398 :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
10399 using_trans)
10400{
10401 file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
10402}
10403#endif
10404
10405
10406Begin_load_query_log_event::
10407Begin_load_query_log_event(const char* buf, uint len,
10408 const Format_description_log_event* desc_event)
10409 :Append_block_log_event(buf, len, desc_event)
10410{
10411}
10412
10413
10414#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10415int Begin_load_query_log_event::get_create_or_append() const
10416{
10417 return 1; /* create the file */
10418}
10419#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
10420
10421
10422#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10423Log_event::enum_skip_reason
10424Begin_load_query_log_event::do_shall_skip(rpl_group_info *rgi)
10425{
10426 /*
10427 If the slave skip counter is 1, then we should not start executing
10428 on the next event.
10429 */
10430 return continue_group(rgi);
10431}
10432#endif
10433
10434
10435/**************************************************************************
10436 Execute_load_query_log_event methods
10437**************************************************************************/
10438
10439
10440#ifndef MYSQL_CLIENT
10441Execute_load_query_log_event::
10442Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
10443 ulong query_length_arg, uint fn_pos_start_arg,
10444 uint fn_pos_end_arg,
10445 enum_load_dup_handling dup_handling_arg,
10446 bool using_trans, bool direct, bool suppress_use,
10447 int errcode):
10448 Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, direct,
10449 suppress_use, errcode),
10450 file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
10451 fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
10452{
10453}
10454#endif /* !MYSQL_CLIENT */
10455
10456
10457Execute_load_query_log_event::
10458Execute_load_query_log_event(const char* buf, uint event_len,
10459 const Format_description_log_event* desc_event):
10460 Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
10461 file_id(0), fn_pos_start(0), fn_pos_end(0)
10462{
10463 if (!Query_log_event::is_valid())
10464 return;
10465
10466 buf+= desc_event->common_header_len;
10467
10468 fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
10469 fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
10470 dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
10471
10472 if (fn_pos_start > q_len || fn_pos_end > q_len ||
10473 dup_handling > LOAD_DUP_REPLACE)
10474 return;
10475
10476 file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
10477}
10478
10479
10480ulong Execute_load_query_log_event::get_post_header_size_for_derived()
10481{
10482 return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
10483}
10484
10485
10486#ifndef MYSQL_CLIENT
10487bool
10488Execute_load_query_log_event::write_post_header_for_derived()
10489{
10490 uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
10491 int4store(buf, file_id);
10492 int4store(buf + 4, fn_pos_start);
10493 int4store(buf + 4 + 4, fn_pos_end);
10494 *(buf + 4 + 4 + 4)= (uchar) dup_handling;
10495 return write_data(buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
10496}
10497#endif
10498
10499
10500#ifdef MYSQL_CLIENT
10501bool Execute_load_query_log_event::print(FILE* file,
10502 PRINT_EVENT_INFO* print_event_info)
10503{
10504 return print(file, print_event_info, 0);
10505}
10506
10507/**
10508 Prints the query as LOAD DATA LOCAL and with rewritten filename.
10509*/
10510bool Execute_load_query_log_event::print(FILE* file,
10511 PRINT_EVENT_INFO* print_event_info,
10512 const char *local_fname)
10513{
10514 Write_on_release_cache cache(&print_event_info->head_cache, file);
10515
10516 if (print_query_header(&cache, print_event_info))
10517 goto err;
10518
10519 /**
10520 reduce the size of io cache so that the write function is called
10521 for every call to my_b_printf().
10522 */
10523 DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
10524 {(&cache)->write_pos= (&cache)->write_end;
10525 DBUG_SET("+d,simulate_file_write_error");});
10526
10527 if (local_fname)
10528 {
10529 if (my_b_write(&cache, (uchar*) query, fn_pos_start) ||
10530 my_b_write_string(&cache, " LOCAL INFILE ") ||
10531 pretty_print_str(&cache, local_fname, (int)strlen(local_fname)))
10532 goto err;
10533
10534 if (dup_handling == LOAD_DUP_REPLACE)
10535 if (my_b_write_string(&cache, " REPLACE"))
10536 goto err;
10537
10538 if (my_b_write_string(&cache, " INTO") ||
10539 my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end) ||
10540 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
10541 goto err;
10542 }
10543 else
10544 {
10545 if (my_b_write(&cache, (uchar*) query, q_len) ||
10546 my_b_printf(&cache, "\n%s\n", print_event_info->delimiter))
10547 goto err;
10548 }
10549
10550 if (!print_event_info->short_form)
10551 my_b_printf(&cache, "# file_id: %d \n", file_id);
10552
10553 return cache.flush_data();
10554err:
10555 return 1;
10556}
10557#endif
10558
10559
10560#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
10561void Execute_load_query_log_event::pack_info(Protocol *protocol)
10562{
10563 char buf_mem[1024];
10564 String buf(buf_mem, sizeof(buf_mem), system_charset_info);
10565 buf.real_alloc(9 + db_len + q_len + 10 + 21);
10566 if (db && db_len)
10567 {
10568 if (buf.append(STRING_WITH_LEN("use ")) ||
10569 append_identifier(protocol->thd, &buf, db, db_len) ||
10570 buf.append(STRING_WITH_LEN("; ")))
10571 return;
10572 }
10573 if (query && q_len && buf.append(query, q_len))
10574 return;
10575 if (buf.append(" ;file_id=") ||
10576 buf.append_ulonglong(file_id))
10577 return;
10578 protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
10579}
10580
10581
10582int
10583Execute_load_query_log_event::do_apply_event(rpl_group_info *rgi)
10584{
10585 char *p;
10586 char *buf;
10587 char *fname;
10588 char *fname_end;
10589 int error;
10590 Relay_log_info const *rli= rgi->rli;
10591
10592 buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
10593 (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
10594
10595 DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
10596
10597 /* Replace filename and LOCAL keyword in query before executing it */
10598 if (buf == NULL)
10599 {
10600 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(),
10601 ER_THD(rgi->thd, ER_SLAVE_FATAL_ERROR), "Not enough memory");
10602 return 1;
10603 }
10604
10605 p= buf;
10606 memcpy(p, query, fn_pos_start);
10607 p+= fn_pos_start;
10608 fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
10609 p= slave_load_file_stem(p, file_id, server_id, ".data",
10610 &rli->mi->cmp_connection_name);
10611 fname_end= p= strend(p); // Safer than p=p+5
10612 *(p++)='\'';
10613 switch (dup_handling) {
10614 case LOAD_DUP_IGNORE:
10615 p= strmake(p, STRING_WITH_LEN(" IGNORE"));
10616 break;
10617 case LOAD_DUP_REPLACE:
10618 p= strmake(p, STRING_WITH_LEN(" REPLACE"));
10619 break;
10620 default:
10621 /* Ordinary load data */
10622 break;
10623 }
10624 p= strmake(p, STRING_WITH_LEN(" INTO "));
10625 p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
10626
10627 error= Query_log_event::do_apply_event(rgi, buf, (uint32)(p-buf));
10628
10629 /* Forging file name for deletion in same buffer */
10630 *fname_end= 0;
10631
10632 /*
10633 If there was an error the slave is going to stop, leave the
10634 file so that we can re-execute this event at START SLAVE.
10635 */
10636 if (unlikely(!error))
10637 mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
10638
10639 my_free(buf);
10640 return error;
10641}
10642#endif
10643
10644
10645/**************************************************************************
10646 sql_ex_info methods
10647**************************************************************************/
10648
10649/*
10650 sql_ex_info::init()
10651*/
10652
10653const char *sql_ex_info::init(const char *buf, const char *buf_end,
10654 bool use_new_format)
10655{
10656 cached_new_format = use_new_format;
10657 if (use_new_format)
10658 {
10659 empty_flags=0;
10660 /*
10661 The code below assumes that buf will not disappear from
10662 under our feet during the lifetime of the event. This assumption
10663 holds true in the slave thread if the log is in new format, but is not
10664 the case when we have old format because we will be reusing net buffer
10665 to read the actual file before we write out the Create_file event.
10666 */
10667 if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
10668 read_str(&buf, buf_end, &enclosed, &enclosed_len) ||
10669 read_str(&buf, buf_end, &line_term, &line_term_len) ||
10670 read_str(&buf, buf_end, &line_start, &line_start_len) ||
10671 read_str(&buf, buf_end, &escaped, &escaped_len))
10672 return 0;
10673 opt_flags = *buf++;
10674 }
10675 else
10676 {
10677 field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
10678 field_term = buf++; // Use first byte in string
10679 enclosed= buf++;
10680 line_term= buf++;
10681 line_start= buf++;
10682 escaped= buf++;
10683 opt_flags = *buf++;
10684 empty_flags= *buf++;
10685 if (empty_flags & FIELD_TERM_EMPTY)
10686 field_term_len=0;
10687 if (empty_flags & ENCLOSED_EMPTY)
10688 enclosed_len=0;
10689 if (empty_flags & LINE_TERM_EMPTY)
10690 line_term_len=0;
10691 if (empty_flags & LINE_START_EMPTY)
10692 line_start_len=0;
10693 if (empty_flags & ESCAPED_EMPTY)
10694 escaped_len=0;
10695 }
10696 return buf;
10697}
10698
10699#ifndef MYSQL_CLIENT
10700/*
10701 write_str()
10702*/
10703
10704static bool write_str(Log_event_writer *writer, const char *str, uint length)
10705{
10706 uchar tmp[1];
10707 tmp[0]= (uchar) length;
10708 return (writer->write_data(tmp, sizeof(tmp)) ||
10709 writer->write_data((uchar*) str, length));
10710}
10711
10712/*
10713 sql_ex_info::write_data()
10714*/
10715
10716bool sql_ex_info::write_data(Log_event_writer *writer)
10717{
10718 if (new_format())
10719 {
10720 return write_str(writer, field_term, field_term_len) ||
10721 write_str(writer, enclosed, enclosed_len) ||
10722 write_str(writer, line_term, line_term_len) ||
10723 write_str(writer, line_start, line_start_len) ||
10724 write_str(writer, escaped, escaped_len) ||
10725 writer->write_data((uchar*) &opt_flags, 1);
10726 }
10727 else
10728 {
10729 uchar old_ex[7];
10730 old_ex[0]= *field_term;
10731 old_ex[1]= *enclosed;
10732 old_ex[2]= *line_term;
10733 old_ex[3]= *line_start;
10734 old_ex[4]= *escaped;
10735 old_ex[5]= opt_flags;
10736 old_ex[6]= empty_flags;
10737 return writer->write_data(old_ex, sizeof(old_ex));
10738 }
10739}
10740
10741
10742
10743/**************************************************************************
10744 Rows_log_event member functions
10745**************************************************************************/
10746
10747Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
10748 MY_BITMAP const *cols, bool is_transactional,
10749 Log_event_type event_type)
10750 : Log_event(thd_arg, 0, is_transactional),
10751 m_row_count(0),
10752 m_table(tbl_arg),
10753 m_table_id(tid),
10754 m_width(tbl_arg ? tbl_arg->s->fields : 1),
10755 m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
10756 m_type(event_type), m_extra_row_data(0)
10757#ifdef HAVE_REPLICATION
10758 , m_curr_row(NULL), m_curr_row_end(NULL),
10759 m_key(NULL), m_key_info(NULL), m_key_nr(0),
10760 master_had_triggers(0)
10761#endif
10762{
10763 /*
10764 We allow a special form of dummy event when the table, and cols
10765 are null and the table id is ~0UL. This is a temporary
10766 solution, to be able to terminate a started statement in the
10767 binary log: the extraneous events will be removed in the future.
10768 */
10769 DBUG_ASSERT((tbl_arg && tbl_arg->s && tid != ~0UL) ||
10770 (!tbl_arg && !cols && tid == ~0UL));
10771
10772 if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
10773 set_flags(NO_FOREIGN_KEY_CHECKS_F);
10774 if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
10775 set_flags(RELAXED_UNIQUE_CHECKS_F);
10776 if (thd_arg->variables.option_bits & OPTION_NO_CHECK_CONSTRAINT_CHECKS)
10777 set_flags(NO_CHECK_CONSTRAINT_CHECKS_F);
10778 /* if my_bitmap_init fails, caught in is_valid() */
10779 if (likely(!my_bitmap_init(&m_cols,
10780 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
10781 m_width,
10782 false)))
10783 {
10784 /* Cols can be zero if this is a dummy binrows event */
10785 if (likely(cols != NULL))
10786 {
10787 memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
10788 create_last_word_mask(&m_cols);
10789 }
10790 }
10791 else
10792 {
10793 // Needed because my_bitmap_init() does not set it to null on failure
10794 m_cols.bitmap= 0;
10795 }
10796}
10797#endif
10798
10799Rows_log_event::Rows_log_event(const char *buf, uint event_len,
10800 const Format_description_log_event
10801 *description_event)
10802 : Log_event(buf, description_event),
10803 m_row_count(0),
10804#ifndef MYSQL_CLIENT
10805 m_table(NULL),
10806#endif
10807 m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
10808 m_extra_row_data(0)
10809#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10810 , m_curr_row(NULL), m_curr_row_end(NULL),
10811 m_key(NULL), m_key_info(NULL), m_key_nr(0),
10812 master_had_triggers(0)
10813#endif
10814{
10815 DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
10816 uint8 const common_header_len= description_event->common_header_len;
10817 Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET];
10818 m_type= event_type;
10819
10820 uint8 const post_header_len= description_event->post_header_len[event_type-1];
10821
10822 DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
10823 "post_header_len: %d",
10824 event_len, common_header_len,
10825 post_header_len));
10826
10827 const char *post_start= buf + common_header_len;
10828 post_start+= RW_MAPID_OFFSET;
10829 if (post_header_len == 6)
10830 {
10831 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
10832 m_table_id= uint4korr(post_start);
10833 post_start+= 4;
10834 }
10835 else
10836 {
10837 m_table_id= (ulong) uint6korr(post_start);
10838 post_start+= RW_FLAGS_OFFSET;
10839 }
10840
10841 m_flags_pos= post_start - buf;
10842 m_flags= uint2korr(post_start);
10843 post_start+= 2;
10844
10845 uint16 var_header_len= 0;
10846 if (post_header_len == ROWS_HEADER_LEN_V2)
10847 {
10848 /*
10849 Have variable length header, check length,
10850 which includes length bytes
10851 */
10852 var_header_len= uint2korr(post_start);
10853 assert(var_header_len >= 2);
10854 var_header_len-= 2;
10855
10856 /* Iterate over var-len header, extracting 'chunks' */
10857 const char* start= post_start + 2;
10858 const char* end= start + var_header_len;
10859 for (const char* pos= start; pos < end;)
10860 {
10861 switch(*pos++)
10862 {
10863 case RW_V_EXTRAINFO_TAG:
10864 {
10865 /* Have an 'extra info' section, read it in */
10866 assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
10867 uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
10868 assert((end - pos) >= infoLen);
10869 /* Just store/use the first tag of this type, skip others */
10870 if (likely(!m_extra_row_data))
10871 {
10872 m_extra_row_data= (uchar*) my_malloc(infoLen,
10873 MYF(MY_WME));
10874 if (likely(m_extra_row_data != NULL))
10875 {
10876 memcpy(m_extra_row_data, pos, infoLen);
10877 }
10878 }
10879 pos+= infoLen;
10880 break;
10881 }
10882 default:
10883 /* Unknown code, we will not understand anything further here */
10884 pos= end; /* Break loop */
10885 }
10886 }
10887 }
10888
10889 uchar const *const var_start=
10890 (const uchar *)buf + common_header_len + post_header_len + var_header_len;
10891 uchar const *const ptr_width= var_start;
10892 uchar *ptr_after_width= (uchar*) ptr_width;
10893 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
10894 m_width = net_field_length(&ptr_after_width);
10895 DBUG_PRINT("debug", ("m_width=%lu", m_width));
10896
10897 /* Avoid reading out of buffer */
10898 if (ptr_after_width + (m_width + 7) / 8 > (uchar*)buf + event_len)
10899 {
10900 m_cols.bitmap= NULL;
10901 DBUG_VOID_RETURN;
10902 }
10903
10904 /* if my_bitmap_init fails, catched in is_valid() */
10905 if (likely(!my_bitmap_init(&m_cols,
10906 m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
10907 m_width,
10908 false)))
10909 {
10910 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
10911 memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
10912 create_last_word_mask(&m_cols);
10913 ptr_after_width+= (m_width + 7) / 8;
10914 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
10915 }
10916 else
10917 {
10918 // Needed because my_bitmap_init() does not set it to null on failure
10919 m_cols.bitmap= NULL;
10920 DBUG_VOID_RETURN;
10921 }
10922
10923 m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
10924
10925 if (LOG_EVENT_IS_UPDATE_ROW(event_type))
10926 {
10927 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
10928
10929 /* if my_bitmap_init fails, caught in is_valid() */
10930 if (likely(!my_bitmap_init(&m_cols_ai,
10931 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
10932 m_width,
10933 false)))
10934 {
10935 DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
10936 memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
10937 create_last_word_mask(&m_cols_ai);
10938 ptr_after_width+= (m_width + 7) / 8;
10939 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
10940 no_bytes_in_map(&m_cols_ai));
10941 }
10942 else
10943 {
10944 // Needed because my_bitmap_init() does not set it to null on failure
10945 m_cols_ai.bitmap= 0;
10946 DBUG_VOID_RETURN;
10947 }
10948 }
10949
10950 const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
10951
10952 size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
10953 if (read_size > event_len)
10954 {
10955 DBUG_VOID_RETURN;
10956 }
10957 size_t const data_size= event_len - read_size;
10958 DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu",
10959 m_table_id, m_flags, m_width, (ulong) data_size));
10960
10961 m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
10962 if (likely((bool)m_rows_buf))
10963 {
10964#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10965 m_curr_row= m_rows_buf;
10966#endif
10967 m_rows_end= m_rows_buf + data_size;
10968 m_rows_cur= m_rows_end;
10969 memcpy(m_rows_buf, ptr_rows_data, data_size);
10970 m_rows_before_size= ptr_rows_data - (const uchar *) buf; // Get the size that before SET part
10971 }
10972 else
10973 m_cols.bitmap= 0; // to not free it
10974
10975 DBUG_VOID_RETURN;
10976}
10977
10978void Rows_log_event::uncompress_buf()
10979{
10980 uint32 un_len = binlog_get_uncompress_len((char *)m_rows_buf);
10981 if (!un_len)
10982 return;
10983
10984 uchar *new_buf= (uchar*) my_malloc(ALIGN_SIZE(un_len), MYF(MY_WME));
10985 if (new_buf)
10986 {
10987 if(!binlog_buf_uncompress((char *)m_rows_buf, (char *)new_buf,
10988 (uint32)(m_rows_cur - m_rows_buf), &un_len))
10989 {
10990 my_free(m_rows_buf);
10991 m_rows_buf = new_buf;
10992#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
10993 m_curr_row= m_rows_buf;
10994#endif
10995 m_rows_end= m_rows_buf + un_len;
10996 m_rows_cur= m_rows_end;
10997 return;
10998 }
10999 else
11000 {
11001 my_free(new_buf);
11002 }
11003 }
11004 m_cols.bitmap= 0; // catch it in is_valid
11005}
11006
11007Rows_log_event::~Rows_log_event()
11008{
11009 if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
11010 m_cols.bitmap= 0; // so no my_free in my_bitmap_free
11011 my_bitmap_free(&m_cols); // To pair with my_bitmap_init().
11012 my_free(m_rows_buf);
11013 my_free(m_extra_row_data);
11014}
11015
11016int Rows_log_event::get_data_size()
11017{
11018 int const general_type_code= get_general_type_code();
11019
11020 uchar buf[MAX_INT_WIDTH];
11021 uchar *end= net_store_length(buf, m_width);
11022
11023 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11024 return (int)(6 + no_bytes_in_map(&m_cols) + (end - buf) +
11025 (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
11026 m_rows_cur - m_rows_buf););
11027
11028 int data_size= 0;
11029 Log_event_type type = get_type_code();
11030 bool is_v2_event= LOG_EVENT_IS_ROW_V2(type);
11031 if (is_v2_event)
11032 {
11033 data_size= ROWS_HEADER_LEN_V2 +
11034 (m_extra_row_data ?
11035 RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
11036 0);
11037 }
11038 else
11039 {
11040 data_size= ROWS_HEADER_LEN_V1;
11041 }
11042 data_size+= no_bytes_in_map(&m_cols);
11043 data_size+= (uint) (end - buf);
11044
11045 if (general_type_code == UPDATE_ROWS_EVENT)
11046 data_size+= no_bytes_in_map(&m_cols_ai);
11047
11048 data_size+= (uint) (m_rows_cur - m_rows_buf);
11049 return data_size;
11050}
11051
11052
11053#ifndef MYSQL_CLIENT
11054int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
11055{
11056 /*
11057 When the table has a primary key, we would probably want, by default, to
11058 log only the primary key value instead of the entire "before image". This
11059 would save binlog space. TODO
11060 */
11061 DBUG_ENTER("Rows_log_event::do_add_row_data");
11062 DBUG_PRINT("enter", ("row_data:%p length: %lu", row_data,
11063 (ulong) length));
11064
11065 /*
11066 If length is zero, there is nothing to write, so we just
11067 return. Note that this is not an optimization, since calling
11068 realloc() with size 0 means free().
11069 */
11070 if (length == 0)
11071 {
11072 m_row_count++;
11073 DBUG_RETURN(0);
11074 }
11075
11076 /*
11077 Don't print debug messages when running valgrind since they can
11078 trigger false warnings.
11079 */
11080#ifndef HAVE_valgrind
11081 DBUG_DUMP("row_data", row_data, MY_MIN(length, 32));
11082#endif
11083
11084 DBUG_ASSERT(m_rows_buf <= m_rows_cur);
11085 DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
11086 DBUG_ASSERT(m_rows_cur <= m_rows_end);
11087
11088 /* The cast will always work since m_rows_cur <= m_rows_end */
11089 if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
11090 {
11091 size_t const block_size= 1024;
11092 size_t cur_size= m_rows_cur - m_rows_buf;
11093 DBUG_EXECUTE_IF("simulate_too_big_row_case1",
11094 cur_size= UINT_MAX32 - (block_size * 10);
11095 length= UINT_MAX32 - (block_size * 10););
11096 DBUG_EXECUTE_IF("simulate_too_big_row_case2",
11097 cur_size= UINT_MAX32 - (block_size * 10);
11098 length= block_size * 10;);
11099 DBUG_EXECUTE_IF("simulate_too_big_row_case3",
11100 cur_size= block_size * 10;
11101 length= UINT_MAX32 - (block_size * 10););
11102 DBUG_EXECUTE_IF("simulate_too_big_row_case4",
11103 cur_size= UINT_MAX32 - (block_size * 10);
11104 length= (block_size * 10) - block_size + 1;);
11105 size_t remaining_space= UINT_MAX32 - cur_size;
11106 /* Check that the new data fits within remaining space and we can add
11107 block_size without wrapping.
11108 */
11109 if (cur_size > UINT_MAX32 || length > remaining_space ||
11110 ((length + block_size) > remaining_space))
11111 {
11112 sql_print_error("The row data is greater than 4GB, which is too big to "
11113 "write to the binary log.");
11114 DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
11115 }
11116 size_t const new_alloc=
11117 block_size * ((cur_size + length + block_size - 1) / block_size);
11118
11119 uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, new_alloc,
11120 MYF(MY_ALLOW_ZERO_PTR|MY_WME));
11121 if (unlikely(!new_buf))
11122 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
11123
11124 /* If the memory moved, we need to move the pointers */
11125 if (new_buf != m_rows_buf)
11126 {
11127 m_rows_buf= new_buf;
11128 m_rows_cur= m_rows_buf + cur_size;
11129 }
11130
11131 /*
11132 The end pointer should always be changed to point to the end of
11133 the allocated memory.
11134 */
11135 m_rows_end= m_rows_buf + new_alloc;
11136 }
11137
11138 DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
11139 memcpy(m_rows_cur, row_data, length);
11140 m_rows_cur+= length;
11141 m_row_count++;
11142 DBUG_RETURN(0);
11143}
11144#endif
11145
11146#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
11147
11148/**
11149 Restores empty table list as it was before trigger processing.
11150
11151 @note We have a lot of ASSERTS that check the lists when we close tables.
11152 There was the same problem with MERGE MYISAM tables and so here we try to
11153 go the same way.
11154*/
11155static void restore_empty_query_table_list(LEX *lex)
11156{
11157 if (lex->first_not_own_table())
11158 (*lex->first_not_own_table()->prev_global)= NULL;
11159 lex->query_tables= NULL;
11160 lex->query_tables_last= &lex->query_tables;
11161}
11162
11163
11164int Rows_log_event::do_apply_event(rpl_group_info *rgi)
11165{
11166 Relay_log_info const *rli= rgi->rli;
11167 TABLE* table;
11168 DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
11169 int error= 0;
11170 /*
11171 If m_table_id == ~0UL, then we have a dummy event that does not
11172 contain any data. In that case, we just remove all tables in the
11173 tables_to_lock list, close the thread tables, and return with
11174 success.
11175 */
11176 if (m_table_id == ~0UL)
11177 {
11178 /*
11179 This one is supposed to be set: just an extra check so that
11180 nothing strange has happened.
11181 */
11182 DBUG_ASSERT(get_flags(STMT_END_F));
11183
11184 rgi->slave_close_thread_tables(thd);
11185 thd->clear_error();
11186 DBUG_RETURN(0);
11187 }
11188
11189 /*
11190 'thd' has been set by exec_relay_log_event(), just before calling
11191 do_apply_event(). We still check here to prevent future coding
11192 errors.
11193 */
11194 DBUG_ASSERT(rgi->thd == thd);
11195
11196 /*
11197 If there is no locks taken, this is the first binrow event seen
11198 after the table map events. We should then lock all the tables
11199 used in the transaction and proceed with execution of the actual
11200 event.
11201 */
11202 if (!thd->lock)
11203 {
11204 /*
11205 Lock_tables() reads the contents of thd->lex, so they must be
11206 initialized.
11207
11208 We also call the THD::reset_for_next_command(), since this
11209 is the logical start of the next "statement". Note that this
11210 call might reset the value of current_stmt_binlog_format, so
11211 we need to do any changes to that value after this function.
11212 */
11213 delete_explain_query(thd->lex);
11214 lex_start(thd);
11215 thd->reset_for_next_command();
11216 /*
11217 The current statement is just about to begin and
11218 has not yet modified anything. Note, all.modified is reset
11219 by THD::reset_for_next_command().
11220 */
11221 thd->transaction.stmt.modified_non_trans_table= FALSE;
11222 thd->transaction.stmt.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
11223 /*
11224 This is a row injection, so we flag the "statement" as
11225 such. Note that this code is called both when the slave does row
11226 injections and when the BINLOG statement is used to do row
11227 injections.
11228 */
11229 thd->lex->set_stmt_row_injection();
11230
11231 /*
11232 There are a few flags that are replicated with each row event.
11233 Make sure to set/clear them before executing the main body of
11234 the event.
11235 */
11236 if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
11237 thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
11238 else
11239 thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
11240
11241 if (get_flags(RELAXED_UNIQUE_CHECKS_F))
11242 thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
11243 else
11244 thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
11245
11246 if (get_flags(NO_CHECK_CONSTRAINT_CHECKS_F))
11247 thd->variables.option_bits|= OPTION_NO_CHECK_CONSTRAINT_CHECKS;
11248 else
11249 thd->variables.option_bits&= ~OPTION_NO_CHECK_CONSTRAINT_CHECKS;
11250
11251 /* A small test to verify that objects have consistent types */
11252 DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
11253
11254 if (slave_run_triggers_for_rbr)
11255 {
11256 LEX *lex= thd->lex;
11257 uint8 new_trg_event_map= get_trg_event_map();
11258
11259 /*
11260 Trigger's procedures work with global table list. So we have to add
11261 rgi->tables_to_lock content there to get trigger's in the list.
11262
11263 Then restore_empty_query_table_list() restore the list as it was
11264 */
11265 DBUG_ASSERT(lex->query_tables == NULL);
11266 if ((lex->query_tables= rgi->tables_to_lock))
11267 rgi->tables_to_lock->prev_global= &lex->query_tables;
11268
11269 for (TABLE_LIST *tables= rgi->tables_to_lock; tables;
11270 tables= tables->next_global)
11271 {
11272 tables->trg_event_map= new_trg_event_map;
11273 lex->query_tables_last= &tables->next_global;
11274 }
11275 }
11276 if (unlikely(open_and_lock_tables(thd, rgi->tables_to_lock, FALSE, 0)))
11277 {
11278 uint actual_error= thd->get_stmt_da()->sql_errno();
11279#ifdef WITH_WSREP
11280 if (WSREP(thd))
11281 {
11282 WSREP_WARN("BF applier failed to open_and_lock_tables: %u, fatal: %d "
11283 "wsrep = (exec_mode: %d conflict_state: %d seqno: %lld)",
11284 thd->get_stmt_da()->sql_errno(),
11285 thd->is_fatal_error,
11286 thd->wsrep_exec_mode,
11287 thd->wsrep_conflict_state,
11288 (long long)wsrep_thd_trx_seqno(thd));
11289 }
11290#endif
11291 if ((thd->is_slave_error || thd->is_fatal_error) &&
11292 !is_parallel_retry_error(rgi, actual_error))
11293 {
11294 /*
11295 Error reporting borrowed from Query_log_event with many excessive
11296 simplifications.
11297 We should not honour --slave-skip-errors at this point as we are
11298 having severe errors which should not be skiped.
11299 */
11300 rli->report(ERROR_LEVEL, actual_error, rgi->gtid_info(),
11301 "Error executing row event: '%s'",
11302 (actual_error ? thd->get_stmt_da()->message() :
11303 "unexpected success or fatal error"));
11304 thd->is_slave_error= 1;
11305 }
11306 /* remove trigger's tables */
11307 error= actual_error;
11308 goto err;
11309 }
11310
11311 /*
11312 When the open and locking succeeded, we check all tables to
11313 ensure that they still have the correct type.
11314 */
11315
11316 {
11317 DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
11318 rgi->tables_to_lock));
11319
11320 /**
11321 When using RBR and MyISAM MERGE tables the base tables that make
11322 up the MERGE table can be appended to the list of tables to lock.
11323
11324 Thus, we just check compatibility for those that tables that have
11325 a correspondent table map event (ie, those that are actually going
11326 to be accessed while applying the event). That's why the loop stops
11327 at rli->tables_to_lock_count .
11328
11329 NOTE: The base tables are added here are removed when
11330 close_thread_tables is called.
11331 */
11332 TABLE_LIST *table_list_ptr= rgi->tables_to_lock;
11333 for (uint i=0 ; table_list_ptr && (i < rgi->tables_to_lock_count);
11334 table_list_ptr= table_list_ptr->next_global, i++)
11335 {
11336 /*
11337 Below if condition takes care of skipping base tables that
11338 make up the MERGE table (which are added by open_tables()
11339 call). They are added next to the merge table in the list.
11340 For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
11341 are base tables for merge table 't3'), open_tables will modify
11342 the list by adding t1 and t2 again immediately after t3 in the
11343 list (*not at the end of the list*). New table_to_lock list will
11344 look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
11345 objects added by open_tables() call). There is no flag(or logic) in
11346 open_tables() that can skip adding these base tables to the list.
11347 So the logic here should take care of skipping them.
11348
11349 tables_to_lock_count logic will take care of skipping base tables
11350 that are added at the end of the list.
11351 For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
11352 the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
11353 because tables_to_lock_count logic in this for loop.
11354 */
11355 if (table_list_ptr->parent_l)
11356 continue;
11357 /*
11358 We can use a down cast here since we know that every table added
11359 to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
11360 skipped above).
11361 */
11362 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
11363 DBUG_ASSERT(ptr->m_tabledef_valid);
11364 TABLE *conv_table;
11365 if (!ptr->m_tabledef.compatible_with(thd, rgi, ptr->table, &conv_table))
11366 {
11367 DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
11368 ptr->table->s->db.str,
11369 ptr->table->s->table_name.str));
11370 /*
11371 We should not honour --slave-skip-errors at this point as we are
11372 having severe errors which should not be skiped.
11373 */
11374 thd->is_slave_error= 1;
11375 /* remove trigger's tables */
11376 error= ERR_BAD_TABLE_DEF;
11377 goto err;
11378 }
11379 DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
11380 " - conv_table: %p",
11381 ptr->table->s->db.str,
11382 ptr->table->s->table_name.str, conv_table));
11383 ptr->m_conv_table= conv_table;
11384 }
11385 }
11386
11387 /*
11388 ... and then we add all the tables to the table map and but keep
11389 them in the tables to lock list.
11390
11391 We also invalidate the query cache for all the tables, since
11392 they will now be changed.
11393
11394 TODO [/Matz]: Maybe the query cache should not be invalidated
11395 here? It might be that a table is not changed, even though it
11396 was locked for the statement. We do know that each
11397 Rows_log_event contain at least one row, so after processing one
11398 Rows_log_event, we can invalidate the query cache for the
11399 associated table.
11400 */
11401 TABLE_LIST *ptr= rgi->tables_to_lock;
11402 for (uint i=0 ; ptr && (i < rgi->tables_to_lock_count); ptr= ptr->next_global, i++)
11403 {
11404 /*
11405 Please see comment in above 'for' loop to know the reason
11406 for this if condition
11407 */
11408 if (ptr->parent_l)
11409 continue;
11410 rgi->m_table_map.set_table(ptr->table_id, ptr->table);
11411 /*
11412 Following is passing flag about triggers on the server. The problem was
11413 to pass it between table map event and row event. I do it via extended
11414 TABLE_LIST (RPL_TABLE_LIST) but row event uses only TABLE so I need to
11415 find somehow the corresponding TABLE_LIST.
11416 */
11417 if (m_table_id == ptr->table_id)
11418 {
11419 ptr->table->master_had_triggers=
11420 ((RPL_TABLE_LIST*)ptr)->master_had_triggers;
11421 }
11422 }
11423
11424#ifdef HAVE_QUERY_CACHE
11425#ifdef WITH_WSREP
11426 /*
11427 Moved invalidation right before the call to rows_event_stmt_cleanup(),
11428 to avoid query cache being polluted with stale entries.
11429 */
11430 if (! (WSREP(thd) && (thd->wsrep_exec_mode == REPL_RECV)))
11431 {
11432#endif /* WITH_WSREP */
11433 query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
11434#ifdef WITH_WSREP
11435 }
11436#endif /* WITH_WSREP */
11437#endif
11438 }
11439
11440 table= m_table= rgi->m_table_map.get_table(m_table_id);
11441
11442 DBUG_PRINT("debug", ("m_table:%p, m_table_id: %lu%s",
11443 m_table, m_table_id,
11444 table && master_had_triggers ?
11445 " (master had triggers)" : ""));
11446 if (table)
11447 {
11448 master_had_triggers= table->master_had_triggers;
11449 bool transactional_table= table->file->has_transactions();
11450 /*
11451 table == NULL means that this table should not be replicated
11452 (this was set up by Table_map_log_event::do_apply_event()
11453 which tested replicate-* rules).
11454 */
11455
11456 /*
11457 It's not needed to set_time() but
11458 1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11459 much slave is behind
11460 2) it will be needed when we allow replication from a table with no
11461 TIMESTAMP column to a table with one.
11462 So we call set_time(), like in SBR. Presently it changes nothing.
11463 */
11464 thd->set_time(when, when_sec_part);
11465
11466 if (m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11467 set_flags(COMPLETE_ROWS_F);
11468
11469 /*
11470 Set tables write and read sets.
11471
11472 Read_set contains all slave columns (in case we are going to fetch
11473 a complete record from slave)
11474
11475 Write_set equals the m_cols bitmap sent from master but it can be
11476 longer if slave has extra columns.
11477 */
11478
11479 DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11480
11481 bitmap_set_all(table->read_set);
11482 if (get_general_type_code() == DELETE_ROWS_EVENT ||
11483 get_general_type_code() == UPDATE_ROWS_EVENT)
11484 bitmap_intersect(table->read_set,&m_cols);
11485
11486 bitmap_set_all(table->write_set);
11487 table->rpl_write_set= table->write_set;
11488
11489 /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11490 MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
11491 &m_cols_ai : &m_cols);
11492 bitmap_intersect(table->write_set, after_image);
11493
11494 this->slave_exec_mode= slave_exec_mode_options; // fix the mode
11495
11496 // Do event specific preparations
11497 error= do_before_row_operations(rli);
11498
11499 /*
11500 Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11501 Don't allow generation of auto_increment value when processing
11502 rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
11503 to this rule happens when the auto_inc column exists on some
11504 extra columns on the slave. In that case, do not force
11505 MODE_NO_AUTO_VALUE_ON_ZERO.
11506 */
11507 sql_mode_t saved_sql_mode= thd->variables.sql_mode;
11508 if (!is_auto_inc_in_extra_columns())
11509 thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11510
11511 // row processing loop
11512
11513 /*
11514 set the initial time of this ROWS statement if it was not done
11515 before in some other ROWS event.
11516 */
11517 rgi->set_row_stmt_start_timestamp();
11518
11519 THD_STAGE_INFO(thd, stage_executing);
11520 do
11521 {
11522 /* in_use can have been set to NULL in close_tables_for_reopen */
11523 THD* old_thd= table->in_use;
11524 if (!table->in_use)
11525 table->in_use= thd;
11526
11527 error= do_exec_row(rgi);
11528
11529 if (unlikely(error))
11530 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11531 DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
11532
11533 table->in_use = old_thd;
11534
11535 if (unlikely(error))
11536 {
11537 int actual_error= convert_handler_error(error, thd, table);
11538 bool idempotent_error= (idempotent_error_code(error) &&
11539 (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
11540 bool ignored_error= (idempotent_error == 0 ?
11541 ignored_error_code(actual_error) : 0);
11542
11543 if (idempotent_error || ignored_error)
11544 {
11545 if (global_system_variables.log_warnings)
11546 slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
11547 get_type_str(),
11548 RPL_LOG_NAME, log_pos);
11549 thd->clear_error(1);
11550 error= 0;
11551 if (idempotent_error == 0)
11552 break;
11553 }
11554 }
11555
11556 /*
11557 If m_curr_row_end was not set during event execution (e.g., because
11558 of errors) we can't proceed to the next row. If the error is transient
11559 (i.e., error==0 at this point) we must call unpack_current_row() to set
11560 m_curr_row_end.
11561 */
11562
11563 DBUG_PRINT("info", ("curr_row: %p; curr_row_end: %p; rows_end:%p",
11564 m_curr_row, m_curr_row_end, m_rows_end));
11565
11566 if (!m_curr_row_end && likely(!error))
11567 error= unpack_current_row(rgi);
11568
11569 m_curr_row= m_curr_row_end;
11570
11571 if (likely(error == 0) && !transactional_table)
11572 thd->transaction.all.modified_non_trans_table=
11573 thd->transaction.stmt.modified_non_trans_table= TRUE;
11574 } // row processing loop
11575 while (error == 0 && (m_curr_row != m_rows_end));
11576
11577 /*
11578 Restore the sql_mode after the rows event is processed.
11579 */
11580 thd->variables.sql_mode= saved_sql_mode;
11581
11582 {/**
11583 The following failure injecion works in cooperation with tests
11584 setting @@global.debug= 'd,stop_slave_middle_group'.
11585 The sql thread receives the killed status and will proceed
11586 to shutdown trying to finish incomplete events group.
11587 */
11588 DBUG_EXECUTE_IF("stop_slave_middle_group",
11589 if (thd->transaction.all.modified_non_trans_table)
11590 const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11591 }
11592
11593 if (unlikely(error= do_after_row_operations(rli, error)) &&
11594 ignored_error_code(convert_handler_error(error, thd, table)))
11595 {
11596
11597 if (global_system_variables.log_warnings)
11598 slave_rows_error_report(WARNING_LEVEL, error, rgi, thd, table,
11599 get_type_str(),
11600 RPL_LOG_NAME, log_pos);
11601 thd->clear_error(1);
11602 error= 0;
11603 }
11604 } // if (table)
11605
11606
11607 if (unlikely(error))
11608 {
11609 slave_rows_error_report(ERROR_LEVEL, error, rgi, thd, table,
11610 get_type_str(),
11611 RPL_LOG_NAME, log_pos);
11612 /*
11613 @todo We should probably not call
11614 reset_current_stmt_binlog_format_row() from here.
11615
11616 Note: this applies to log_event_old.cc too.
11617 /Sven
11618 */
11619 thd->reset_current_stmt_binlog_format_row();
11620 thd->is_slave_error= 1;
11621 /* remove trigger's tables */
11622 goto err;
11623 }
11624
11625 /* remove trigger's tables */
11626 if (slave_run_triggers_for_rbr)
11627 restore_empty_query_table_list(thd->lex);
11628
11629#if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
11630 if (WSREP(thd) && thd->wsrep_exec_mode == REPL_RECV)
11631 {
11632 query_cache.invalidate_locked_for_write(thd, rgi->tables_to_lock);
11633 }
11634#endif /* WITH_WSREP && HAVE_QUERY_CACHE */
11635
11636 if (unlikely(get_flags(STMT_END_F) &&
11637 (error= rows_event_stmt_cleanup(rgi, thd))))
11638 slave_rows_error_report(ERROR_LEVEL,
11639 thd->is_error() ? 0 : error,
11640 rgi, thd, table,
11641 get_type_str(),
11642 RPL_LOG_NAME, log_pos);
11643 DBUG_RETURN(error);
11644
11645err:
11646 if (slave_run_triggers_for_rbr)
11647 restore_empty_query_table_list(thd->lex);
11648 rgi->slave_close_thread_tables(thd);
11649 DBUG_RETURN(error);
11650}
11651
11652Log_event::enum_skip_reason
11653Rows_log_event::do_shall_skip(rpl_group_info *rgi)
11654{
11655 /*
11656 If the slave skip counter is 1 and this event does not end a
11657 statement, then we should not start executing on the next event.
11658 Otherwise, we defer the decision to the normal skipping logic.
11659 */
11660 if (rgi->rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11661 return Log_event::EVENT_SKIP_IGNORE;
11662 else
11663 return Log_event::do_shall_skip(rgi);
11664}
11665
11666/**
11667 The function is called at Rows_log_event statement commit time,
11668 normally from Rows_log_event::do_update_pos() and possibly from
11669 Query_log_event::do_apply_event() of the COMMIT.
11670 The function commits the last statement for engines, binlog and
11671 releases resources have been allocated for the statement.
11672
11673 @retval 0 Ok.
11674 @retval non-zero Error at the commit.
11675 */
11676
11677static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD * thd)
11678{
11679 int error;
11680 DBUG_ENTER("rows_event_stmt_cleanup");
11681
11682 {
11683 /*
11684 This is the end of a statement or transaction, so close (and
11685 unlock) the tables we opened when processing the
11686 Table_map_log_event starting the statement.
11687
11688 OBSERVER. This will clear *all* mappings, not only those that
11689 are open for the table. There is not good handle for on-close
11690 actions for tables.
11691
11692 NOTE. Even if we have no table ('table' == 0) we still need to be
11693 here, so that we increase the group relay log position. If we didn't, we
11694 could have a group relay log position which lags behind "forever"
11695 (assume the last master's transaction is ignored by the slave because of
11696 replicate-ignore rules).
11697 */
11698 error= thd->binlog_flush_pending_rows_event(TRUE);
11699
11700 /*
11701 If this event is not in a transaction, the call below will, if some
11702 transactional storage engines are involved, commit the statement into
11703 them and flush the pending event to binlog.
11704 If this event is in a transaction, the call will do nothing, but a
11705 Xid_log_event will come next which will, if some transactional engines
11706 are involved, commit the transaction and flush the pending event to the
11707 binlog.
11708 If there was a deadlock the transaction should have been rolled back
11709 already. So there should be no need to rollback the transaction.
11710 */
11711 DBUG_ASSERT(! thd->transaction_rollback_request);
11712 error|= (int)(error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11713
11714 /*
11715 Now what if this is not a transactional engine? we still need to
11716 flush the pending event to the binlog; we did it with
11717 thd->binlog_flush_pending_rows_event(). Note that we imitate
11718 what is done for real queries: a call to
11719 ha_autocommit_or_rollback() (sometimes only if involves a
11720 transactional engine), and a call to be sure to have the pending
11721 event flushed.
11722 */
11723
11724 /*
11725 @todo We should probably not call
11726 reset_current_stmt_binlog_format_row() from here.
11727
11728 Note: this applies to log_event_old.cc too
11729
11730 Btw, the previous comment about transactional engines does not
11731 seem related to anything that happens here.
11732 /Sven
11733 */
11734 thd->reset_current_stmt_binlog_format_row();
11735
11736 /*
11737 Reset modified_non_trans_table that we have set in
11738 rows_log_event::do_apply_event()
11739 */
11740 if (!thd->in_multi_stmt_transaction_mode())
11741 {
11742 thd->transaction.all.modified_non_trans_table= 0;
11743 thd->transaction.all.m_unsafe_rollback_flags&= ~THD_TRANS::DID_WAIT;
11744 }
11745
11746 rgi->cleanup_context(thd, 0);
11747 }
11748 DBUG_RETURN(error);
11749}
11750
11751/**
11752 The method either increments the relay log position or
11753 commits the current statement and increments the master group
11754 possition if the event is STMT_END_F flagged and
11755 the statement corresponds to the autocommit query (i.e replicated
11756 without wrapping in BEGIN/COMMIT)
11757
11758 @retval 0 Success
11759 @retval non-zero Error in the statement commit
11760 */
11761int
11762Rows_log_event::do_update_pos(rpl_group_info *rgi)
11763{
11764 Relay_log_info *rli= rgi->rli;
11765 int error= 0;
11766 DBUG_ENTER("Rows_log_event::do_update_pos");
11767
11768 DBUG_PRINT("info", ("flags: %s",
11769 get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11770
11771 if (get_flags(STMT_END_F))
11772 {
11773 /*
11774 Indicate that a statement is finished.
11775 Step the group log position if we are not in a transaction,
11776 otherwise increase the event log position.
11777 */
11778 error= rli->stmt_done(log_pos, thd, rgi);
11779 /*
11780 Clear any errors in thd->net.last_err*. It is not known if this is
11781 needed or not. It is believed that any errors that may exist in
11782 thd->net.last_err* are allowed. Examples of errors are "key not
11783 found", which is produced in the test case rpl_row_conflicts.test
11784 */
11785 thd->clear_error();
11786 }
11787 else
11788 {
11789 rgi->inc_event_relay_log_pos();
11790 }
11791
11792 DBUG_RETURN(error);
11793}
11794
11795#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11796
11797#ifndef MYSQL_CLIENT
11798bool Rows_log_event::write_data_header()
11799{
11800 uchar buf[ROWS_HEADER_LEN_V2]; // No need to init the buffer
11801 DBUG_ASSERT(m_table_id != ~0UL);
11802 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11803 {
11804 int4store(buf + 0, m_table_id);
11805 int2store(buf + 4, m_flags);
11806 return (write_data(buf, 6));
11807 });
11808 int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
11809 int2store(buf + RW_FLAGS_OFFSET, m_flags);
11810 return write_data(buf, ROWS_HEADER_LEN);
11811}
11812
11813bool Rows_log_event::write_data_body()
11814{
11815 /*
11816 Note that this should be the number of *bits*, not the number of
11817 bytes.
11818 */
11819 uchar sbuf[MAX_INT_WIDTH];
11820 my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
11821 bool res= false;
11822 uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
11823 DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
11824
11825 DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
11826 res= res || write_data(sbuf, (size_t) (sbuf_end - sbuf));
11827
11828 DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
11829 res= res || write_data((uchar*)m_cols.bitmap, no_bytes_in_map(&m_cols));
11830 /*
11831 TODO[refactor write]: Remove the "down cast" here (and elsewhere).
11832 */
11833 if (get_general_type_code() == UPDATE_ROWS_EVENT)
11834 {
11835 DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
11836 no_bytes_in_map(&m_cols_ai));
11837 res= res || write_data((uchar*)m_cols_ai.bitmap,
11838 no_bytes_in_map(&m_cols_ai));
11839 }
11840 DBUG_DUMP("rows", m_rows_buf, data_size);
11841 res= res || write_data(m_rows_buf, (size_t) data_size);
11842
11843 return res;
11844
11845}
11846
11847bool Rows_log_event::write_compressed()
11848{
11849 uchar *m_rows_buf_tmp = m_rows_buf;
11850 uchar *m_rows_cur_tmp = m_rows_cur;
11851 bool ret = true;
11852 uint32 comlen, alloc_size;
11853 comlen= alloc_size= binlog_get_compress_len((uint32)(m_rows_cur_tmp - m_rows_buf_tmp));
11854 m_rows_buf = (uchar *)my_safe_alloca(alloc_size);
11855 if(m_rows_buf &&
11856 !binlog_buf_compress((const char *)m_rows_buf_tmp, (char *)m_rows_buf,
11857 (uint32)(m_rows_cur_tmp - m_rows_buf_tmp), &comlen))
11858 {
11859 m_rows_cur= comlen + m_rows_buf;
11860 ret= Log_event::write();
11861 }
11862 my_safe_afree(m_rows_buf, alloc_size);
11863 m_rows_buf= m_rows_buf_tmp;
11864 m_rows_cur= m_rows_cur_tmp;
11865 return ret;
11866}
11867#endif
11868
11869#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
11870void Rows_log_event::pack_info(Protocol *protocol)
11871{
11872 char buf[256];
11873 char const *const flagstr=
11874 get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
11875 size_t bytes= my_snprintf(buf, sizeof(buf),
11876 "table_id: %lu%s", m_table_id, flagstr);
11877 protocol->store(buf, bytes, &my_charset_bin);
11878}
11879#endif
11880
11881#ifdef MYSQL_CLIENT
11882bool Rows_log_event::print_helper(FILE *file,
11883 PRINT_EVENT_INFO *print_event_info,
11884 char const *const name)
11885{
11886 IO_CACHE *const head= &print_event_info->head_cache;
11887 IO_CACHE *const body= &print_event_info->body_cache;
11888#ifdef WHEN_FLASHBACK_REVIEW_READY
11889 IO_CACHE *const sql= &print_event_info->review_sql_cache;
11890#endif
11891 bool const last_stmt_event= get_flags(STMT_END_F);
11892
11893 if (!print_event_info->short_form)
11894 {
11895 print_header(head, print_event_info, !last_stmt_event);
11896 if (my_b_printf(head, "\t%s: table id %lu%s\n",
11897 name, m_table_id,
11898 last_stmt_event ? " flags: STMT_END_F" : ""))
11899 goto err;
11900 }
11901 if (!print_event_info->short_form || print_event_info->print_row_count)
11902 if (print_base64(body, print_event_info, !last_stmt_event))
11903 goto err;
11904
11905 if (last_stmt_event)
11906 {
11907 if (!is_flashback)
11908 {
11909 if (copy_event_cache_to_file_and_reinit(head, file) ||
11910 copy_event_cache_to_file_and_reinit(body, file))
11911 goto err;
11912 }
11913 else
11914 {
11915 LEX_STRING tmp_str;
11916 if (copy_event_cache_to_string_and_reinit(head, &tmp_str))
11917 return 1;
11918 output_buf.append(tmp_str.str, tmp_str.length); // Not \0 terminated
11919 my_free(tmp_str.str);
11920 if (copy_event_cache_to_string_and_reinit(body, &tmp_str))
11921 return 1;
11922 output_buf.append(tmp_str.str, tmp_str.length);
11923 my_free(tmp_str.str);
11924#ifdef WHEN_FLASHBACK_REVIEW_READY
11925 if (copy_event_cache_to_string_and_reinit(sql, &tmp_str))
11926 return 1;
11927 output_buf.append(tmp_str.str, tmp_str.length);
11928 my_free(tmp_str.str);
11929#endif
11930 }
11931 }
11932
11933 return 0;
11934err:
11935 return 1;
11936}
11937#endif
11938
11939/**************************************************************************
11940 Annotate_rows_log_event member functions
11941**************************************************************************/
11942
11943#ifndef MYSQL_CLIENT
11944Annotate_rows_log_event::Annotate_rows_log_event(THD *thd,
11945 bool using_trans,
11946 bool direct)
11947 : Log_event(thd, 0, using_trans),
11948 m_save_thd_query_txt(0),
11949 m_save_thd_query_len(0),
11950 m_saved_thd_query(false),
11951 m_used_query_txt(0)
11952{
11953 m_query_txt= thd->query();
11954 m_query_len= thd->query_length();
11955 if (direct)
11956 cache_type= Log_event::EVENT_NO_CACHE;
11957}
11958#endif
11959
11960Annotate_rows_log_event::Annotate_rows_log_event(const char *buf,
11961 uint event_len,
11962 const Format_description_log_event *desc)
11963 : Log_event(buf, desc),
11964 m_save_thd_query_txt(0),
11965 m_save_thd_query_len(0),
11966 m_saved_thd_query(false),
11967 m_used_query_txt(0)
11968{
11969 m_query_len= event_len - desc->common_header_len;
11970 m_query_txt= (char*) buf + desc->common_header_len;
11971}
11972
11973Annotate_rows_log_event::~Annotate_rows_log_event()
11974{
11975 DBUG_ENTER("Annotate_rows_log_event::~Annotate_rows_log_event");
11976#ifndef MYSQL_CLIENT
11977 if (m_saved_thd_query)
11978 thd->set_query(m_save_thd_query_txt, m_save_thd_query_len);
11979 else if (m_used_query_txt)
11980 thd->reset_query();
11981#endif
11982 DBUG_VOID_RETURN;
11983}
11984
11985int Annotate_rows_log_event::get_data_size()
11986{
11987 return m_query_len;
11988}
11989
11990Log_event_type Annotate_rows_log_event::get_type_code()
11991{
11992 return ANNOTATE_ROWS_EVENT;
11993}
11994
11995bool Annotate_rows_log_event::is_valid() const
11996{
11997 return (m_query_txt != NULL && m_query_len != 0);
11998}
11999
12000#ifndef MYSQL_CLIENT
12001bool Annotate_rows_log_event::write_data_header()
12002{
12003 return 0;
12004}
12005#endif
12006
12007#ifndef MYSQL_CLIENT
12008bool Annotate_rows_log_event::write_data_body()
12009{
12010 return write_data(m_query_txt, m_query_len);
12011}
12012#endif
12013
12014#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12015void Annotate_rows_log_event::pack_info(Protocol* protocol)
12016{
12017 if (m_query_txt && m_query_len)
12018 protocol->store(m_query_txt, m_query_len, &my_charset_bin);
12019}
12020#endif
12021
12022#ifdef MYSQL_CLIENT
12023bool Annotate_rows_log_event::print(FILE *file, PRINT_EVENT_INFO *pinfo)
12024{
12025 char *pbeg; // beginning of the next line
12026 char *pend; // end of the next line
12027 uint cnt= 0; // characters counter
12028
12029 if (!pinfo->short_form)
12030 {
12031 if (print_header(&pinfo->head_cache, pinfo, TRUE) ||
12032 my_b_printf(&pinfo->head_cache, "\tAnnotate_rows:\n"))
12033 goto err;
12034 }
12035 else if (my_b_printf(&pinfo->head_cache, "# Annotate_rows:\n"))
12036 goto err;
12037
12038 for (pbeg= m_query_txt; ; pbeg= pend)
12039 {
12040 // skip all \r's and \n's at the beginning of the next line
12041 for (;; pbeg++)
12042 {
12043 if (++cnt > m_query_len)
12044 return 0;
12045
12046 if (*pbeg != '\r' && *pbeg != '\n')
12047 break;
12048 }
12049
12050 // find end of the next line
12051 for (pend= pbeg + 1;
12052 ++cnt <= m_query_len && *pend != '\r' && *pend != '\n';
12053 pend++)
12054 ;
12055
12056 // print next line
12057 if (my_b_write(&pinfo->head_cache, (const uchar*) "#Q> ", 4) ||
12058 my_b_write(&pinfo->head_cache, (const uchar*) pbeg, pend - pbeg) ||
12059 my_b_write(&pinfo->head_cache, (const uchar*) "\n", 1))
12060 goto err;
12061 }
12062
12063 return 0;
12064err:
12065 return 1;
12066}
12067#endif
12068
12069#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12070int Annotate_rows_log_event::do_apply_event(rpl_group_info *rgi)
12071{
12072 rgi->free_annotate_event();
12073 m_save_thd_query_txt= thd->query();
12074 m_save_thd_query_len= thd->query_length();
12075 m_saved_thd_query= true;
12076 m_used_query_txt= 1;
12077 thd->set_query(m_query_txt, m_query_len);
12078 return 0;
12079}
12080#endif
12081
12082#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12083int Annotate_rows_log_event::do_update_pos(rpl_group_info *rgi)
12084{
12085 rgi->inc_event_relay_log_pos();
12086 return 0;
12087}
12088#endif
12089
12090#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12091Log_event::enum_skip_reason
12092Annotate_rows_log_event::do_shall_skip(rpl_group_info *rgi)
12093{
12094 return continue_group(rgi);
12095}
12096#endif
12097
12098/**************************************************************************
12099 Table_map_log_event member functions and support functions
12100**************************************************************************/
12101
12102/**
12103 @page How replication of field metadata works.
12104
12105 When a table map is created, the master first calls
12106 Table_map_log_event::save_field_metadata() which calculates how many
12107 values will be in the field metadata. Only those fields that require the
12108 extra data are added. The method also loops through all of the fields in
12109 the table calling the method Field::save_field_metadata() which returns the
12110 values for the field that will be saved in the metadata and replicated to
12111 the slave. Once all fields have been processed, the table map is written to
12112 the binlog adding the size of the field metadata and the field metadata to
12113 the end of the body of the table map.
12114
12115 When a table map is read on the slave, the field metadata is read from the
12116 table map and passed to the table_def class constructor which saves the
12117 field metadata from the table map into an array based on the type of the
12118 field. Field metadata values not present (those fields that do not use extra
12119 data) in the table map are initialized as zero (0). The array size is the
12120 same as the columns for the table on the slave.
12121
12122 Additionally, values saved for field metadata on the master are saved as a
12123 string of bytes (uchar) in the binlog. A field may require 1 or more bytes
12124 to store the information. In cases where values require multiple bytes
12125 (e.g. values > 255), the endian-safe methods are used to properly encode
12126 the values on the master and decode them on the slave. When the field
12127 metadata values are captured on the slave, they are stored in an array of
12128 type uint16. This allows the least number of casts to prevent casting bugs
12129 when the field metadata is used in comparisons of field attributes. When
12130 the field metadata is used for calculating addresses in pointer math, the
12131 type used is uint32.
12132*/
12133
12134#if !defined(MYSQL_CLIENT)
12135/**
12136 Save the field metadata based on the real_type of the field.
12137 The metadata saved depends on the type of the field. Some fields
12138 store a single byte for pack_length() while others store two bytes
12139 for field_length (max length).
12140
12141 @retval 0 Ok.
12142
12143 @todo
12144 We may want to consider changing the encoding of the information.
12145 Currently, the code attempts to minimize the number of bytes written to
12146 the tablemap. There are at least two other alternatives; 1) using
12147 net_store_length() to store the data allowing it to choose the number of
12148 bytes that are appropriate thereby making the code much easier to
12149 maintain (only 1 place to change the encoding), or 2) use a fixed number
12150 of bytes for each field. The problem with option 1 is that net_store_length()
12151 will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
12152 for fields like CHAR which can be no larger than 255 characters, the method
12153 will use 3 bytes when the value is > 250. Further, every value that is
12154 encoded using 2 parts (e.g., pack_length, field_length) will be numerically
12155 > 250 therefore will use 3 bytes for eah value. The problem with option 2
12156 is less wasteful for space but does waste 1 byte for every field that does
12157 not encode 2 parts.
12158*/
12159int Table_map_log_event::save_field_metadata()
12160{
12161 DBUG_ENTER("Table_map_log_event::save_field_metadata");
12162 int index= 0;
12163 for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
12164 {
12165 DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
12166 index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
12167 }
12168 DBUG_RETURN(index);
12169}
12170#endif /* !defined(MYSQL_CLIENT) */
12171
12172/*
12173 Constructor used to build an event for writing to the binary log.
12174 Mats says tbl->s lives longer than this event so it's ok to copy pointers
12175 (tbl->s->db etc) and not pointer content.
12176 */
12177#if !defined(MYSQL_CLIENT)
12178Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
12179 bool is_transactional)
12180 : Log_event(thd, 0, is_transactional),
12181 m_table(tbl),
12182 m_dbnam(tbl->s->db.str),
12183 m_dblen(m_dbnam ? tbl->s->db.length : 0),
12184 m_tblnam(tbl->s->table_name.str),
12185 m_tbllen(tbl->s->table_name.length),
12186 m_colcnt(tbl->s->fields),
12187 m_memory(NULL),
12188 m_table_id(tid),
12189 m_flags(TM_BIT_LEN_EXACT_F),
12190 m_data_size(0),
12191 m_field_metadata(0),
12192 m_field_metadata_size(0),
12193 m_null_bits(0),
12194 m_meta_memory(NULL)
12195{
12196 uchar cbuf[MAX_INT_WIDTH];
12197 uchar *cbuf_end;
12198 DBUG_ENTER("Table_map_log_event::Table_map_log_event(TABLE)");
12199 DBUG_ASSERT(m_table_id != ~0UL);
12200 /*
12201 In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
12202 table.cc / alloc_table_share():
12203 Use the fact the key is db/0/table_name/0
12204 As we rely on this let's assert it.
12205 */
12206 DBUG_ASSERT((tbl->s->db.str == 0) ||
12207 (tbl->s->db.str[tbl->s->db.length] == 0));
12208 DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
12209
12210
12211 m_data_size= TABLE_MAP_HEADER_LEN;
12212 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
12213 m_data_size+= m_dblen + 2; // Include length and terminating \0
12214 m_data_size+= m_tbllen + 2; // Include length and terminating \0
12215 cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12216 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12217 m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
12218
12219 if (tbl->triggers)
12220 m_flags|= TM_BIT_HAS_TRIGGERS_F;
12221
12222 /* If malloc fails, caught in is_valid() */
12223 if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
12224 {
12225 m_coltype= reinterpret_cast<uchar*>(m_memory);
12226 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12227 m_coltype[i]= m_table->field[i]->binlog_type();
12228 }
12229
12230 /*
12231 Calculate a bitmap for the results of maybe_null() for all columns.
12232 The bitmap is used to determine when there is a column from the master
12233 that is not on the slave and is null and thus not in the row data during
12234 replication.
12235 */
12236 uint num_null_bytes= (m_table->s->fields + 7) / 8;
12237 m_data_size+= num_null_bytes;
12238 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12239 &m_null_bits, num_null_bytes,
12240 &m_field_metadata, (m_colcnt * 2),
12241 NULL);
12242
12243 bzero(m_field_metadata, (m_colcnt * 2));
12244
12245 /*
12246 Create an array for the field metadata and store it.
12247 */
12248 m_field_metadata_size= save_field_metadata();
12249 DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
12250
12251 /*
12252 Now set the size of the data to the size of the field metadata array
12253 plus one or three bytes (see pack.c:net_store_length) for number of
12254 elements in the field metadata array.
12255 */
12256 if (m_field_metadata_size < 251)
12257 m_data_size+= m_field_metadata_size + 1;
12258 else
12259 m_data_size+= m_field_metadata_size + 3;
12260
12261 bzero(m_null_bits, num_null_bytes);
12262 for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12263 if (m_table->field[i]->maybe_null())
12264 m_null_bits[(i / 8)]+= 1 << (i % 8);
12265
12266 DBUG_VOID_RETURN;
12267}
12268#endif /* !defined(MYSQL_CLIENT) */
12269
12270/*
12271 Constructor used by slave to read the event from the binary log.
12272 */
12273#if defined(HAVE_REPLICATION)
12274Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
12275 const Format_description_log_event
12276 *description_event)
12277
12278 : Log_event(buf, description_event),
12279#ifndef MYSQL_CLIENT
12280 m_table(NULL),
12281#endif
12282 m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
12283 m_colcnt(0), m_coltype(0),
12284 m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
12285 m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
12286 m_null_bits(0), m_meta_memory(NULL)
12287{
12288 unsigned int bytes_read= 0;
12289 DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
12290
12291 uint8 common_header_len= description_event->common_header_len;
12292 uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
12293 DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
12294 event_len, common_header_len, post_header_len));
12295
12296 /*
12297 Don't print debug messages when running valgrind since they can
12298 trigger false warnings.
12299 */
12300#ifndef HAVE_valgrind
12301 DBUG_DUMP("event buffer", (uchar*) buf, event_len);
12302#endif
12303
12304 /* Read the post-header */
12305 const char *post_start= buf + common_header_len;
12306
12307 post_start+= TM_MAPID_OFFSET;
12308 if (post_header_len == 6)
12309 {
12310 /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
12311 m_table_id= uint4korr(post_start);
12312 post_start+= 4;
12313 }
12314 else
12315 {
12316 DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
12317 m_table_id= (ulong) uint6korr(post_start);
12318 post_start+= TM_FLAGS_OFFSET;
12319 }
12320
12321 DBUG_ASSERT(m_table_id != ~0UL);
12322
12323 m_flags= uint2korr(post_start);
12324
12325 /* Read the variable part of the event */
12326 const char *const vpart= buf + common_header_len + post_header_len;
12327
12328 /* Extract the length of the various parts from the buffer */
12329 uchar const *const ptr_dblen= (uchar const*)vpart + 0;
12330 m_dblen= *(uchar*) ptr_dblen;
12331
12332 /* Length of database name + counter + terminating null */
12333 uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
12334 m_tbllen= *(uchar*) ptr_tbllen;
12335
12336 /* Length of table name + counter + terminating null */
12337 uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
12338 uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
12339 m_colcnt= net_field_length(&ptr_after_colcnt);
12340
12341 DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
12342 (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
12343 (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
12344 m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
12345
12346 /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
12347 m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12348 &m_dbnam, (uint) m_dblen + 1,
12349 &m_tblnam, (uint) m_tbllen + 1,
12350 &m_coltype, (uint) m_colcnt,
12351 NullS);
12352
12353 if (m_memory)
12354 {
12355 /* Copy the different parts into their memory */
12356 strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
12357 strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
12358 memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
12359
12360 ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
12361 bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
12362 DBUG_PRINT("info", ("Bytes read: %d", bytes_read));
12363 if (bytes_read < event_len)
12364 {
12365 m_field_metadata_size= net_field_length(&ptr_after_colcnt);
12366 DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
12367 uint num_null_bytes= (m_colcnt + 7) / 8;
12368 m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12369 &m_null_bits, num_null_bytes,
12370 &m_field_metadata, m_field_metadata_size,
12371 NULL);
12372 memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
12373 ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
12374 memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
12375 }
12376 }
12377
12378 DBUG_VOID_RETURN;
12379}
12380#endif
12381
12382Table_map_log_event::~Table_map_log_event()
12383{
12384 my_free(m_meta_memory);
12385 my_free(m_memory);
12386}
12387
12388
12389#ifdef MYSQL_CLIENT
12390
12391/*
12392 Rewrite database name for the event to name specified by new_db
12393 SYNOPSIS
12394 new_db Database name to change to
12395 new_len Length
12396 desc Event describing binlog that we're writing to.
12397
12398 DESCRIPTION
12399 Reset db name. This function assumes that temp_buf member contains event
12400 representation taken from a binary log. It resets m_dbnam and m_dblen and
12401 rewrites temp_buf with new db name.
12402
12403 RETURN
12404 0 - Success
12405 other - Error
12406*/
12407
12408int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
12409 const Format_description_log_event* desc)
12410{
12411 DBUG_ENTER("Table_map_log_event::rewrite_db");
12412 DBUG_ASSERT(temp_buf);
12413
12414 uint header_len= MY_MIN(desc->common_header_len,
12415 LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN;
12416 int len_diff;
12417
12418 if (!(len_diff= (int)(new_len - m_dblen)))
12419 {
12420 memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1);
12421 memcpy((void*) m_dbnam, new_db, m_dblen + 1);
12422 DBUG_RETURN(0);
12423 }
12424
12425 // Create new temp_buf
12426 ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET);
12427 ulong event_new_len= event_cur_len + len_diff;
12428 char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME));
12429
12430 if (!new_temp_buf)
12431 {
12432 sql_print_error("Table_map_log_event::rewrite_db: "
12433 "failed to allocate new temp_buf (%d bytes required)",
12434 event_new_len);
12435 DBUG_RETURN(-1);
12436 }
12437
12438 // Rewrite temp_buf
12439 char* ptr= new_temp_buf;
12440 size_t cnt= 0;
12441
12442 // Copy header and change event length
12443 memcpy(ptr, temp_buf, header_len);
12444 int4store(ptr + EVENT_LEN_OFFSET, event_new_len);
12445 ptr += header_len;
12446 cnt += header_len;
12447
12448 // Write new db name length and new name
12449 DBUG_ASSERT(new_len < 0xff);
12450 *ptr++ = (char)new_len;
12451 memcpy(ptr, new_db, new_len + 1);
12452 ptr += new_len + 1;
12453 cnt += m_dblen + 2;
12454
12455 // Copy rest part
12456 memcpy(ptr, temp_buf + cnt, event_cur_len - cnt);
12457
12458 // Reregister temp buf
12459 free_temp_buf();
12460 register_temp_buf(new_temp_buf, TRUE);
12461
12462 // Reset m_dbnam and m_dblen members
12463 m_dblen= new_len;
12464
12465 // m_dbnam resides in m_memory together with m_tblnam and m_coltype
12466 uchar* memory= m_memory;
12467 char const* tblnam= m_tblnam;
12468 uchar* coltype= m_coltype;
12469
12470 m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12471 &m_dbnam, (uint) m_dblen + 1,
12472 &m_tblnam, (uint) m_tbllen + 1,
12473 &m_coltype, (uint) m_colcnt,
12474 NullS);
12475
12476 if (!m_memory)
12477 {
12478 sql_print_error("Table_map_log_event::rewrite_db: "
12479 "failed to allocate new m_memory (%d + %d + %d bytes required)",
12480 m_dblen + 1, m_tbllen + 1, m_colcnt);
12481 DBUG_RETURN(-1);
12482 }
12483
12484 memcpy((void*)m_dbnam, new_db, m_dblen + 1);
12485 memcpy((void*)m_tblnam, tblnam, m_tbllen + 1);
12486 memcpy(m_coltype, coltype, m_colcnt);
12487
12488 my_free(memory);
12489 DBUG_RETURN(0);
12490}
12491#endif /* MYSQL_CLIENT */
12492
12493
12494/*
12495 Return value is an error code, one of:
12496
12497 -1 Failure to open table [from open_tables()]
12498 0 Success
12499 1 No room for more tables [from set_table()]
12500 2 Out of memory [from set_table()]
12501 3 Wrong table definition
12502 4 Daisy-chaining RBR with SBR not possible
12503 */
12504
12505#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12506
12507enum enum_tbl_map_status
12508{
12509 /* no duplicate identifier found */
12510 OK_TO_PROCESS= 0,
12511
12512 /* this table map must be filtered out */
12513 FILTERED_OUT= 1,
12514
12515 /* identifier mapping table with different properties */
12516 SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
12517
12518 /* a duplicate identifier was found mapping the same table */
12519 SAME_ID_MAPPING_SAME_TABLE= 3
12520};
12521
12522/*
12523 Checks if this table map event should be processed or not. First
12524 it checks the filtering rules, and then looks for duplicate identifiers
12525 in the existing list of rli->tables_to_lock.
12526
12527 It checks that there hasn't been any corruption by verifying that there
12528 are no duplicate entries with different properties.
12529
12530 In some cases, some binary logs could get corrupted, showing several
12531 tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
12532 early sanity check for such cases and avoid that the server crashes
12533 later.
12534
12535 In some corner cases, the master logs duplicate table map events, i.e.,
12536 same id, same database name, same table name (see: BUG#37137). This is
12537 different from the above as it's the same table that is mapped again
12538 to the same identifier. Thus we cannot just check for same ids and
12539 assume that the event is corrupted we need to check every property.
12540
12541 NOTE: in the event that BUG#37137 ever gets fixed, this extra check
12542 will still be valid because we would need to support old binary
12543 logs anyway.
12544
12545 @param rli The relay log info reference.
12546 @param table_list A list element containing the table to check against.
12547 @return OK_TO_PROCESS
12548 if there was no identifier already in rli->tables_to_lock
12549
12550 FILTERED_OUT
12551 if the event is filtered according to the filtering rules
12552
12553 SAME_ID_MAPPING_DIFFERENT_TABLE
12554 if the same identifier already maps a different table in
12555 rli->tables_to_lock
12556
12557 SAME_ID_MAPPING_SAME_TABLE
12558 if the same identifier already maps the same table in
12559 rli->tables_to_lock.
12560*/
12561static enum_tbl_map_status
12562check_table_map(rpl_group_info *rgi, RPL_TABLE_LIST *table_list)
12563{
12564 DBUG_ENTER("check_table_map");
12565 enum_tbl_map_status res= OK_TO_PROCESS;
12566 Relay_log_info *rli= rgi->rli;
12567 if ((rgi->thd->slave_thread /* filtering is for slave only */ ||
12568 IF_WSREP((WSREP(rgi->thd) && rgi->thd->wsrep_applier), 0)) &&
12569 (!rli->mi->rpl_filter->db_ok(table_list->db.str) ||
12570 (rli->mi->rpl_filter->is_on() && !rli->mi->rpl_filter->tables_ok("", table_list))))
12571 res= FILTERED_OUT;
12572 else
12573 {
12574 RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rgi->tables_to_lock);
12575 for(uint i=0 ; ptr && (i< rgi->tables_to_lock_count);
12576 ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
12577 {
12578 if (ptr->table_id == table_list->table_id)
12579 {
12580
12581 if (cmp(&ptr->db, &table_list->db) ||
12582 cmp(&ptr->alias, &table_list->table_name) ||
12583 ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
12584 res= SAME_ID_MAPPING_DIFFERENT_TABLE;
12585 else
12586 res= SAME_ID_MAPPING_SAME_TABLE;
12587
12588 break;
12589 }
12590 }
12591 }
12592
12593 DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
12594
12595 DBUG_RETURN(res);
12596}
12597
12598int Table_map_log_event::do_apply_event(rpl_group_info *rgi)
12599{
12600 RPL_TABLE_LIST *table_list;
12601 char *db_mem, *tname_mem;
12602 size_t dummy_len, db_mem_length, tname_mem_length;
12603 void *memory;
12604 Rpl_filter *filter;
12605 Relay_log_info const *rli= rgi->rli;
12606 DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
12607
12608 /* Step the query id to mark what columns that are actually used. */
12609 thd->set_query_id(next_query_id());
12610
12611 if (!(memory= my_multi_malloc(MYF(MY_WME),
12612 &table_list, (uint) sizeof(RPL_TABLE_LIST),
12613 &db_mem, (uint) NAME_LEN + 1,
12614 &tname_mem, (uint) NAME_LEN + 1,
12615 NullS)))
12616 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
12617
12618 /* call from mysql_client_binlog_statement() will not set rli->mi */
12619 filter= rgi->thd->slave_thread ? rli->mi->rpl_filter : global_rpl_filter;
12620 db_mem_length= strmov(db_mem, filter->get_rewrite_db(m_dbnam, &dummy_len))- db_mem;
12621 tname_mem_length= strmov(tname_mem, m_tblnam)- tname_mem;
12622
12623 LEX_CSTRING tmp_db_name= {db_mem, db_mem_length };
12624 LEX_CSTRING tmp_tbl_name= {tname_mem, tname_mem_length };
12625
12626 table_list->init_one_table(&tmp_db_name, &tmp_tbl_name, 0, TL_WRITE);
12627 table_list->table_id= DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id);
12628 table_list->updating= 1;
12629 table_list->required_type= TABLE_TYPE_NORMAL;
12630
12631 DBUG_PRINT("debug", ("table: %s is mapped to %u",
12632 table_list->table_name.str,
12633 table_list->table_id));
12634 table_list->master_had_triggers= ((m_flags & TM_BIT_HAS_TRIGGERS_F) ? 1 : 0);
12635 DBUG_PRINT("debug", ("table->master_had_triggers=%d",
12636 (int)table_list->master_had_triggers));
12637
12638 enum_tbl_map_status tblmap_status= check_table_map(rgi, table_list);
12639 if (tblmap_status == OK_TO_PROCESS)
12640 {
12641 DBUG_ASSERT(thd->lex->query_tables != table_list);
12642
12643 /*
12644 Use placement new to construct the table_def instance in the
12645 memory allocated for it inside table_list.
12646
12647 The memory allocated by the table_def structure (i.e., not the
12648 memory allocated *for* the table_def structure) is released
12649 inside Relay_log_info::clear_tables_to_lock() by calling the
12650 table_def destructor explicitly.
12651 */
12652 new (&table_list->m_tabledef)
12653 table_def(m_coltype, m_colcnt,
12654 m_field_metadata, m_field_metadata_size,
12655 m_null_bits, m_flags);
12656 table_list->m_tabledef_valid= TRUE;
12657 table_list->m_conv_table= NULL;
12658 table_list->open_type= OT_BASE_ONLY;
12659
12660 /*
12661 We record in the slave's information that the table should be
12662 locked by linking the table into the list of tables to lock.
12663 */
12664 table_list->next_global= table_list->next_local= rgi->tables_to_lock;
12665 rgi->tables_to_lock= table_list;
12666 rgi->tables_to_lock_count++;
12667 /* 'memory' is freed in clear_tables_to_lock */
12668 }
12669 else // FILTERED_OUT, SAME_ID_MAPPING_*
12670 {
12671 /*
12672 If mapped already but with different properties, we raise an
12673 error.
12674 If mapped already but with same properties we skip the event.
12675 If filtered out we skip the event.
12676
12677 In all three cases, we need to free the memory previously
12678 allocated.
12679 */
12680 if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
12681 {
12682 /*
12683 Something bad has happened. We need to stop the slave as strange things
12684 could happen if we proceed: slave crash, wrong table being updated, ...
12685 As a consequence we push an error in this case.
12686 */
12687
12688 char buf[256];
12689
12690 my_snprintf(buf, sizeof(buf),
12691 "Found table map event mapping table id %u which "
12692 "was already mapped but with different settings.",
12693 table_list->table_id);
12694
12695 if (thd->slave_thread)
12696 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, rgi->gtid_info(),
12697 ER_THD(thd, ER_SLAVE_FATAL_ERROR), buf);
12698 else
12699 /*
12700 For the cases in which a 'BINLOG' statement is set to
12701 execute in a user session
12702 */
12703 my_error(ER_SLAVE_FATAL_ERROR, MYF(0), buf);
12704 }
12705
12706 my_free(memory);
12707 }
12708
12709 DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12710}
12711
12712Log_event::enum_skip_reason
12713Table_map_log_event::do_shall_skip(rpl_group_info *rgi)
12714{
12715 /*
12716 If the slave skip counter is 1, then we should not start executing
12717 on the next event.
12718 */
12719 return continue_group(rgi);
12720}
12721
12722int Table_map_log_event::do_update_pos(rpl_group_info *rgi)
12723{
12724 rgi->inc_event_relay_log_pos();
12725 return 0;
12726}
12727
12728#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12729
12730#ifndef MYSQL_CLIENT
12731bool Table_map_log_event::write_data_header()
12732{
12733 DBUG_ASSERT(m_table_id != ~0UL);
12734 uchar buf[TABLE_MAP_HEADER_LEN];
12735 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12736 {
12737 int4store(buf + 0, m_table_id);
12738 int2store(buf + 4, m_flags);
12739 return (write_data(buf, 6));
12740 });
12741 int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
12742 int2store(buf + TM_FLAGS_OFFSET, m_flags);
12743 return write_data(buf, TABLE_MAP_HEADER_LEN);
12744}
12745
12746bool Table_map_log_event::write_data_body()
12747{
12748 DBUG_ASSERT(m_dbnam != NULL);
12749 DBUG_ASSERT(m_tblnam != NULL);
12750 /* We use only one byte per length for storage in event: */
12751 DBUG_ASSERT(m_dblen <= MY_MIN(NAME_LEN, 255));
12752 DBUG_ASSERT(m_tbllen <= MY_MIN(NAME_LEN, 255));
12753
12754 uchar const dbuf[]= { (uchar) m_dblen };
12755 uchar const tbuf[]= { (uchar) m_tbllen };
12756
12757 uchar cbuf[MAX_INT_WIDTH];
12758 uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12759 DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12760
12761 /*
12762 Store the size of the field metadata.
12763 */
12764 uchar mbuf[MAX_INT_WIDTH];
12765 uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12766
12767 return write_data(dbuf, sizeof(dbuf)) ||
12768 write_data(m_dbnam, m_dblen+1) ||
12769 write_data(tbuf, sizeof(tbuf)) ||
12770 write_data(m_tblnam, m_tbllen+1) ||
12771 write_data(cbuf, (size_t) (cbuf_end - cbuf)) ||
12772 write_data(m_coltype, m_colcnt) ||
12773 write_data(mbuf, (size_t) (mbuf_end - mbuf)) ||
12774 write_data(m_field_metadata, m_field_metadata_size),
12775 write_data(m_null_bits, (m_colcnt + 7) / 8);
12776 }
12777#endif
12778
12779#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12780
12781/*
12782 Print some useful information for the SHOW BINARY LOG information
12783 field.
12784 */
12785
12786#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12787void Table_map_log_event::pack_info(Protocol *protocol)
12788{
12789 char buf[256];
12790 size_t bytes= my_snprintf(buf, sizeof(buf),
12791 "table_id: %lu (%s.%s)",
12792 m_table_id, m_dbnam, m_tblnam);
12793 protocol->store(buf, bytes, &my_charset_bin);
12794}
12795#endif
12796
12797
12798#endif
12799
12800
12801#ifdef MYSQL_CLIENT
12802bool Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
12803{
12804 if (!print_event_info->short_form)
12805 {
12806 print_header(&print_event_info->head_cache, print_event_info, TRUE);
12807 if (my_b_printf(&print_event_info->head_cache,
12808 "\tTable_map: %`s.%`s mapped to number %lu%s\n",
12809 m_dbnam, m_tblnam, m_table_id,
12810 ((m_flags & TM_BIT_HAS_TRIGGERS_F) ?
12811 " (has triggers)" : "")))
12812 goto err;
12813 }
12814 if (!print_event_info->short_form || print_event_info->print_row_count)
12815 {
12816 if (print_base64(&print_event_info->body_cache, print_event_info, TRUE) ||
12817 copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
12818 file))
12819 goto err;
12820 }
12821
12822 return 0;
12823err:
12824 return 1;
12825}
12826#endif
12827
12828/**************************************************************************
12829 Write_rows_log_event member functions
12830**************************************************************************/
12831
12832/*
12833 Constructor used to build an event for writing to the binary log.
12834 */
12835#if !defined(MYSQL_CLIENT)
12836Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12837 ulong tid_arg,
12838 bool is_transactional)
12839 :Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->rpl_write_set,
12840 is_transactional, WRITE_ROWS_EVENT_V1)
12841{
12842}
12843
12844Write_rows_compressed_log_event::Write_rows_compressed_log_event(
12845 THD *thd_arg,
12846 TABLE *tbl_arg,
12847 ulong tid_arg,
12848 bool is_transactional)
12849 : Write_rows_log_event(thd_arg, tbl_arg, tid_arg, is_transactional)
12850{
12851 m_type = WRITE_ROWS_COMPRESSED_EVENT_V1;
12852}
12853
12854bool Write_rows_compressed_log_event::write()
12855{
12856 return Rows_log_event::write_compressed();
12857}
12858#endif
12859
12860/*
12861 Constructor used by slave to read the event from the binary log.
12862 */
12863#ifdef HAVE_REPLICATION
12864Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12865 const Format_description_log_event
12866 *description_event)
12867: Rows_log_event(buf, event_len, description_event)
12868{
12869}
12870
12871Write_rows_compressed_log_event::Write_rows_compressed_log_event(
12872 const char *buf, uint event_len,
12873 const Format_description_log_event
12874 *description_event)
12875: Write_rows_log_event(buf, event_len, description_event)
12876{
12877 uncompress_buf();
12878}
12879#endif
12880
12881#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12882int
12883Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12884{
12885 int error= 0;
12886
12887 /*
12888 Increment the global status insert count variable
12889 */
12890 if (get_flags(STMT_END_F))
12891 status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
12892
12893 /**
12894 todo: to introduce a property for the event (handler?) which forces
12895 applying the event in the replace (idempotent) fashion.
12896 */
12897 if (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT)
12898 {
12899 /*
12900 We are using REPLACE semantics and not INSERT IGNORE semantics
12901 when writing rows, that is: new rows replace old rows. We need to
12902 inform the storage engine that it should use this behaviour.
12903 */
12904
12905 /* Tell the storage engine that we are using REPLACE semantics. */
12906 thd->lex->duplicates= DUP_REPLACE;
12907
12908 /*
12909 Pretend we're executing a REPLACE command: this is needed for
12910 InnoDB since it is not (properly) checking the lex->duplicates flag.
12911 */
12912 thd->lex->sql_command= SQLCOM_REPLACE;
12913 /*
12914 Do not raise the error flag in case of hitting to an unique attribute
12915 */
12916 m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12917 /*
12918 The following is needed in case if we have AFTER DELETE triggers.
12919 */
12920 m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12921 m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12922 }
12923 if (slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers )
12924 m_table->prepare_triggers_for_insert_stmt_or_event();
12925
12926 /* Honor next number column if present */
12927 m_table->next_number_field= m_table->found_next_number_field;
12928 /*
12929 * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12930 * sequence numbers for auto_increment fields if the values of them are 0.
12931 * If generateing a sequence number is decided by the values of
12932 * table->auto_increment_field_not_null and SQL_MODE(if includes
12933 * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12934 * SQL_MODE of slave sql thread is always consistency with master's.
12935 * In RBR, auto_increment fields never are NULL, except if the auto_inc
12936 * column exists only on the slave side (i.e., in an extra column
12937 * on the slave's table).
12938 */
12939 if (!is_auto_inc_in_extra_columns())
12940 m_table->auto_increment_field_not_null= TRUE;
12941 else
12942 {
12943 /*
12944 Here we have checked that there is an extra field
12945 on this server's table that has an auto_inc column.
12946
12947 Mark that the auto_increment field is null and mark
12948 the read and write set bits.
12949
12950 (There can only be one AUTO_INC column, it is always
12951 indexed and it cannot have a DEFAULT value).
12952 */
12953 m_table->auto_increment_field_not_null= FALSE;
12954 m_table->mark_auto_increment_column();
12955 }
12956
12957 return error;
12958}
12959
12960int
12961Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12962 int error)
12963{
12964 int local_error= 0;
12965
12966 /**
12967 Clear the write_set bit for auto_inc field that only
12968 existed on the destination table as an extra column.
12969 */
12970 if (is_auto_inc_in_extra_columns())
12971 {
12972 bitmap_clear_bit(m_table->rpl_write_set,
12973 m_table->next_number_field->field_index);
12974 bitmap_clear_bit(m_table->read_set,
12975 m_table->next_number_field->field_index);
12976
12977 if (get_flags(STMT_END_F))
12978 m_table->file->ha_release_auto_increment();
12979 }
12980 m_table->next_number_field=0;
12981 m_table->auto_increment_field_not_null= FALSE;
12982 if (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT)
12983 {
12984 m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
12985 m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
12986 /*
12987 resetting the extra with
12988 table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
12989 fires bug#27077
12990 explanation: file->reset() performs this duty
12991 ultimately. Still todo: fix
12992 */
12993 }
12994 if (unlikely((local_error= m_table->file->ha_end_bulk_insert())))
12995 {
12996 m_table->file->print_error(local_error, MYF(0));
12997 }
12998 return error? error : local_error;
12999}
13000
13001#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13002
13003bool Rows_log_event::process_triggers(trg_event_type event,
13004 trg_action_time_type time_type,
13005 bool old_row_is_record1)
13006{
13007 bool result;
13008 DBUG_ENTER("Rows_log_event::process_triggers");
13009 m_table->triggers->mark_fields_used(event);
13010 if (slave_run_triggers_for_rbr == SLAVE_RUN_TRIGGERS_FOR_RBR_YES)
13011 {
13012 tmp_disable_binlog(thd); /* Do not replicate the low-level changes. */
13013 result= m_table->triggers->process_triggers(thd, event,
13014 time_type, old_row_is_record1);
13015 reenable_binlog(thd);
13016 }
13017 else
13018 result= m_table->triggers->process_triggers(thd, event,
13019 time_type, old_row_is_record1);
13020
13021 DBUG_RETURN(result);
13022}
13023/*
13024 Check if there are more UNIQUE keys after the given key.
13025*/
13026static int
13027last_uniq_key(TABLE *table, uint keyno)
13028{
13029 while (++keyno < table->s->keys)
13030 if (table->key_info[keyno].flags & HA_NOSAME)
13031 return 0;
13032 return 1;
13033}
13034
13035/**
13036 Check if an error is a duplicate key error.
13037
13038 This function is used to check if an error code is one of the
13039 duplicate key error, i.e., and error code for which it is sensible
13040 to do a <code>get_dup_key()</code> to retrieve the duplicate key.
13041
13042 @param errcode The error code to check.
13043
13044 @return <code>true</code> if the error code is such that
13045 <code>get_dup_key()</code> will return true, <code>false</code>
13046 otherwise.
13047 */
13048bool
13049is_duplicate_key_error(int errcode)
13050{
13051 switch (errcode)
13052 {
13053 case HA_ERR_FOUND_DUPP_KEY:
13054 case HA_ERR_FOUND_DUPP_UNIQUE:
13055 return true;
13056 }
13057 return false;
13058}
13059
13060/**
13061 Write the current row into event's table.
13062
13063 The row is located in the row buffer, pointed by @c m_curr_row member.
13064 Number of columns of the row is stored in @c m_width member (it can be
13065 different from the number of columns in the table to which we insert).
13066 Bitmap @c m_cols indicates which columns are present in the row. It is assumed
13067 that event's table is already open and pointed by @c m_table.
13068
13069 If the same record already exists in the table it can be either overwritten
13070 or an error is reported depending on the value of @c overwrite flag
13071 (error reporting not yet implemented). Note that the matching record can be
13072 different from the row we insert if we use primary keys to identify records in
13073 the table.
13074
13075 The row to be inserted can contain values only for selected columns. The
13076 missing columns are filled with default values using @c prepare_record()
13077 function. If a matching record is found in the table and @c overwritte is
13078 true, the missing columns are taken from it.
13079
13080 @param rli Relay log info (needed for row unpacking).
13081 @param overwrite
13082 Shall we overwrite if the row already exists or signal
13083 error (currently ignored).
13084
13085 @returns Error code on failure, 0 on success.
13086
13087 This method, if successful, sets @c m_curr_row_end pointer to point at the
13088 next row in the rows buffer. This is done when unpacking the row to be
13089 inserted.
13090
13091 @note If a matching record is found, it is either updated using
13092 @c ha_update_row() or first deleted and then new record written.
13093*/
13094
13095int
13096Rows_log_event::write_row(rpl_group_info *rgi,
13097 const bool overwrite)
13098{
13099 DBUG_ENTER("write_row");
13100 DBUG_ASSERT(m_table != NULL && thd != NULL);
13101
13102 TABLE *table= m_table; // pointer to event's table
13103 int error;
13104 int UNINIT_VAR(keynum);
13105 const bool invoke_triggers=
13106 slave_run_triggers_for_rbr && !master_had_triggers && table->triggers;
13107 auto_afree_ptr<char> key(NULL);
13108
13109 prepare_record(table, m_width, true);
13110
13111 /* unpack row into table->record[0] */
13112 if (unlikely((error= unpack_current_row(rgi))))
13113 {
13114 table->file->print_error(error, MYF(0));
13115 DBUG_RETURN(error);
13116 }
13117
13118 if (m_curr_row == m_rows_buf && !invoke_triggers)
13119 {
13120 /*
13121 This table has no triggers so we can do bulk insert.
13122
13123 This is the first row to be inserted, we estimate the rows with
13124 the size of the first row and use that value to initialize
13125 storage engine for bulk insertion.
13126 */
13127 /* this is the first row to be inserted, we estimate the rows with
13128 the size of the first row and use that value to initialize
13129 storage engine for bulk insertion */
13130 DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
13131 ha_rows estimated_rows= 0;
13132 if (m_curr_row < m_curr_row_end)
13133 estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
13134 else if (m_curr_row == m_curr_row_end)
13135 estimated_rows= 1;
13136
13137 table->file->ha_start_bulk_insert(estimated_rows);
13138 }
13139
13140 /*
13141 Explicitly set the auto_inc to null to make sure that
13142 it gets an auto_generated value.
13143 */
13144 if (is_auto_inc_in_extra_columns())
13145 m_table->next_number_field->set_null();
13146
13147 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13148 DBUG_PRINT_BITSET("debug", "rpl_write_set: %s", table->rpl_write_set);
13149 DBUG_PRINT_BITSET("debug", "read_set: %s", table->read_set);
13150
13151 if (invoke_triggers &&
13152 unlikely(process_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE, TRUE)))
13153 {
13154 DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet
13155 }
13156
13157 // Handle INSERT.
13158 // Set vers fields when replicating from not system-versioned table.
13159 if (m_type == WRITE_ROWS_EVENT_V1 && table->versioned(VERS_TIMESTAMP))
13160 {
13161 ulong sec_part;
13162 bitmap_set_bit(table->read_set, table->vers_start_field()->field_index);
13163 // Check whether a row came from unversioned table and fix vers fields.
13164 if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0)
13165 table->vers_update_fields();
13166 }
13167
13168 /*
13169 Try to write record. If a corresponding record already exists in the table,
13170 we try to change it using ha_update_row() if possible. Otherwise we delete
13171 it and repeat the whole process again.
13172
13173 TODO: Add safety measures against infinite looping.
13174 */
13175
13176 if (table->s->sequence)
13177 error= update_sequence();
13178 else while (unlikely(error= table->file->ha_write_row(table->record[0])))
13179 {
13180 if (error == HA_ERR_LOCK_DEADLOCK ||
13181 error == HA_ERR_LOCK_WAIT_TIMEOUT ||
13182 (keynum= table->file->get_dup_key(error)) < 0 ||
13183 !overwrite)
13184 {
13185 DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
13186 /*
13187 Deadlock, waiting for lock or just an error from the handler
13188 such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
13189 Retrieval of the duplicate key number may fail
13190 - either because the error was not "duplicate key" error
13191 - or because the information which key is not available
13192 */
13193 table->file->print_error(error, MYF(0));
13194 DBUG_RETURN(error);
13195 }
13196 /*
13197 We need to retrieve the old row into record[1] to be able to
13198 either update or delete the offending record. We either:
13199
13200 - use rnd_pos() with a row-id (available as dupp_row) to the
13201 offending row, if that is possible (MyISAM and Blackhole), or else
13202
13203 - use index_read_idx() with the key that is duplicated, to
13204 retrieve the offending row.
13205 */
13206 if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
13207 {
13208 DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
13209 error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
13210 if (unlikely(error))
13211 {
13212 DBUG_PRINT("info",("rnd_pos() returns error %d",error));
13213 table->file->print_error(error, MYF(0));
13214 DBUG_RETURN(error);
13215 }
13216 }
13217 else
13218 {
13219 DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
13220
13221 if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
13222 {
13223 DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
13224 DBUG_RETURN(my_errno);
13225 }
13226
13227 if (key.get() == NULL)
13228 {
13229 key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
13230 if (key.get() == NULL)
13231 {
13232 DBUG_PRINT("info",("Can't allocate key buffer"));
13233 DBUG_RETURN(ENOMEM);
13234 }
13235 }
13236
13237 key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
13238 0);
13239 error= table->file->ha_index_read_idx_map(table->record[1], keynum,
13240 (const uchar*)key.get(),
13241 HA_WHOLE_KEY,
13242 HA_READ_KEY_EXACT);
13243 if (unlikely(error))
13244 {
13245 DBUG_PRINT("info",("index_read_idx() returns %s", HA_ERR(error)));
13246 table->file->print_error(error, MYF(0));
13247 DBUG_RETURN(error);
13248 }
13249 }
13250
13251 /*
13252 Now, record[1] should contain the offending row. That
13253 will enable us to update it or, alternatively, delete it (so
13254 that we can insert the new row afterwards).
13255 */
13256
13257 /*
13258 If row is incomplete we will use the record found to fill
13259 missing columns.
13260 */
13261 if (!get_flags(COMPLETE_ROWS_F))
13262 {
13263 restore_record(table,record[1]);
13264 error= unpack_current_row(rgi);
13265 }
13266
13267 DBUG_PRINT("debug",("preparing for update: before and after image"));
13268 DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
13269 DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
13270
13271 /*
13272 REPLACE is defined as either INSERT or DELETE + INSERT. If
13273 possible, we can replace it with an UPDATE, but that will not
13274 work on InnoDB if FOREIGN KEY checks are necessary.
13275
13276 I (Matz) am not sure of the reason for the last_uniq_key()
13277 check as, but I'm guessing that it's something along the
13278 following lines.
13279
13280 Suppose that we got the duplicate key to be a key that is not
13281 the last unique key for the table and we perform an update:
13282 then there might be another key for which the unique check will
13283 fail, so we're better off just deleting the row and inserting
13284 the correct row.
13285
13286 Additionally we don't use UPDATE if rbr triggers should be invoked -
13287 when triggers are used we want a simple and predictable execution path.
13288 */
13289 if (last_uniq_key(table, keynum) && !invoke_triggers &&
13290 !table->file->referenced_by_foreign_key())
13291 {
13292 DBUG_PRINT("info",("Updating row using ha_update_row()"));
13293 error= table->file->ha_update_row(table->record[1],
13294 table->record[0]);
13295 switch (error) {
13296
13297 case HA_ERR_RECORD_IS_THE_SAME:
13298 DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
13299 " ha_update_row()"));
13300 error= 0;
13301
13302 case 0:
13303 break;
13304
13305 default:
13306 DBUG_PRINT("info",("ha_update_row() returns error %d",error));
13307 table->file->print_error(error, MYF(0));
13308 }
13309
13310 DBUG_RETURN(error);
13311 }
13312 else
13313 {
13314 DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
13315 if (invoke_triggers &&
13316 unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE,
13317 TRUE)))
13318 error= HA_ERR_GENERIC; // in case if error is not set yet
13319 else
13320 {
13321 if (unlikely((error= table->file->ha_delete_row(table->record[1]))))
13322 {
13323 DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
13324 table->file->print_error(error, MYF(0));
13325 DBUG_RETURN(error);
13326 }
13327 if (invoke_triggers &&
13328 unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER,
13329 TRUE)))
13330 DBUG_RETURN(HA_ERR_GENERIC); // in case if error is not set yet
13331 }
13332 /* Will retry ha_write_row() with the offending row removed. */
13333 }
13334 }
13335
13336 if (invoke_triggers &&
13337 unlikely(process_triggers(TRG_EVENT_INSERT, TRG_ACTION_AFTER, TRUE)))
13338 error= HA_ERR_GENERIC; // in case if error is not set yet
13339
13340 DBUG_RETURN(error);
13341}
13342
13343
13344int Rows_log_event::update_sequence()
13345{
13346 TABLE *table= m_table; // pointer to event's table
13347
13348 if (!bitmap_is_set(table->rpl_write_set, MIN_VALUE_FIELD_NO))
13349 {
13350 /* This event come from a setval function executed on the master.
13351 Update the sequence next_number and round, like we do with setval()
13352 */
13353 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
13354 table->read_set);
13355 longlong nextval= table->field[NEXT_FIELD_NO]->val_int();
13356 longlong round= table->field[ROUND_FIELD_NO]->val_int();
13357 dbug_tmp_restore_column_map(table->read_set, old_map);
13358
13359 return table->s->sequence->set_value(table, nextval, round, 0) > 0;
13360 }
13361
13362 /*
13363 Update all fields in table and update the active sequence, like with
13364 ALTER SEQUENCE
13365 */
13366 return table->file->ha_write_row(table->record[0]);
13367}
13368
13369
13370#endif
13371
13372int
13373Write_rows_log_event::do_exec_row(rpl_group_info *rgi)
13374{
13375 DBUG_ASSERT(m_table != NULL);
13376 const char *tmp= thd->get_proc_info();
13377 const char *message= "Write_rows_log_event::write_row()";
13378 int error;
13379
13380#ifdef WSREP_PROC_INFO
13381 my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
13382 "Write_rows_log_event::write_row(%lld)",
13383 (long long) wsrep_thd_trx_seqno(thd));
13384 message= thd->wsrep_info;
13385#endif /* WSREP_PROC_INFO */
13386
13387 thd_proc_info(thd, message);
13388 error= write_row(rgi, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
13389 thd_proc_info(thd, tmp);
13390
13391 if (unlikely(error) && unlikely(!thd->is_error()))
13392 {
13393 DBUG_ASSERT(0);
13394 my_error(ER_UNKNOWN_ERROR, MYF(0));
13395 }
13396
13397 return error;
13398}
13399
13400#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13401
13402#ifdef MYSQL_CLIENT
13403bool Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
13404{
13405 DBUG_EXECUTE_IF("simulate_cache_read_error",
13406 {DBUG_SET("+d,simulate_my_b_fill_error");});
13407 return Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Delete_rows" : "Write_rows");
13408}
13409
13410bool Write_rows_compressed_log_event::print(FILE *file,
13411 PRINT_EVENT_INFO* print_event_info)
13412{
13413 char *new_buf;
13414 ulong len;
13415 bool is_malloc = false;
13416 if(!row_log_event_uncompress(glob_description_event,
13417 checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
13418 temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len))
13419 {
13420 free_temp_buf();
13421 register_temp_buf(new_buf, true);
13422 if (Rows_log_event::print_helper(file, print_event_info,
13423 "Write_compressed_rows"))
13424 goto err;
13425 }
13426 else
13427 {
13428 if (my_b_printf(&print_event_info->head_cache,
13429 "ERROR: uncompress write_compressed_rows failed\n"))
13430 goto err;
13431 }
13432
13433 return 0;
13434err:
13435 return 1;
13436}
13437#endif
13438
13439
13440#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
13441uint8 Write_rows_log_event::get_trg_event_map()
13442{
13443 return (static_cast<uint8> (1 << static_cast<int>(TRG_EVENT_INSERT)) |
13444 static_cast<uint8> (1 << static_cast<int>(TRG_EVENT_UPDATE)) |
13445 static_cast<uint8> (1 << static_cast<int>(TRG_EVENT_DELETE)));
13446}
13447#endif
13448
13449/**************************************************************************
13450 Delete_rows_log_event member functions
13451**************************************************************************/
13452
13453#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13454/*
13455 Compares table->record[0] and table->record[1]
13456
13457 Returns TRUE if different.
13458*/
13459static bool record_compare(TABLE *table)
13460{
13461 bool result= FALSE;
13462 /**
13463 Compare full record only if:
13464 - there are no blob fields (otherwise we would also need
13465 to compare blobs contents as well);
13466 - there are no varchar fields (otherwise we would also need
13467 to compare varchar contents as well);
13468 - there are no null fields, otherwise NULLed fields
13469 contents (i.e., the don't care bytes) may show arbitrary
13470 values, depending on how each engine handles internally.
13471 */
13472 if ((table->s->blob_fields +
13473 table->s->varchar_fields +
13474 table->s->null_fields) == 0)
13475 {
13476 result= cmp_record(table,record[1]);
13477 goto record_compare_exit;
13478 }
13479
13480 /* Compare null bits */
13481 if (memcmp(table->null_flags,
13482 table->null_flags+table->s->rec_buff_length,
13483 table->s->null_bytes))
13484 {
13485 result= TRUE; // Diff in NULL value
13486 goto record_compare_exit;
13487 }
13488
13489 /* Compare fields */
13490 for (Field **ptr=table->field ; *ptr ; ptr++)
13491 {
13492 if (table->versioned() && (*ptr)->vers_sys_field())
13493 {
13494 continue;
13495 }
13496 /**
13497 We only compare field contents that are not null.
13498 NULL fields (i.e., their null bits) were compared
13499 earlier.
13500 */
13501 if (!(*(ptr))->is_null())
13502 {
13503 if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
13504 {
13505 result= TRUE;
13506 goto record_compare_exit;
13507 }
13508 }
13509 }
13510
13511record_compare_exit:
13512 return result;
13513}
13514
13515
13516/**
13517 Find the best key to use when locating the row in @c find_row().
13518
13519 A primary key is preferred if it exists; otherwise a unique index is
13520 preferred. Else we pick the index with the smalles rec_per_key value.
13521
13522 If a suitable key is found, set @c m_key, @c m_key_nr and @c m_key_info
13523 member fields appropriately.
13524
13525 @returns Error code on failure, 0 on success.
13526*/
13527int Rows_log_event::find_key()
13528{
13529 uint i, best_key_nr, last_part;
13530 KEY *key, *UNINIT_VAR(best_key);
13531 ulong UNINIT_VAR(best_rec_per_key), tmp;
13532 DBUG_ENTER("Rows_log_event::find_key");
13533 DBUG_ASSERT(m_table);
13534
13535 best_key_nr= MAX_KEY;
13536
13537 /*
13538 Keys are sorted so that any primary key is first, followed by unique keys,
13539 followed by any other. So we will automatically pick the primary key if
13540 it exists.
13541 */
13542 for (i= 0, key= m_table->key_info; i < m_table->s->keys; i++, key++)
13543 {
13544 if (!m_table->s->keys_in_use.is_set(i))
13545 continue;
13546 /*
13547 We cannot use a unique key with NULL-able columns to uniquely identify
13548 a row (but we can still select it for range scan below if nothing better
13549 is available).
13550 */
13551 if ((key->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
13552 {
13553 best_key_nr= i;
13554 best_key= key;
13555 break;
13556 }
13557 /*
13558 We can only use a non-unique key if it allows range scans (ie. skip
13559 FULLTEXT indexes and such).
13560 */
13561 last_part= key->user_defined_key_parts - 1;
13562 DBUG_PRINT("info", ("Index %s rec_per_key[%u]= %lu",
13563 key->name.str, last_part, key->rec_per_key[last_part]));
13564 if (!(m_table->file->index_flags(i, last_part, 1) & HA_READ_NEXT))
13565 continue;
13566
13567 tmp= key->rec_per_key[last_part];
13568 if (best_key_nr == MAX_KEY || (tmp > 0 && tmp < best_rec_per_key))
13569 {
13570 best_key_nr= i;
13571 best_key= key;
13572 best_rec_per_key= tmp;
13573 }
13574 }
13575
13576 if (best_key_nr == MAX_KEY)
13577 {
13578 m_key_info= NULL;
13579 DBUG_RETURN(0);
13580 }
13581
13582 // Allocate buffer for key searches
13583 m_key= (uchar *) my_malloc(best_key->key_length, MYF(MY_WME));
13584 if (m_key == NULL)
13585 DBUG_RETURN(HA_ERR_OUT_OF_MEM);
13586 m_key_info= best_key;
13587 m_key_nr= best_key_nr;
13588
13589 DBUG_RETURN(0);;
13590}
13591
13592
13593/*
13594 Check if we are already spending too much time on this statement.
13595 if we are, warn user that it might be because table does not have
13596 a PK, but only if the warning was not printed before for this STMT.
13597
13598 @param type The event type code.
13599 @param table_name The name of the table that the slave is
13600 operating.
13601 @param is_index_scan States whether the slave is doing an index scan
13602 or not.
13603 @param rli The relay metadata info.
13604*/
13605static inline
13606void issue_long_find_row_warning(Log_event_type type,
13607 const char *table_name,
13608 bool is_index_scan,
13609 rpl_group_info *rgi)
13610{
13611 if ((global_system_variables.log_warnings > 1 &&
13612 !rgi->is_long_find_row_note_printed()))
13613 {
13614 ulonglong now= microsecond_interval_timer();
13615 ulonglong stmt_ts= rgi->get_row_stmt_start_timestamp();
13616
13617 DBUG_EXECUTE_IF("inject_long_find_row_note",
13618 stmt_ts-=(LONG_FIND_ROW_THRESHOLD*2*HRTIME_RESOLUTION););
13619
13620 longlong delta= (now - stmt_ts)/HRTIME_RESOLUTION;
13621
13622 if (delta > LONG_FIND_ROW_THRESHOLD)
13623 {
13624 rgi->set_long_find_row_note_printed();
13625 const char* evt_type= LOG_EVENT_IS_DELETE_ROW(type) ? " DELETE" : "n UPDATE";
13626 const char* scan_type= is_index_scan ? "scanning an index" : "scanning the table";
13627
13628 sql_print_information("The slave is applying a ROW event on behalf of a%s statement "
13629 "on table %s and is currently taking a considerable amount "
13630 "of time (%lld seconds). This is due to the fact that it is %s "
13631 "while looking up records to be processed. Consider adding a "
13632 "primary key (or unique key) to the table to improve "
13633 "performance.",
13634 evt_type, table_name, (long) delta, scan_type);
13635 }
13636 }
13637}
13638
13639
13640/**
13641 Locate the current row in event's table.
13642
13643 The current row is pointed by @c m_curr_row. Member @c m_width tells
13644 how many columns are there in the row (this can be differnet from
13645 the number of columns in the table). It is assumed that event's
13646 table is already open and pointed by @c m_table.
13647
13648 If a corresponding record is found in the table it is stored in
13649 @c m_table->record[0]. Note that when record is located based on a primary
13650 key, it is possible that the record found differs from the row being located.
13651
13652 If no key is specified or table does not have keys, a table scan is used to
13653 find the row. In that case the row should be complete and contain values for
13654 all columns. However, it can still be shorter than the table, i.e. the table
13655 can contain extra columns not present in the row. It is also possible that
13656 the table has fewer columns than the row being located.
13657
13658 @returns Error code on failure, 0 on success.
13659
13660 @post In case of success @c m_table->record[0] contains the record found.
13661 Also, the internal "cursor" of the table is positioned at the record found.
13662
13663 @note If the engine allows random access of the records, a combination of
13664 @c position() and @c rnd_pos() will be used.
13665
13666 Note that one MUST call ha_index_or_rnd_end() after this function if
13667 it returns 0 as we must leave the row position in the handler intact
13668 for any following update/delete command.
13669*/
13670
13671int Rows_log_event::find_row(rpl_group_info *rgi)
13672{
13673 DBUG_ENTER("Rows_log_event::find_row");
13674
13675 DBUG_ASSERT(m_table && m_table->in_use != NULL);
13676
13677 TABLE *table= m_table;
13678 int error= 0;
13679 bool is_table_scan= false, is_index_scan= false;
13680
13681 /*
13682 rpl_row_tabledefs.test specifies that
13683 if the extra field on the slave does not have a default value
13684 and this is okay with Delete or Update events.
13685 Todo: fix wl3228 hld that requires defauls for all types of events
13686 */
13687
13688 prepare_record(table, m_width, FALSE);
13689 error= unpack_current_row(rgi);
13690
13691 m_vers_from_plain= false;
13692 if (table->versioned())
13693 {
13694 Field *row_end= table->vers_end_field();
13695 DBUG_ASSERT(table->read_set);
13696 bitmap_set_bit(table->read_set, row_end->field_index);
13697 // check whether master table is unversioned
13698 if (row_end->val_int() == 0)
13699 {
13700 bitmap_set_bit(table->write_set, row_end->field_index);
13701 // Plain source table may have a PRIMARY KEY. And row_end is always
13702 // a part of PRIMARY KEY. Set it to max value for engine to find it in
13703 // index. Needed for an UPDATE/DELETE cases.
13704 table->vers_end_field()->set_max();
13705 m_vers_from_plain= true;
13706 }
13707 }
13708
13709 DBUG_PRINT("info",("looking for the following record"));
13710 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13711
13712 if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
13713 table->s->primary_key < MAX_KEY)
13714 {
13715 /*
13716 Use a more efficient method to fetch the record given by
13717 table->record[0] if the engine allows it. We first compute a
13718 row reference using the position() member function (it will be
13719 stored in table->file->ref) and the use rnd_pos() to position
13720 the "cursor" (i.e., record[0] in this case) at the correct row.
13721
13722 TODO: Add a check that the correct record has been fetched by
13723 comparing with the original record. Take into account that the
13724 record on the master and slave can be of different
13725 length. Something along these lines should work:
13726
13727 ADD>>> store_record(table,record[1]);
13728 int error= table->file->ha_rnd_pos(table->record[0],
13729 table->file->ref);
13730 ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
13731 table->s->reclength) == 0);
13732
13733 */
13734 int error;
13735 DBUG_PRINT("info",("locating record using primary key (position)"));
13736
13737 if (!table->file->inited &&
13738 (error= table->file->ha_rnd_init_with_error(0)))
13739 DBUG_RETURN(error);
13740
13741 error= table->file->ha_rnd_pos_by_record(table->record[0]);
13742 if (unlikely(error))
13743 {
13744 DBUG_PRINT("info",("rnd_pos returns error %d",error));
13745 table->file->print_error(error, MYF(0));
13746 }
13747 DBUG_RETURN(error);
13748 }
13749
13750 // We can't use position() - try other methods.
13751
13752 /*
13753 We need to retrieve all fields
13754 TODO: Move this out from this function to main loop
13755 */
13756 table->use_all_columns();
13757
13758 /*
13759 Save copy of the record in table->record[1]. It might be needed
13760 later if linear search is used to find exact match.
13761 */
13762 store_record(table,record[1]);
13763
13764 if (m_key_info)
13765 {
13766 DBUG_PRINT("info",("locating record using key #%u [%s] (index_read)",
13767 m_key_nr, m_key_info->name.str));
13768 /* We use this to test that the correct key is used in test cases. */
13769 DBUG_EXECUTE_IF("slave_crash_if_wrong_index",
13770 if(0 != strcmp(m_key_info->name.str,"expected_key")) abort(););
13771
13772 /* The key is active: search the table using the index */
13773 if (!table->file->inited &&
13774 (error= table->file->ha_index_init(m_key_nr, FALSE)))
13775 {
13776 DBUG_PRINT("info",("ha_index_init returns error %d",error));
13777 table->file->print_error(error, MYF(0));
13778 goto end;
13779 }
13780
13781 /* Fill key data for the row */
13782
13783 DBUG_ASSERT(m_key);
13784 key_copy(m_key, table->record[0], m_key_info, 0);
13785
13786 /*
13787 Don't print debug messages when running valgrind since they can
13788 trigger false warnings.
13789 */
13790#ifndef HAVE_valgrind
13791 DBUG_DUMP("key data", m_key, m_key_info->key_length);
13792#endif
13793
13794 /*
13795 We need to set the null bytes to ensure that the filler bit are
13796 all set when returning. There are storage engines that just set
13797 the necessary bits on the bytes and don't set the filler bits
13798 correctly.
13799 */
13800 if (table->s->null_bytes > 0)
13801 table->record[0][table->s->null_bytes - 1]|=
13802 256U - (1U << table->s->last_null_bit_pos);
13803
13804 if (unlikely((error= table->file->ha_index_read_map(table->record[0],
13805 m_key,
13806 HA_WHOLE_KEY,
13807 HA_READ_KEY_EXACT))))
13808 {
13809 DBUG_PRINT("info",("no record matching the key found in the table"));
13810 table->file->print_error(error, MYF(0));
13811 table->file->ha_index_end();
13812 goto end;
13813 }
13814
13815 /*
13816 Don't print debug messages when running valgrind since they can
13817 trigger false warnings.
13818 */
13819#ifndef HAVE_valgrind
13820 DBUG_PRINT("info",("found first matching record"));
13821 DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13822#endif
13823 /*
13824 Below is a minor "optimization". If the key (i.e., key number
13825 0) has the HA_NOSAME flag set, we know that we have found the
13826 correct record (since there can be no duplicates); otherwise, we
13827 have to compare the record with the one found to see if it is
13828 the correct one.
13829
13830 CAVEAT! This behaviour is essential for the replication of,
13831 e.g., the mysql.proc table since the correct record *shall* be
13832 found using the primary key *only*. There shall be no
13833 comparison of non-PK columns to decide if the correct record is
13834 found. I can see no scenario where it would be incorrect to
13835 chose the row to change only using a PK or an UNNI.
13836 */
13837 if (table->key_info->flags & HA_NOSAME)
13838 {
13839 /* Unique does not have non nullable part */
13840 if (!(table->key_info->flags & (HA_NULL_PART_KEY)))
13841 {
13842 error= 0;
13843 goto end;
13844 }
13845 else
13846 {
13847 KEY *keyinfo= table->key_info;
13848 /*
13849 Unique has nullable part. We need to check if there is any
13850 field in the BI image that is null and part of UNNI.
13851 */
13852 bool null_found= FALSE;
13853 for (uint i=0; i < keyinfo->user_defined_key_parts && !null_found; i++)
13854 {
13855 uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
13856 Field **f= table->field+fieldnr;
13857 null_found= (*f)->is_null();
13858 }
13859
13860 if (!null_found)
13861 {
13862 error= 0;
13863 goto end;
13864 }
13865
13866 /* else fall through to index scan */
13867 }
13868 }
13869
13870 is_index_scan=true;
13871
13872 /*
13873 In case key is not unique, we still have to iterate over records found
13874 and find the one which is identical to the row given. A copy of the
13875 record we are looking for is stored in record[1].
13876 */
13877 DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
13878 /* We use this to test that the correct key is used in test cases. */
13879 DBUG_EXECUTE_IF("slave_crash_if_index_scan", abort(););
13880
13881 while (record_compare(table))
13882 {
13883 while ((error= table->file->ha_index_next(table->record[0])))
13884 {
13885 DBUG_PRINT("info",("no record matching the given row found"));
13886 table->file->print_error(error, MYF(0));
13887 table->file->ha_index_end();
13888 goto end;
13889 }
13890 }
13891 }
13892 else
13893 {
13894 DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
13895 /* We use this to test that the correct key is used in test cases. */
13896 DBUG_EXECUTE_IF("slave_crash_if_table_scan", abort(););
13897
13898 /* We don't have a key: search the table using rnd_next() */
13899 if (unlikely((error= table->file->ha_rnd_init_with_error(1))))
13900 {
13901 DBUG_PRINT("info",("error initializing table scan"
13902 " (ha_rnd_init returns %d)",error));
13903 goto end;
13904 }
13905
13906 is_table_scan= true;
13907
13908 /* Continue until we find the right record or have made a full loop */
13909 do
13910 {
13911 error= table->file->ha_rnd_next(table->record[0]);
13912
13913 if (unlikely(error))
13914 DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
13915 switch (error) {
13916
13917 case 0:
13918 DBUG_DUMP("record found", table->record[0], table->s->reclength);
13919 break;
13920
13921 case HA_ERR_END_OF_FILE:
13922 DBUG_PRINT("info", ("Record not found"));
13923 table->file->ha_rnd_end();
13924 goto end;
13925
13926 default:
13927 DBUG_PRINT("info", ("Failed to get next record"
13928 " (rnd_next returns %d)",error));
13929 table->file->print_error(error, MYF(0));
13930 table->file->ha_rnd_end();
13931 goto end;
13932 }
13933 }
13934 while (record_compare(table));
13935
13936 /*
13937 Note: above record_compare will take into accout all record fields
13938 which might be incorrect in case a partial row was given in the event
13939 */
13940
13941 DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
13942 }
13943
13944end:
13945 if (is_table_scan || is_index_scan)
13946 issue_long_find_row_warning(get_general_type_code(), m_table->alias.c_ptr(),
13947 is_index_scan, rgi);
13948 table->default_column_bitmaps();
13949 DBUG_RETURN(error);
13950}
13951
13952#endif
13953
13954/*
13955 Constructor used to build an event for writing to the binary log.
13956 */
13957
13958#ifndef MYSQL_CLIENT
13959Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13960 ulong tid, bool is_transactional)
13961 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13962 DELETE_ROWS_EVENT_V1)
13963{
13964}
13965
13966Delete_rows_compressed_log_event::Delete_rows_compressed_log_event(
13967 THD *thd_arg, TABLE *tbl_arg,
13968 ulong tid_arg,
13969 bool is_transactional)
13970 : Delete_rows_log_event(thd_arg, tbl_arg, tid_arg, is_transactional)
13971{
13972 m_type= DELETE_ROWS_COMPRESSED_EVENT_V1;
13973}
13974
13975bool Delete_rows_compressed_log_event::write()
13976{
13977 return Rows_log_event::write_compressed();
13978}
13979#endif /* #if !defined(MYSQL_CLIENT) */
13980
13981/*
13982 Constructor used by slave to read the event from the binary log.
13983 */
13984#ifdef HAVE_REPLICATION
13985Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
13986 const Format_description_log_event
13987 *description_event)
13988 : Rows_log_event(buf, event_len, description_event)
13989{
13990}
13991
13992Delete_rows_compressed_log_event::Delete_rows_compressed_log_event(
13993 const char *buf, uint event_len,
13994 const Format_description_log_event
13995 *description_event)
13996 : Delete_rows_log_event(buf, event_len, description_event)
13997{
13998 uncompress_buf();
13999}
14000#endif
14001
14002#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
14003
14004int
14005Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
14006{
14007 /*
14008 Increment the global status delete count variable
14009 */
14010 if (get_flags(STMT_END_F))
14011 status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
14012
14013 if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
14014 m_table->s->primary_key < MAX_KEY)
14015 {
14016 /*
14017 We don't need to allocate any memory for m_key since it is not used.
14018 */
14019 return 0;
14020 }
14021 if (slave_run_triggers_for_rbr && !master_had_triggers)
14022 m_table->prepare_triggers_for_delete_stmt_or_event();
14023
14024 return find_key();
14025}
14026
14027int
14028Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
14029 int error)
14030{
14031 m_table->file->ha_index_or_rnd_end();
14032 my_free(m_key);
14033 m_key= NULL;
14034 m_key_info= NULL;
14035
14036 return error;
14037}
14038
14039int Delete_rows_log_event::do_exec_row(rpl_group_info *rgi)
14040{
14041 int error;
14042 const char *tmp= thd->get_proc_info();
14043 const char *message= "Delete_rows_log_event::find_row()";
14044 const bool invoke_triggers=
14045 slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers;
14046 DBUG_ASSERT(m_table != NULL);
14047
14048#ifdef WSREP_PROC_INFO
14049 my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
14050 "Delete_rows_log_event::find_row(%lld)",
14051 (long long) wsrep_thd_trx_seqno(thd));
14052 message= thd->wsrep_info;
14053#endif /* WSREP_PROC_INFO */
14054
14055 thd_proc_info(thd, message);
14056 if (likely(!(error= find_row(rgi))))
14057 {
14058 /*
14059 Delete the record found, located in record[0]
14060 */
14061 message= "Delete_rows_log_event::ha_delete_row()";
14062#ifdef WSREP_PROC_INFO
14063 snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
14064 "Delete_rows_log_event::ha_delete_row(%lld)",
14065 (long long) wsrep_thd_trx_seqno(thd));
14066 message= thd->wsrep_info;
14067#endif
14068 thd_proc_info(thd, message);
14069
14070 if (invoke_triggers &&
14071 unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)))
14072 error= HA_ERR_GENERIC; // in case if error is not set yet
14073 if (likely(!error))
14074 {
14075 m_table->mark_columns_per_binlog_row_image();
14076 if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
14077 {
14078 Field *end= m_table->vers_end_field();
14079 bitmap_set_bit(m_table->write_set, end->field_index);
14080 store_record(m_table, record[1]);
14081 end->set_time();
14082 error= m_table->file->ha_update_row(m_table->record[1],
14083 m_table->record[0]);
14084 }
14085 else
14086 {
14087 error= m_table->file->ha_delete_row(m_table->record[0]);
14088 }
14089 m_table->default_column_bitmaps();
14090 }
14091 if (invoke_triggers && likely(!error) &&
14092 unlikely(process_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE)))
14093 error= HA_ERR_GENERIC; // in case if error is not set yet
14094 m_table->file->ha_index_or_rnd_end();
14095 }
14096 thd_proc_info(thd, tmp);
14097 return error;
14098}
14099
14100#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
14101
14102#ifdef MYSQL_CLIENT
14103bool Delete_rows_log_event::print(FILE *file,
14104 PRINT_EVENT_INFO* print_event_info)
14105{
14106 return Rows_log_event::print_helper(file, print_event_info, is_flashback ? "Write_rows" : "Delete_rows");
14107}
14108
14109bool Delete_rows_compressed_log_event::print(FILE *file,
14110 PRINT_EVENT_INFO* print_event_info)
14111{
14112 char *new_buf;
14113 ulong len;
14114 bool is_malloc = false;
14115 if(!row_log_event_uncompress(glob_description_event,
14116 checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
14117 temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len))
14118 {
14119 free_temp_buf();
14120 register_temp_buf(new_buf, true);
14121 if (Rows_log_event::print_helper(file, print_event_info,
14122 "Delete_compressed_rows"))
14123 goto err;
14124 }
14125 else
14126 {
14127 if (my_b_printf(&print_event_info->head_cache,
14128 "ERROR: uncompress delete_compressed_rows failed\n"))
14129 goto err;
14130 }
14131
14132 return 0;
14133err:
14134 return 1;
14135}
14136#endif
14137
14138
14139#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
14140uint8 Delete_rows_log_event::get_trg_event_map()
14141{
14142 return static_cast<uint8> (1 << static_cast<int>(TRG_EVENT_DELETE));
14143}
14144#endif
14145
14146/**************************************************************************
14147 Update_rows_log_event member functions
14148**************************************************************************/
14149
14150/*
14151 Constructor used to build an event for writing to the binary log.
14152 */
14153#if !defined(MYSQL_CLIENT)
14154Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
14155 ulong tid,
14156 bool is_transactional)
14157: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
14158 UPDATE_ROWS_EVENT_V1)
14159{
14160 init(tbl_arg->rpl_write_set);
14161}
14162
14163Update_rows_compressed_log_event::Update_rows_compressed_log_event(THD *thd_arg, TABLE *tbl_arg,
14164 ulong tid,
14165 bool is_transactional)
14166: Update_rows_log_event(thd_arg, tbl_arg, tid, is_transactional)
14167{
14168 m_type = UPDATE_ROWS_COMPRESSED_EVENT_V1;
14169}
14170
14171bool Update_rows_compressed_log_event::write()
14172{
14173 return Rows_log_event::write_compressed();
14174}
14175
14176void Update_rows_log_event::init(MY_BITMAP const *cols)
14177{
14178 /* if my_bitmap_init fails, caught in is_valid() */
14179 if (likely(!my_bitmap_init(&m_cols_ai,
14180 m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
14181 m_width,
14182 false)))
14183 {
14184 /* Cols can be zero if this is a dummy binrows event */
14185 if (likely(cols != NULL))
14186 {
14187 memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
14188 create_last_word_mask(&m_cols_ai);
14189 }
14190 }
14191}
14192#endif /* !defined(MYSQL_CLIENT) */
14193
14194
14195Update_rows_log_event::~Update_rows_log_event()
14196{
14197 if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
14198 m_cols_ai.bitmap= 0; // so no my_free in my_bitmap_free
14199 my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init().
14200}
14201
14202
14203/*
14204 Constructor used by slave to read the event from the binary log.
14205 */
14206#ifdef HAVE_REPLICATION
14207Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
14208 const
14209 Format_description_log_event
14210 *description_event)
14211 : Rows_log_event(buf, event_len, description_event)
14212{
14213}
14214
14215Update_rows_compressed_log_event::Update_rows_compressed_log_event(
14216 const char *buf, uint event_len,
14217 const Format_description_log_event
14218 *description_event)
14219 : Update_rows_log_event(buf, event_len, description_event)
14220{
14221 uncompress_buf();
14222}
14223#endif
14224
14225#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
14226
14227int
14228Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
14229{
14230 /*
14231 Increment the global status update count variable
14232 */
14233 if (get_flags(STMT_END_F))
14234 status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
14235
14236 int err;
14237 if ((err= find_key()))
14238 return err;
14239
14240 if (slave_run_triggers_for_rbr && !master_had_triggers)
14241 m_table->prepare_triggers_for_update_stmt_or_event();
14242
14243 return 0;
14244}
14245
14246int
14247Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
14248 int error)
14249{
14250 /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
14251 m_table->file->ha_index_or_rnd_end();
14252 my_free(m_key); // Free for multi_malloc
14253 m_key= NULL;
14254 m_key_info= NULL;
14255
14256 return error;
14257}
14258
14259int
14260Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
14261{
14262 const bool invoke_triggers=
14263 slave_run_triggers_for_rbr && !master_had_triggers && m_table->triggers;
14264 const char *tmp= thd->get_proc_info();
14265 const char *message= "Update_rows_log_event::find_row()";
14266 DBUG_ASSERT(m_table != NULL);
14267
14268#ifdef WSREP_PROC_INFO
14269 my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
14270 "Update_rows_log_event::find_row(%lld)",
14271 (long long) wsrep_thd_trx_seqno(thd));
14272 message= thd->wsrep_info;
14273#endif /* WSREP_PROC_INFO */
14274
14275 thd_proc_info(thd, message);
14276 int error= find_row(rgi);
14277 if (unlikely(error))
14278 {
14279 /*
14280 We need to read the second image in the event of error to be
14281 able to skip to the next pair of updates
14282 */
14283 if ((m_curr_row= m_curr_row_end))
14284 unpack_current_row(rgi, &m_cols_ai);
14285 thd_proc_info(thd, tmp);
14286 return error;
14287 }
14288
14289 /*
14290 This is the situation after locating BI:
14291
14292 ===|=== before image ====|=== after image ===|===
14293 ^ ^
14294 m_curr_row m_curr_row_end
14295
14296 BI found in the table is stored in record[0]. We copy it to record[1]
14297 and unpack AI to record[0].
14298 */
14299
14300 store_record(m_table,record[1]);
14301
14302 m_curr_row= m_curr_row_end;
14303 message= "Update_rows_log_event::unpack_current_row()";
14304#ifdef WSREP_PROC_INFO
14305 my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
14306 "Update_rows_log_event::unpack_current_row(%lld)",
14307 (long long) wsrep_thd_trx_seqno(thd));
14308 message= thd->wsrep_info;
14309#endif /* WSREP_PROC_INFO */
14310
14311 /* this also updates m_curr_row_end */
14312 thd_proc_info(thd, message);
14313 if (unlikely((error= unpack_current_row(rgi, &m_cols_ai))))
14314 goto err;
14315
14316 /*
14317 Now we have the right row to update. The old row (the one we're
14318 looking for) is in record[1] and the new row is in record[0].
14319 */
14320#ifndef HAVE_valgrind
14321 /*
14322 Don't print debug messages when running valgrind since they can
14323 trigger false warnings.
14324 */
14325 DBUG_PRINT("info",("Updating row in table"));
14326 DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
14327 DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
14328#endif
14329
14330 message= "Update_rows_log_event::ha_update_row()";
14331#ifdef WSREP_PROC_INFO
14332 my_snprintf(thd->wsrep_info, sizeof(thd->wsrep_info) - 1,
14333 "Update_rows_log_event::ha_update_row(%lld)",
14334 (long long) wsrep_thd_trx_seqno(thd));
14335 message= thd->wsrep_info;
14336#endif /* WSREP_PROC_INFO */
14337
14338 thd_proc_info(thd, message);
14339 if (invoke_triggers &&
14340 unlikely(process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, TRUE)))
14341 {
14342 error= HA_ERR_GENERIC; // in case if error is not set yet
14343 goto err;
14344 }
14345
14346 // Temporary fix to find out why it fails [/Matz]
14347 memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
14348 memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
14349
14350 m_table->mark_columns_per_binlog_row_image();
14351 if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
14352 m_table->vers_update_fields();
14353 error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
14354 if (unlikely(error == HA_ERR_RECORD_IS_THE_SAME))
14355 error= 0;
14356 if (m_vers_from_plain && m_table->versioned(VERS_TIMESTAMP))
14357 {
14358 store_record(m_table, record[2]);
14359 error= vers_insert_history_row(m_table);
14360 restore_record(m_table, record[2]);
14361 }
14362 m_table->default_column_bitmaps();
14363
14364 if (invoke_triggers && likely(!error) &&
14365 unlikely(process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE)))
14366 error= HA_ERR_GENERIC; // in case if error is not set yet
14367
14368 thd_proc_info(thd, tmp);
14369
14370err:
14371 m_table->file->ha_index_or_rnd_end();
14372 return error;
14373}
14374
14375#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
14376
14377#ifdef MYSQL_CLIENT
14378bool Update_rows_log_event::print(FILE *file,
14379 PRINT_EVENT_INFO* print_event_info)
14380{
14381 return Rows_log_event::print_helper(file, print_event_info, "Update_rows");
14382}
14383
14384bool
14385Update_rows_compressed_log_event::print(FILE *file,
14386 PRINT_EVENT_INFO *print_event_info)
14387{
14388 char *new_buf;
14389 ulong len;
14390 bool is_malloc= false;
14391 if(!row_log_event_uncompress(glob_description_event,
14392 checksum_alg == BINLOG_CHECKSUM_ALG_CRC32,
14393 temp_buf, UINT_MAX32, NULL, 0, &is_malloc, &new_buf, &len))
14394 {
14395 free_temp_buf();
14396 register_temp_buf(new_buf, true);
14397 if (Rows_log_event::print_helper(file, print_event_info,
14398 "Update_compressed_rows"))
14399 goto err;
14400 }
14401 else
14402 {
14403 if (my_b_printf(&print_event_info->head_cache,
14404 "ERROR: uncompress update_compressed_rows failed\n"))
14405 goto err;
14406 }
14407
14408 return 0;
14409err:
14410 return 1;
14411}
14412#endif
14413
14414#if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
14415uint8 Update_rows_log_event::get_trg_event_map()
14416{
14417 return static_cast<uint8> (1 << static_cast<int>(TRG_EVENT_UPDATE));
14418}
14419#endif
14420
14421Incident_log_event::Incident_log_event(const char *buf, uint event_len,
14422 const Format_description_log_event *descr_event)
14423 : Log_event(buf, descr_event)
14424{
14425 DBUG_ENTER("Incident_log_event::Incident_log_event");
14426 uint8 const common_header_len=
14427 descr_event->common_header_len;
14428 uint8 const post_header_len=
14429 descr_event->post_header_len[INCIDENT_EVENT-1];
14430
14431 DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
14432 event_len, common_header_len, post_header_len));
14433
14434 m_message.str= NULL;
14435 m_message.length= 0;
14436 int incident_number= uint2korr(buf + common_header_len);
14437 if (incident_number >= INCIDENT_COUNT ||
14438 incident_number <= INCIDENT_NONE)
14439 {
14440 // If the incident is not recognized, this binlog event is
14441 // invalid. If we set incident_number to INCIDENT_NONE, the
14442 // invalidity will be detected by is_valid().
14443 m_incident= INCIDENT_NONE;
14444 DBUG_VOID_RETURN;
14445 }
14446 m_incident= static_cast<Incident>(incident_number);
14447 char const *ptr= buf + common_header_len + post_header_len;
14448 char const *const str_end= buf + event_len;
14449 uint8 len= 0; // Assignment to keep compiler happy
14450 const char *str= NULL; // Assignment to keep compiler happy
14451 if (read_str(&ptr, str_end, &str, &len))
14452 {
14453 /* Mark this event invalid */
14454 m_incident= INCIDENT_NONE;
14455 DBUG_VOID_RETURN;
14456 }
14457 if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
14458 {
14459 /* Mark this event invalid */
14460 m_incident= INCIDENT_NONE;
14461 DBUG_VOID_RETURN;
14462 }
14463 strmake(m_message.str, str, len);
14464 m_message.length= len;
14465 DBUG_PRINT("info", ("m_incident: %d", m_incident));
14466 DBUG_VOID_RETURN;
14467}
14468
14469
14470Incident_log_event::~Incident_log_event()
14471{
14472 if (m_message.str)
14473 my_free(m_message.str);
14474}
14475
14476
14477const char *
14478Incident_log_event::description() const
14479{
14480 static const char *const description[]= {
14481 "NOTHING", // Not used
14482 "LOST_EVENTS"
14483 };
14484
14485 DBUG_PRINT("info", ("m_incident: %d", m_incident));
14486 return description[m_incident];
14487}
14488
14489
14490#ifndef MYSQL_CLIENT
14491void Incident_log_event::pack_info(Protocol *protocol)
14492{
14493 char buf[256];
14494 size_t bytes;
14495 if (m_message.length > 0)
14496 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
14497 m_incident, description());
14498 else
14499 bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
14500 m_incident, description(), m_message.str);
14501 protocol->store(buf, bytes, &my_charset_bin);
14502}
14503#endif /* MYSQL_CLIENT */
14504
14505
14506#if defined(WITH_WSREP) && !defined(MYSQL_CLIENT)
14507/*
14508 read the first event from (*buf). The size of the (*buf) is (*buf_len).
14509 At the end (*buf) is shitfed to point to the following event or NULL and
14510 (*buf_len) will be changed to account just being read bytes of the 1st event.
14511*/
14512#define WSREP_MAX_ALLOWED_PACKET 1024*1024*1024 // current protocol max
14513
14514Log_event* wsrep_read_log_event(
14515 char **arg_buf, size_t *arg_buf_len,
14516 const Format_description_log_event *description_event)
14517{
14518 char *head= (*arg_buf);
14519 uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
14520 char *buf= (*arg_buf);
14521 const char *error= 0;
14522 Log_event *res= 0;
14523 DBUG_ENTER("wsrep_read_log_event");
14524
14525 if (data_len > WSREP_MAX_ALLOWED_PACKET)
14526 {
14527 error = "Event too big";
14528 goto err;
14529 }
14530
14531 res= Log_event::read_log_event(buf, data_len, &error, description_event, false);
14532
14533err:
14534 if (!res)
14535 {
14536 DBUG_ASSERT(error != 0);
14537 sql_print_error("Error in Log_event::read_log_event(): "
14538 "'%s', data_len: %d, event_type: %d",
14539 error,data_len,(uchar)head[EVENT_TYPE_OFFSET]);
14540 }
14541 (*arg_buf)+= data_len;
14542 (*arg_buf_len)-= data_len;
14543 DBUG_RETURN(res);
14544}
14545#endif
14546
14547
14548#ifdef MYSQL_CLIENT
14549bool Incident_log_event::print(FILE *file,
14550 PRINT_EVENT_INFO *print_event_info)
14551{
14552 if (print_event_info->short_form)
14553 return 0;
14554
14555 Write_on_release_cache cache(&print_event_info->head_cache, file);
14556
14557 if (print_header(&cache, print_event_info, FALSE) ||
14558 my_b_printf(&cache, "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n", description()))
14559 return 1;
14560 return cache.flush_data();
14561}
14562#endif
14563
14564#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
14565int
14566Incident_log_event::do_apply_event(rpl_group_info *rgi)
14567{
14568 Relay_log_info const *rli= rgi->rli;
14569 DBUG_ENTER("Incident_log_event::do_apply_event");
14570
14571 if (ignored_error_code(ER_SLAVE_INCIDENT))
14572 {
14573 DBUG_PRINT("info", ("Ignoring Incident"));
14574 DBUG_RETURN(0);
14575 }
14576
14577 rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT, NULL,
14578 ER_THD(rgi->thd, ER_SLAVE_INCIDENT),
14579 description(),
14580 m_message.length > 0 ? m_message.str : "<none>");
14581 DBUG_RETURN(1);
14582}
14583#endif
14584
14585#ifdef MYSQL_SERVER
14586bool
14587Incident_log_event::write_data_header()
14588{
14589 DBUG_ENTER("Incident_log_event::write_data_header");
14590 DBUG_PRINT("enter", ("m_incident: %d", m_incident));
14591 uchar buf[sizeof(int16)];
14592 int2store(buf, (int16) m_incident);
14593 DBUG_RETURN(write_data(buf, sizeof(buf)));
14594}
14595
14596bool
14597Incident_log_event::write_data_body()
14598{
14599 uchar tmp[1];
14600 DBUG_ENTER("Incident_log_event::write_data_body");
14601 tmp[0]= (uchar) m_message.length;
14602 DBUG_RETURN(write_data(tmp, sizeof(tmp)) ||
14603 write_data(m_message.str, m_message.length));
14604}
14605#endif
14606
14607Ignorable_log_event::Ignorable_log_event(const char *buf,
14608 const Format_description_log_event
14609 *descr_event,
14610 const char *event_name)
14611 :Log_event(buf, descr_event), number((int) (uchar) buf[EVENT_TYPE_OFFSET]),
14612 description(event_name)
14613{
14614 DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
14615 DBUG_VOID_RETURN;
14616}
14617
14618Ignorable_log_event::~Ignorable_log_event()
14619{
14620}
14621
14622#ifndef MYSQL_CLIENT
14623/* Pack info for its unrecognized ignorable event */
14624void Ignorable_log_event::pack_info(Protocol *protocol)
14625{
14626 char buf[256];
14627 size_t bytes;
14628 bytes= my_snprintf(buf, sizeof(buf), "# Ignorable event type %d (%s)",
14629 number, description);
14630 protocol->store(buf, bytes, &my_charset_bin);
14631}
14632#endif
14633
14634#ifdef MYSQL_CLIENT
14635/* Print for its unrecognized ignorable event */
14636bool Ignorable_log_event::print(FILE *file,
14637 PRINT_EVENT_INFO *print_event_info)
14638{
14639 if (print_event_info->short_form)
14640 return 0;
14641
14642 if (print_header(&print_event_info->head_cache, print_event_info, FALSE) ||
14643 my_b_printf(&print_event_info->head_cache, "\tIgnorable\n") ||
14644 my_b_printf(&print_event_info->head_cache,
14645 "# Ignorable event type %d (%s)\n", number, description) ||
14646 copy_event_cache_to_file_and_reinit(&print_event_info->head_cache,
14647 file))
14648 return 1;
14649 return 0;
14650}
14651#endif
14652
14653
14654#ifdef MYSQL_CLIENT
14655/**
14656 The default values for these variables should be values that are
14657 *incorrect*, i.e., values that cannot occur in an event. This way,
14658 they will always be printed for the first event.
14659*/
14660st_print_event_info::st_print_event_info()
14661{
14662 myf const flags = MYF(MY_WME | MY_NABP);
14663 /*
14664 Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
14665 program's startup, but these explicit bzero() is for the day someone
14666 creates dynamic instances.
14667 */
14668 bzero(db, sizeof(db));
14669 bzero(charset, sizeof(charset));
14670 bzero(time_zone_str, sizeof(time_zone_str));
14671 delimiter[0]= ';';
14672 delimiter[1]= 0;
14673 flags2_inited= 0;
14674 sql_mode_inited= 0;
14675 row_events= 0;
14676 sql_mode= 0;
14677 auto_increment_increment= 0;
14678 auto_increment_offset= 0;
14679 charset_inited= 0;
14680 lc_time_names_number= ~0;
14681 charset_database_number= ILLEGAL_CHARSET_INFO_NUMBER;
14682 thread_id= 0;
14683 server_id= 0;
14684 domain_id= 0;
14685 thread_id_printed= false;
14686 server_id_printed= false;
14687 domain_id_printed= false;
14688 allow_parallel= true;
14689 allow_parallel_printed= false;
14690 found_row_event= false;
14691 print_row_count= false;
14692 short_form= false;
14693 skip_replication= 0;
14694 printed_fd_event=FALSE;
14695 file= 0;
14696 base64_output_mode=BASE64_OUTPUT_UNSPEC;
14697 open_cached_file(&head_cache, NULL, NULL, 0, flags);
14698 open_cached_file(&body_cache, NULL, NULL, 0, flags);
14699#ifdef WHEN_FLASHBACK_REVIEW_READY
14700 open_cached_file(&review_sql_cache, NULL, NULL, 0, flags);
14701#endif
14702}
14703
14704
14705bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to)
14706{
14707 reinit_io_cache(cache, READ_CACHE, 0L, FALSE, FALSE);
14708 if (cache->end_of_file > SIZE_T_MAX ||
14709 !(to->str= (char*) my_malloc((to->length= (size_t)cache->end_of_file), MYF(0))))
14710 {
14711 perror("Out of memory: can't allocate memory in copy_event_cache_to_string_and_reinit().");
14712 goto err;
14713 }
14714 if (my_b_read(cache, (uchar*) to->str, to->length))
14715 {
14716 my_free(to->str);
14717 perror("Can't read data from IO_CACHE");
14718 return true;
14719 }
14720 reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
14721 return false;
14722
14723err:
14724 to->str= 0;
14725 to->length= 0;
14726 return true;
14727}
14728#endif /* MYSQL_CLIENT */
14729
14730bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file)
14731{
14732 return (my_b_copy_to_file(cache, file) ||
14733 reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE));
14734}
14735
14736#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
14737Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
14738 const Format_description_log_event* description_event)
14739 :Log_event(buf, description_event)
14740{
14741 uint8 header_size= description_event->common_header_len;
14742 ident_len = event_len - header_size;
14743 set_if_smaller(ident_len,FN_REFLEN-1);
14744 log_ident= buf + header_size;
14745}
14746#endif
14747
14748#if defined(MYSQL_SERVER)
14749/**
14750 Check if we should write event to the relay log
14751
14752 This is used to skip events that is only supported by MySQL
14753
14754 Return:
14755 0 ok
14756 1 Don't write event
14757*/
14758
14759bool event_that_should_be_ignored(const char *buf)
14760{
14761 uint event_type= (uchar)buf[EVENT_TYPE_OFFSET];
14762 if (event_type == GTID_LOG_EVENT ||
14763 event_type == ANONYMOUS_GTID_LOG_EVENT ||
14764 event_type == PREVIOUS_GTIDS_LOG_EVENT ||
14765 event_type == TRANSACTION_CONTEXT_EVENT ||
14766 event_type == VIEW_CHANGE_EVENT ||
14767 event_type == XA_PREPARE_LOG_EVENT ||
14768 (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F))
14769 return 1;
14770 return 0;
14771}
14772#endif /* MYSQL_SERVER */
14773