1 /*
2    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
3    Copyright (c) 2018, Percona and/or its affiliates. All rights reserved.
4    Copyright (c) 2009, 2016, MariaDB
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License, version 2.0,
8    as published by the Free Software Foundation.
9 
10    This program is also distributed with certain software (including
11    but not limited to OpenSSL) that is licensed under separate terms,
12    as designated in a particular file or component or in included license
13    documentation.  The authors of MySQL hereby grant you an additional
14    permission to link the program and your derivative works with the
15    separately licensed software that they have included with MySQL.
16 
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License, version 2.0, for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
25 
26 #include "log_event.h"
27 
28 #include "base64.h"            // base64_encode
29 #include "binary_log_funcs.h"  // my_timestamp_binary_length
30 
31 #ifndef MYSQL_CLIENT
32 #include "debug_sync.h"        // debug_sync_set_action
33 #include "my_dir.h"            // my_dir
34 #include "log.h"               // Log_throttle
35 #include "rpl_mts_submode.h"   // Mts_submode
36 #include "rpl_rli.h"           // Relay_log_info
37 #include "rpl_rli_pdb.h"       // Slave_job_group
38 #include "rpl_slave.h"         // use_slave_mask
39 #include "sql_base.h"          // close_thread_tables
40 #include "sql_cache.h"         // QUERY_CACHE_FLAGS_SIZE
41 #include "sql_db.h"            // load_db_opt_by_name
42 #include "sql_load.h"          // mysql_load
43 #include "sql_locale.h"        // my_locale_by_number
44 #include "sql_parse.h"         // mysql_test_parse_for_slave
45 #include "sql_show.h"          // append_identifier
46 #include "transaction.h"       // trans_rollback_stmt
47 #include "tztime.h"            // Time_zone
48 #include "rpl_msr.h"           // channel_map
49 #include "binary_log.h"        // binary_log
50 #include "rpl_thd_raii.h"      // Disable_index_extensions_switch_guard
51 
52 #include "pfs_file_provider.h"
53 #include "mysql/psi/mysql_file.h"
54 
55 #include <mysql/psi/mysql_statement.h>
56 #include "transaction_info.h"
57 #include "sql_class.h"
58 #include "mysql/psi/mysql_transaction.h"
59 #include "sql_plugin.h" // plugin_foreach
60 #define window_size Log_throttle::LOG_THROTTLE_WINDOW_SIZE
61 Error_log_throttle
62 slave_ignored_err_throttle(window_size,
63                            sql_print_information,
64                            "Error log throttle: %lu time(s) Error_code: 1237"
65                            " \"Slave SQL thread ignored the query because of"
66                            " replicate-*-table rules\" got suppressed.");
67 #endif /* MYSQL_CLIENT */
68 
69 #include <base64.h>
70 #include <my_bitmap.h>
71 #include <map>
72 #include "rpl_utility.h"
73 /* This is necessary for the List manipuation */
74 #include "sql_list.h"                           /* I_List */
75 #include "hash.h"
76 #include "sql_digest.h"
77 #include "rpl_gtid.h"
78 #include "xa_aux.h"
79 
80 PSI_memory_key key_memory_log_event;
81 PSI_memory_key key_memory_Incident_log_event_message;
82 PSI_memory_key key_memory_Rows_query_log_event_rows_query;
83 
84 #ifndef EMBEDDED_LIBRARY
85 #include "sql_connect.h" //update_global_user_stats
86 #endif
87 
88 using std::min;
89 using std::max;
90 
91 /**
92   BINLOG_CHECKSUM variable.
93 */
94 const char *binlog_checksum_type_names[]= {
95   "NONE",
96   "CRC32",
97   NullS
98 };
99 
100 unsigned int binlog_checksum_type_length[]= {
101   sizeof("NONE") - 1,
102   sizeof("CRC32") - 1,
103   0
104 };
105 
106 TYPELIB binlog_checksum_typelib=
107 {
108   array_elements(binlog_checksum_type_names) - 1, "",
109   binlog_checksum_type_names,
110   binlog_checksum_type_length
111 };
112 
113 
114 #define log_cs	&my_charset_latin1
115 
116 /*
117   Size of buffer for printing a double in format %.<PREC>g
118 
119   optional '-' + optional zero + '.'  + PREC digits + 'e' + sign +
120   exponent digits + '\0'
121 */
122 #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
123 
124 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
125 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
126 
HA_ERR(int i)127 static const char *HA_ERR(int i)
128 {
129   /*
130     This function should only be called in case of an error
131     was detected
132    */
133   assert(i != 0);
134   switch (i) {
135   case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
136   case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
137   case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
138   case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
139   case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
140   case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
141   case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
142   case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
143   case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
144   case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
145   case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
146   case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
147   case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
148   case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
149   case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
150   case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
151   case HA_ERR_TOO_BIG_ROW: return "HA_ERR_TOO_BIG_ROW";
152   case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
153   case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
154   case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
155   case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
156   case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
157   case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
158   case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
159   case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
160   case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
161   case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
162   case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
163   case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
164   case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
165   case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
166   case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
167   case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
168   case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
169   case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
170   case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
171   case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
172   case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
173   case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
174   case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
175   case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
176   case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
177   case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
178   case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
179   case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
180   case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
181   case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
182   case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
183   case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
184   case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
185   case HA_ERR_FK_DEPTH_EXCEEDED : return "HA_ERR_FK_DEPTH_EXCEEDED";
186   case HA_ERR_INNODB_READ_ONLY: return "HA_ERR_INNODB_READ_ONLY";
187   case HA_ERR_COMPUTE_FAILED: return "HA_ERR_COMPUTE_FAILED";
188   case HA_ERR_FTS_TOO_MANY_NESTED_EXP: return "HA_ERR_FTS_TOO_MANY_NESTED_EXP";
189   }
190   return "No Error!";
191 }
192 
193 /**
194    Error reporting facility for Rows_log_event::do_apply_event
195 
196    @param level     error, warning or info
197    @param ha_error  HA_ERR_ code
198    @param rli       pointer to the active Relay_log_info instance
199    @param thd       pointer to the slave thread's thd
200    @param table     pointer to the event's table object
201    @param type      the type of the event
202    @param log_name  the master binlog file name
203    @param pos       the master binlog file pos (the next after the event)
204 
205 */
slave_rows_error_report(enum loglevel level,int ha_error,Relay_log_info const * rli,THD * thd,TABLE * table,const char * type,const char * log_name,ulong pos)206 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
207                                            Relay_log_info const *rli, THD *thd,
208                                            TABLE *table, const char * type,
209                                            const char *log_name, ulong pos)
210 {
211   const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
212   bool is_group_replication_applier_channel=
213     channel_map.is_group_replication_channel_name((const_cast<Relay_log_info *>(rli))->get_channel(), true);
214   char buff[MAX_SLAVE_ERRMSG], *slider;
215   const char *buff_end= buff + sizeof(buff);
216   size_t len;
217   Diagnostics_area::Sql_condition_iterator it=
218     thd->get_stmt_da()->sql_conditions();
219   const Sql_condition *err;
220   buff[0]= 0;
221 
222   for (err= it++, slider= buff; err && slider < buff_end - 1;
223        slider += len, err= it++)
224   {
225     len= my_snprintf(slider, buff_end - slider,
226                      " %s, Error_code: %d;", err->message_text(),
227                      err->mysql_errno());
228   }
229   if (is_group_replication_applier_channel)
230   {
231     if (ha_error != 0)
232     {
233       rli->report(level, thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
234                   ER_UNKNOWN_ERROR, "Could not execute %s event on table %s.%s;"
235                   "%s handler error %s",
236                   type, table->s->db.str, table->s->table_name.str,
237                   buff, handler_error == NULL ? "<unknown>" : handler_error);
238     }
239     else
240     {
241       rli->report(level, thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
242                   ER_UNKNOWN_ERROR, "Could not execute %s event on table %s.%s;"
243                   "%s", type, table->s->db.str, table->s->table_name.str,
244                   buff);
245     }
246   }
247   else
248   {
249     if (ha_error != 0)
250     {
251       rli->report(level, thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
252                   ER_UNKNOWN_ERROR, "Could not execute %s event on table %s.%s;"
253                   "%s handler error %s; "
254                   "the event's master log %s, end_log_pos %lu",
255                   type, table->s->db.str, table->s->table_name.str,
256                   buff, handler_error == NULL ? "<unknown>" : handler_error,
257                   log_name, pos);
258     }
259     else
260     {
261       rli->report(level, thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
262                   ER_UNKNOWN_ERROR, "Could not execute %s event on table %s.%s;"
263                   "%s the event's master log %s, end_log_pos %lu",
264                   type, table->s->db.str, table->s->table_name.str,
265                   buff, log_name, pos);
266     }
267   }
268 }
269 
set_thd_db(THD * thd,const char * db,size_t db_len)270 static void set_thd_db(THD *thd, const char *db, size_t db_len)
271 {
272   char lcase_db_buf[NAME_LEN +1];
273   LEX_CSTRING new_db;
274   new_db.length= db_len;
275   if (lower_case_table_names)
276   {
277     my_stpcpy(lcase_db_buf, db);
278     my_casedn_str(system_charset_info, lcase_db_buf);
279     new_db.str= lcase_db_buf;
280   }
281   else
282     new_db.str= (char*) db;
283 
284   new_db.str= (char*) rpl_filter->get_rewrite_db(new_db.str,
285                                                  &new_db.length);
286   thd->set_db(new_db);
287 }
288 
289 #endif
290 
291 
292 /*
293   pretty_print_str()
294 */
295 
296 #ifdef MYSQL_CLIENT
pretty_print_str(IO_CACHE * cache,const char * str,size_t len)297 static void pretty_print_str(IO_CACHE* cache, const char* str, size_t len)
298 {
299   const char* end = str + len;
300   my_b_printf(cache, "\'");
301   while (str < end)
302   {
303     char c;
304     switch ((c=*str++)) {
305     case '\n': my_b_printf(cache, "\\n"); break;
306     case '\r': my_b_printf(cache, "\\r"); break;
307     case '\\': my_b_printf(cache, "\\\\"); break;
308     case '\b': my_b_printf(cache, "\\b"); break;
309     case '\t': my_b_printf(cache, "\\t"); break;
310     case '\'': my_b_printf(cache, "\\'"); break;
311     case 0   : my_b_printf(cache, "\\0"); break;
312     default:
313       my_b_printf(cache, "%c", c);
314       break;
315     }
316   }
317   my_b_printf(cache, "\'");
318 }
319 #endif /* MYSQL_CLIENT */
320 
321 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
322 
clear_all_errors(THD * thd,Relay_log_info * rli)323 static void clear_all_errors(THD *thd, Relay_log_info *rli)
324 {
325   thd->is_slave_error = 0;
326   thd->clear_error();
327   rli->clear_error();
328   if (rli->workers_array_initialized)
329   {
330     for(size_t i= 0; i < rli->get_worker_count(); i++)
331     {
332       rli->get_worker(i)->clear_error();
333     }
334   }
335 }
336 
idempotent_error_code(int err_code)337 inline int idempotent_error_code(int err_code)
338 {
339   int ret= 0;
340 
341   switch (err_code)
342   {
343     case 0:
344       ret= 1;
345     break;
346     /*
347       The following list of "idempotent" errors
348       means that an error from the list might happen
349       because of idempotent (more than once)
350       applying of a binlog file.
351       Notice, that binlog has a  ddl operation its
352       second applying may cause
353 
354       case HA_ERR_TABLE_DEF_CHANGED:
355       case HA_ERR_CANNOT_ADD_FOREIGN:
356 
357       which are not included into to the list.
358 
359       Note that HA_ERR_RECORD_DELETED is not in the list since
360       do_exec_row() should not return that error code.
361     */
362     case HA_ERR_RECORD_CHANGED:
363     case HA_ERR_KEY_NOT_FOUND:
364     case HA_ERR_END_OF_FILE:
365     case HA_ERR_FOUND_DUPP_KEY:
366     case HA_ERR_FOUND_DUPP_UNIQUE:
367     case HA_ERR_FOREIGN_DUPLICATE_KEY:
368     case HA_ERR_NO_REFERENCED_ROW:
369     case HA_ERR_ROW_IS_REFERENCED:
370       ret= 1;
371     break;
372     default:
373       ret= 0;
374     break;
375   }
376   return (ret);
377 }
378 
379 /**
380   Ignore error code specified on command line.
381 */
382 
ignored_error_code(int err_code)383 int ignored_error_code(int err_code)
384 {
385   return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
386           (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
387 }
388 
389 /*
390   This function converts an engine's error to a server error.
391 
392   If the thread does not have an error already reported, it tries to
393   define it by calling the engine's method print_error. However, if a
394   mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
395   warning message.
396 */
convert_handler_error(int error,THD * thd,TABLE * table)397 int convert_handler_error(int error, THD* thd, TABLE *table)
398 {
399   uint actual_error= (thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
400                            0);
401 
402   if (actual_error == 0)
403   {
404     table->file->print_error(error, MYF(0));
405     actual_error= (thd->is_error() ? thd->get_stmt_da()->mysql_errno() :
406                         ER_UNKNOWN_ERROR);
407     if (actual_error == ER_UNKNOWN_ERROR)
408       sql_print_warning("Unknown error detected %d in handler", error);
409   }
410 
411   return (actual_error);
412 }
413 
concurrency_error_code(int error)414 inline bool concurrency_error_code(int error)
415 {
416   switch (error)
417   {
418   case ER_LOCK_WAIT_TIMEOUT:
419   case ER_LOCK_DEADLOCK:
420   case ER_XA_RBDEADLOCK:
421     return TRUE;
422   default:
423     return (FALSE);
424   }
425 }
426 
unexpected_error_code(int unexpected_error)427 inline bool unexpected_error_code(int unexpected_error)
428 {
429   switch (unexpected_error)
430   {
431   case ER_NET_READ_ERROR:
432   case ER_NET_ERROR_ON_WRITE:
433   case ER_QUERY_INTERRUPTED:
434   case ER_SERVER_SHUTDOWN:
435   case ER_NEW_ABORTING_CONNECTION:
436     return(TRUE);
437   default:
438     return(FALSE);
439   }
440 }
441 
442 /*
443   pretty_print_str()
444 */
445 
pretty_print_str(char * packet,const char * str,size_t len)446 static char *pretty_print_str(char *packet, const char *str, size_t len)
447 {
448   const char *end= str + len;
449   char *pos= packet;
450   *pos++= '\'';
451   while (str < end)
452   {
453     char c;
454     switch ((c=*str++)) {
455     case '\n': *pos++= '\\'; *pos++= 'n'; break;
456     case '\r': *pos++= '\\'; *pos++= 'r'; break;
457     case '\\': *pos++= '\\'; *pos++= '\\'; break;
458     case '\b': *pos++= '\\'; *pos++= 'b'; break;
459     case '\t': *pos++= '\\'; *pos++= 't'; break;
460     case '\'': *pos++= '\\'; *pos++= '\''; break;
461     case 0   : *pos++= '\\'; *pos++= '0'; break;
462     default:
463       *pos++= c;
464       break;
465     }
466   }
467   *pos++= '\'';
468   return pos;
469 }
470 #endif /* !MYSQL_CLIENT */
471 
472 
473 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
474 
475 /**
476   Creates a temporary name for load data infile:.
477 
478   @param buf		      Store new filename here
479   @param file_id	      File_id (part of file name)
480   @param event_server_id     Event_id (part of file name)
481   @param ext		      Extension for file name
482 
483   @return
484     Pointer to start of extension
485 */
486 
slave_load_file_stem(char * buf,uint file_id,int event_server_id,const char * ext)487 static char *slave_load_file_stem(char *buf, uint file_id,
488                                   int event_server_id, const char *ext)
489 {
490   char *res;
491   fn_format(buf,PREFIX_SQL_LOAD,slave_load_tmpdir, "", MY_UNPACK_FILENAME);
492   to_unix_path(buf);
493 
494   buf= strend(buf);
495   int appended_length= sprintf(buf, "%s-%d-", server_uuid, event_server_id);
496   buf+= appended_length;
497   res= int10_to_str(file_id, buf, 10);
498   my_stpcpy(res, ext);                             // Add extension last
499   return res;                                   // Pointer to extension
500 }
501 #endif
502 
503 
504 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
505 
506 /**
507   Delete all temporary files used for SQL_LOAD.
508 */
509 
cleanup_load_tmpdir()510 static void cleanup_load_tmpdir()
511 {
512   MY_DIR *dirp;
513   FILEINFO *file;
514   uint i;
515   char fname[FN_REFLEN], prefbuf[TEMP_FILE_MAX_LEN], *p;
516 
517   if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
518     return;
519 
520   /*
521      When we are deleting temporary files, we should only remove
522      the files associated with the server id of our server.
523      We don't use event_server_id here because since we've disabled
524      direct binlogging of Create_file/Append_file/Exec_load events
525      we cannot meet Start_log event in the middle of events from one
526      LOAD DATA.
527   */
528   p= strmake(prefbuf, STRING_WITH_LEN(PREFIX_SQL_LOAD));
529   sprintf(p,"%s-",server_uuid);
530 
531   for (i=0 ; i < dirp->number_off_files; i++)
532   {
533     file=dirp->dir_entry+i;
534     if (is_prefix(file->name, prefbuf))
535     {
536       fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
537       mysql_file_delete(key_file_misc, fname, MYF(0));
538     }
539   }
540 
541   my_dirend(dirp);
542 }
543 #endif
544 
545 
546 /*
547   Stores string to IO_CACHE file.
548 
549   Writes str to file in the following format:
550    1. Stores length using only one byte (255 maximum value);
551    2. Stores complete str.
552 */
553 
write_str_at_most_255_bytes(IO_CACHE * file,const char * str,uint length,Event_encrypter * event_encrypter)554 static bool write_str_at_most_255_bytes(IO_CACHE *file, const char *str, uint length,
555                                         Event_encrypter *event_encrypter)
556 {
557   uchar tmp[1];
558   tmp[0]= (uchar) length;
559   return (event_encrypter->encrypt_and_write(file, tmp, sizeof(tmp)) ||
560 	  event_encrypter->encrypt_and_write(file, (uchar*) str, length));
561 }
562 
563 /**
564   Transforms a string into "" or its expression in 0x... form.
565 */
566 
str_to_hex(char * to,const char * from,size_t len)567 char *str_to_hex(char *to, const char *from, size_t len)
568 {
569   if (len)
570   {
571     *to++= '0';
572     *to++= 'x';
573     to= octet2hex(to, from, len);
574   }
575   else
576     to= my_stpcpy(to, "\"\"");
577   return to;                               // pointer to end 0 of 'to'
578 }
579 
580 #ifndef MYSQL_CLIENT
581 
582 /**
583   Append a version of the 'from' string suitable for use in a query to
584   the 'to' string.  To generate a correct escaping, the character set
585   information in 'csinfo' is used.
586 */
587 
588 int
append_query_string(THD * thd,const CHARSET_INFO * csinfo,String const * from,String * to)589 append_query_string(THD *thd, const CHARSET_INFO *csinfo,
590                     String const *from, String *to)
591 {
592   char *beg, *ptr;
593   size_t const orig_len= to->length();
594   if (to->reserve(orig_len + from->length()*2+3))
595     return 1;
596 
597   beg= to->c_ptr_quick() + to->length();
598   ptr= beg;
599   if (csinfo->escape_with_backslash_is_dangerous)
600     ptr= str_to_hex(ptr, from->ptr(), from->length());
601   else
602   {
603     *ptr++= '\'';
604     if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
605     {
606       ptr+= escape_string_for_mysql(csinfo, ptr, 0,
607                                     from->ptr(), from->length());
608     }
609     else
610     {
611       const char *frm_str= from->ptr();
612 
613       for (; frm_str < (from->ptr() + from->length()); frm_str++)
614       {
615         /* Using '' way to represent "'" */
616         if (*frm_str == '\'')
617           *ptr++= *frm_str;
618 
619         *ptr++= *frm_str;
620       }
621     }
622 
623     *ptr++= '\'';
624   }
625   to->length(orig_len + ptr - beg);
626   return 0;
627 }
628 #endif
629 
630 
631 /**
632   Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
633   commands just before it prints a query.
634 */
635 
636 #ifdef MYSQL_CLIENT
637 
print_set_option(IO_CACHE * file,uint32 bits_changed,uint32 option,uint32 flags,const char * name,bool * need_comma)638 static void print_set_option(IO_CACHE* file, uint32 bits_changed,
639                              uint32 option, uint32 flags, const char* name,
640                              bool* need_comma)
641 {
642   if (bits_changed & option)
643   {
644     if (*need_comma)
645       my_b_printf(file,", ");
646     my_b_printf(file,"%s=%d", name, MY_TEST(flags & option));
647     *need_comma= 1;
648   }
649 }
650 #endif
651 /**************************************************************************
652 	Log_event methods (= the parent class of all events)
653 **************************************************************************/
654 
655 /**
656   @return
657   returns the human readable name of the event's type
658 */
659 
get_type_str(Log_event_type type)660 const char* Log_event::get_type_str(Log_event_type type)
661 {
662   switch(type) {
663   case binary_log::START_EVENT_V3:  return "Start_v3";
664   case binary_log::STOP_EVENT:   return "Stop";
665   case binary_log::QUERY_EVENT:  return "Query";
666   case binary_log::ROTATE_EVENT: return "Rotate";
667   case binary_log::INTVAR_EVENT: return "Intvar";
668   case binary_log::LOAD_EVENT:   return "Load";
669   case binary_log::NEW_LOAD_EVENT:   return "New_load";
670   case binary_log::CREATE_FILE_EVENT: return "Create_file";
671   case binary_log::APPEND_BLOCK_EVENT: return "Append_block";
672   case binary_log::DELETE_FILE_EVENT: return "Delete_file";
673   case binary_log::EXEC_LOAD_EVENT: return "Exec_load";
674   case binary_log::RAND_EVENT: return "RAND";
675   case binary_log::XID_EVENT: return "Xid";
676   case binary_log::USER_VAR_EVENT: return "User var";
677   case binary_log::FORMAT_DESCRIPTION_EVENT: return "Format_desc";
678   case binary_log::TABLE_MAP_EVENT: return "Table_map";
679   case binary_log::PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
680   case binary_log::PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
681   case binary_log::PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
682   case binary_log::WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
683   case binary_log::UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
684   case binary_log::DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
685   case binary_log::BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
686   case binary_log::EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
687   case binary_log::INCIDENT_EVENT: return "Incident";
688   case binary_log::IGNORABLE_LOG_EVENT: return "Ignorable";
689   case binary_log::ROWS_QUERY_LOG_EVENT: return "Rows_query";
690   case binary_log::WRITE_ROWS_EVENT: return "Write_rows";
691   case binary_log::UPDATE_ROWS_EVENT: return "Update_rows";
692   case binary_log::DELETE_ROWS_EVENT: return "Delete_rows";
693   case binary_log::GTID_LOG_EVENT: return "Gtid";
694   case binary_log::ANONYMOUS_GTID_LOG_EVENT: return "Anonymous_Gtid";
695   case binary_log::PREVIOUS_GTIDS_LOG_EVENT: return "Previous_gtids";
696   case binary_log::HEARTBEAT_LOG_EVENT: return "Heartbeat";
697   case binary_log::TRANSACTION_CONTEXT_EVENT: return "Transaction_context";
698   case binary_log::VIEW_CHANGE_EVENT: return "View_change";
699   case binary_log::XA_PREPARE_LOG_EVENT: return "XA_prepare";
700   case binary_log::START_ENCRYPTION_EVENT: return "Start_encryption";
701   default: return "Unknown";                            /* impossible */
702   }
703 }
704 
get_type_str()705 const char* Log_event::get_type_str()
706 {
707   return get_type_str(get_type_code());
708 }
709 
710 
711 /*
712   Log_event::Log_event()
713 */
714 
715 #ifndef MYSQL_CLIENT
Log_event(THD * thd_arg,uint16 flags_arg,enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg,Log_event_header * header,Log_event_footer * footer)716 Log_event::Log_event(THD* thd_arg, uint16 flags_arg,
717                      enum_event_cache_type cache_type_arg,
718                      enum_event_logging_type logging_type_arg,
719                      Log_event_header *header, Log_event_footer *footer)
720   : is_valid_param(false), temp_buf(0), exec_time(0),
721     event_cache_type(cache_type_arg), event_logging_type(logging_type_arg),
722     crc(0), common_header(header), common_footer(footer), thd(thd_arg)
723 {
724   server_id= thd->server_id;
725   common_header->unmasked_server_id= server_id;
726   common_header->when= thd->start_time;
727   common_header->log_pos= 0;
728   common_header->flags= flags_arg;
729 }
730 
731 /**
732   This minimal constructor is for when you are not even sure that there
733   is a valid THD. For example in the server when we are shutting down or
734   flushing logs after receiving a SIGHUP (then we must write a Rotate to
735   the binlog but we have no THD, so we need this minimal constructor).
736 */
737 
Log_event(Log_event_header * header,Log_event_footer * footer,enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg)738 Log_event::Log_event(Log_event_header* header, Log_event_footer *footer,
739                      enum_event_cache_type cache_type_arg,
740                      enum_event_logging_type logging_type_arg)
741   : is_valid_param(false), temp_buf(0), exec_time(0), event_cache_type(cache_type_arg),
742    event_logging_type(logging_type_arg), crc(0), common_header(header),
743    common_footer(footer), thd(0)
744 {
745   server_id=	::server_id;
746   common_header->unmasked_server_id= server_id;
747 }
748 #endif /* !MYSQL_CLIENT */
749 
750 
751 /*
752   Log_event::Log_event()
753 */
754 
Log_event(Log_event_header * header,Log_event_footer * footer)755 Log_event::Log_event(Log_event_header *header,
756                      Log_event_footer *footer)
757   : is_valid_param(false), temp_buf(0), exec_time(0),
758     event_cache_type(EVENT_INVALID_CACHE),
759     event_logging_type(EVENT_INVALID_LOGGING),
760     crc(0), common_header(header), common_footer(footer)
761 {
762 #ifndef MYSQL_CLIENT
763   thd= 0;
764 #endif
765   /*
766      Mask out any irrelevant parts of the server_id
767   */
768 #ifdef HAVE_REPLICATION
769   server_id = common_header->unmasked_server_id & opt_server_id_mask;
770 #else
771   server_id = common_header->unmasked_server_id;
772 #endif
773 }
774 
775 /*
776   This method is not on header file to avoid using key_memory_log_event
777   outside log_event.cc, allowing header file to be included on plugins.
778 */
operator new(size_t size)779 void* Log_event::operator new(size_t size)
780 {
781   return my_malloc(key_memory_log_event, size, MYF(MY_WME|MY_FAE));
782 }
783 
784 #ifndef MYSQL_CLIENT
785 #ifdef HAVE_REPLICATION
do_apply_event_worker(Slave_worker * w)786 inline int Log_event::do_apply_event_worker(Slave_worker *w)
787 {
788   DBUG_EXECUTE_IF("crash_in_a_worker",
789                   {
790                     /* we will crash a worker after waiting for
791                     2 seconds to make sure that other transactions are
792                     scheduled and completed */
793                     if (w->id == 2)
794                     {
795                       DBUG_SET("-d,crash_in_a_worker");
796                       my_sleep(2000000);
797                       DBUG_SUICIDE();
798                     }
799                   });
800   return do_apply_event(w);
801 }
802 
do_update_pos(Relay_log_info * rli)803 int Log_event::do_update_pos(Relay_log_info *rli)
804 {
805   int error= 0;
806   assert(!rli->belongs_to_client());
807   /*
808     rli is null when (as far as I (Guilhem) know) the caller is
809     Load_log_event::do_apply_event *and* that one is called from
810     Execute_load_log_event::do_apply_event.  In this case, we don't
811     do anything here ; Execute_load_log_event::do_apply_event will
812     call Log_event::do_apply_event again later with the proper rli.
813     Strictly speaking, if we were sure that rli is null only in the
814     case discussed above, 'if (rli)' is useless here.  But as we are
815     not 100% sure, keep it for now.
816 
817     Matz: I don't think we will need this check with this refactoring.
818   */
819 
820   assert(!is_mts_worker(rli->info_thd));
821 
822   if (rli)
823     error= rli->stmt_done(common_header->log_pos);
824   return error;
825 }
826 
827 
828 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)829 Log_event::do_shall_skip(Relay_log_info *rli)
830 {
831   /*
832     The logic for slave_skip_counter is as follows:
833 
834     - Events that are skipped because they have the same server_id as
835       the slave do not decrease slave_skip_counter.
836 
837     - Other events (that pass the server_id test) will decrease
838       slave_skip_counter.
839 
840     - Except in one case: if slave_skip_counter==1, it will only
841       decrease to 0 if we are at a so-called group boundary. Here, a
842       group is defined as the range of events that represent a single
843       transaction in the relay log: see comment for is_in_group in
844       rpl_rli.h for a definition.
845 
846     The difficult part to implement is the logic to avoid decreasing
847     the counter to 0.  Given that groups have the form described in
848     is_in_group in rpl_rli.h, we implement the logic as follows:
849 
850     - Gtid, Rand, User_var, Int_var will never decrease the counter to
851       0.
852 
853     - BEGIN will set thd->variables.option_bits & OPTION_BEGIN and
854       COMMIT/Xid will clear it.  This happens regardless of whether
855       the BEGIN/COMMIT/Xid is skipped itself.
856 
857     - Other events will decrease the counter unless OPTION_BEGIN is
858       set.
859   */
860   DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
861                       " rli->replicate_same_server_id=%d,"
862                       " rli->slave_skip_counter=%d",
863                       (ulong) server_id, (ulong) ::server_id,
864                       rli->replicate_same_server_id,
865                       rli->slave_skip_counter));
866   if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
867       (rli->slave_skip_counter == 1 && rli->is_in_group()))
868     return EVENT_SKIP_IGNORE;
869   else if (rli->slave_skip_counter > 0)
870     return EVENT_SKIP_COUNT;
871   else
872     return EVENT_SKIP_NOT;
873 }
874 
875 
876 /*
877   Log_event::pack_info()
878 */
879 
pack_info(Protocol * protocol)880 int Log_event::pack_info(Protocol *protocol)
881 {
882   protocol->store("", &my_charset_bin);
883   return 0;
884 }
885 
886 
887 /**
888   Only called by SHOW BINLOG EVENTS
889 */
net_send(Protocol * protocol,const char * log_name,my_off_t pos)890 int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
891 {
892   const char *p= strrchr(log_name, FN_LIBCHAR);
893   const char *event_type;
894   if (p)
895     log_name = p + 1;
896 
897   protocol->start_row();
898   protocol->store(log_name, &my_charset_bin);
899   protocol->store((ulonglong) pos);
900   event_type = get_type_str();
901   protocol->store(event_type, strlen(event_type), &my_charset_bin);
902   protocol->store((uint32) server_id);
903   protocol->store((ulonglong) common_header->log_pos);
904   if (pack_info(protocol))
905     return 1;
906   return protocol->end_row();
907 }
908 #endif /* HAVE_REPLICATION */
909 
910 
911 /**
912   init_show_field_list() prepares the column names and types for the
913   output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
914   EVENTS.
915 */
916 
init_show_field_list(List<Item> * field_list)917 void Log_event::init_show_field_list(List<Item>* field_list)
918 {
919   field_list->push_back(new Item_empty_string("Log_name", 20));
920   field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
921 					    MYSQL_TYPE_LONGLONG));
922   field_list->push_back(new Item_empty_string("Event_type", 20));
923   field_list->push_back(new Item_return_int("Server_id", 10,
924 					    MYSQL_TYPE_LONG));
925   field_list->push_back(new Item_return_int("End_log_pos",
926                                             MY_INT32_NUM_DECIMAL_DIGITS,
927 					    MYSQL_TYPE_LONGLONG));
928   field_list->push_back(new Item_empty_string("Info", 20));
929 }
930 
931 /**
932    A decider of whether to trigger checksum computation or not.
933    To be invoked in Log_event::write() stack.
934    The decision is positive
935 
936     S,M) if it's been marked for checksumming with @c checksum_alg
937 
938     M) otherwise, if @@global.binlog_checksum is not NONE and the event is
939        directly written to the binlog file.
940        The to-be-cached event decides at @c write_cache() time.
941 
942    Otherwise the decision is negative.
943 
944    @note   A side effect of the method is altering Log_event::checksum_alg
945            it the latter was undefined at calling.
946 
947    @return true (positive) or false (negative)
948 */
need_checksum()949 my_bool Log_event::need_checksum()
950 {
951   DBUG_ENTER("Log_event::need_checksum");
952   my_bool ret= FALSE;
953   /*
954      few callers of Log_event::write
955      (incl FD::write, FD constructing code on the slave side, Rotate relay log
956      and Stop event)
957      provides their checksum alg preference through Log_event::checksum_alg.
958   */
959   if (common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
960     ret= (common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF);
961   else if (binlog_checksum_options != binary_log::BINLOG_CHECKSUM_ALG_OFF &&
962            event_cache_type == Log_event::EVENT_NO_CACHE)
963     ret= (binlog_checksum_options != 0);
964   else
965     ret= FALSE;
966 
967   /*
968     FD calls the methods before data_written has been calculated.
969     The following invariant claims if the current is not the first
970     call (and therefore data_written is not zero) then `ret' must be
971     TRUE. It may not be null because FD is always checksummed.
972   */
973 
974   assert(get_type_code() != binary_log::FORMAT_DESCRIPTION_EVENT || ret ||
975          common_header->data_written == 0);
976 
977   if (common_footer->checksum_alg == binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
978     common_footer->checksum_alg= ret ? // calculated value stored
979       static_cast<enum_binlog_checksum_alg>(binlog_checksum_options) :
980       binary_log::BINLOG_CHECKSUM_ALG_OFF;
981 
982   assert(!ret ||
983          ((common_footer->checksum_alg ==
984            static_cast<enum_binlog_checksum_alg>(binlog_checksum_options) ||
985            /*
986              Stop event closes the relay-log and its checksum alg
987              preference is set by the caller can be different
988              from the server's binlog_checksum_options.
989            */
990            get_type_code() == binary_log::STOP_EVENT ||
991            /*
992              Rotate:s can be checksummed regardless of the server's
993              binlog_checksum_options. That applies to both
994              the local RL's Rotate and the master's Rotate
995              which IO thread instantiates via queue_binlog_ver_3_event.
996            */
997            get_type_code() == binary_log::ROTATE_EVENT ||
998            get_type_code() == binary_log::START_ENCRYPTION_EVENT ||
999            /*
1000              The previous event has its checksum option defined
1001              according to the format description event.
1002            */
1003            get_type_code() == binary_log::PREVIOUS_GTIDS_LOG_EVENT ||
1004            /* FD is always checksummed */
1005            get_type_code() == binary_log::FORMAT_DESCRIPTION_EVENT) &&
1006           common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF));
1007 
1008   assert(common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF);
1009   assert(((get_type_code() != binary_log::ROTATE_EVENT &&
1010            get_type_code() != binary_log::STOP_EVENT) ||
1011           get_type_code() != binary_log::FORMAT_DESCRIPTION_EVENT) ||
1012          event_cache_type == Log_event::EVENT_NO_CACHE);
1013 
1014   DBUG_RETURN(ret);
1015 }
1016 
wrapper_my_b_safe_write(IO_CACHE * file,const uchar * buf,size_t size)1017 bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, size_t size)
1018 {
1019   DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1020                   {
1021                     memset(file->write_pos, 0, file->write_end - file->write_pos);
1022                     file->write_pos=file->write_end;
1023                     DBUG_SET("+d,simulate_file_write_error");
1024                   });
1025   if (need_checksum() && size != 0)
1026     crc= checksum_crc32(crc, buf, size);
1027 
1028   bool ret = event_encrypter.encrypt_and_write(file, buf, size);
1029   DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1030                   {
1031                     DBUG_SET("-d,simulate_file_write_error");
1032                   });
1033   return ret;
1034 }
1035 
write_footer(IO_CACHE * file)1036 bool Log_event::write_footer(IO_CACHE* file)
1037 {
1038   /*
1039      footer contains the checksum-algorithm descriptor
1040      followed by the checksum value
1041   */
1042   if (need_checksum())
1043   {
1044     uchar buf[BINLOG_CHECKSUM_LEN];
1045     int4store(buf, crc);
1046     if (event_encrypter.encrypt_and_write(file, buf, BINLOG_CHECKSUM_LEN))
1047       return true;
1048   }
1049   return event_encrypter.is_encryption_enabled() &&
1050       event_encrypter.finish(file);
1051 }
1052 
1053 
write_header_to_memory(uchar * buf)1054 uint32 Log_event::write_header_to_memory(uchar *buf)
1055 {
1056   // Query start time
1057   ulong timestamp= (ulong) get_time();
1058 
1059 #ifndef NDEBUG
1060   if (DBUG_EVALUATE_IF("inc_event_time_by_1_hour",1,0)  &&
1061       DBUG_EVALUATE_IF("dec_event_time_by_1_hour",1,0))
1062   {
1063     /**
1064       This assertion guarantees that these debug flags are not
1065       used at the same time (they would cancel each other).
1066     */
1067     assert(0);
1068   }
1069   else
1070   {
1071     DBUG_EXECUTE_IF("inc_event_time_by_1_hour", timestamp= timestamp + 3600;);
1072     DBUG_EXECUTE_IF("dec_event_time_by_1_hour", timestamp= timestamp - 3600;);
1073   }
1074 #endif
1075 
1076   /*
1077     Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1078     FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1079     LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1080     because we read them before knowing the format).
1081   */
1082 
1083   int4store(buf, timestamp);
1084   buf[EVENT_TYPE_OFFSET]= get_type_code();
1085   int4store(buf + SERVER_ID_OFFSET, server_id);
1086   int4store(buf + EVENT_LEN_OFFSET,
1087             static_cast<uint32>(common_header->data_written));
1088   int4store(buf + LOG_POS_OFFSET,
1089             static_cast<uint32>(common_header->log_pos));
1090   int2store(buf + FLAGS_OFFSET, common_header->flags);
1091 
1092   return LOG_EVENT_HEADER_LEN;
1093 }
1094 
1095 
write_header(IO_CACHE * file,size_t event_data_length)1096 bool Log_event::write_header(IO_CACHE* file, size_t event_data_length)
1097 {
1098   uchar header[LOG_EVENT_HEADER_LEN];
1099   DBUG_ENTER("Log_event::write_header");
1100 
1101   /* Store number of bytes that will be written by this event */
1102   common_header->data_written= event_data_length + sizeof(header);
1103 
1104   if (need_checksum())
1105   {
1106     crc= checksum_crc32(0L, NULL, 0);
1107     common_header->data_written += BINLOG_CHECKSUM_LEN;
1108   }
1109 
1110   /*
1111     log_pos != 0 if this is relay-log event. In this case we should not
1112     change the position
1113   */
1114 
1115   if (is_artificial_event())
1116   {
1117     /*
1118       Artificial events are automatically generated and do not exist
1119       in master's binary log, so log_pos should be set to 0.
1120     */
1121     common_header->log_pos= 0;
1122   }
1123   else  if (!common_header->log_pos)
1124   {
1125     /*
1126       Calculate position of end of event
1127 
1128       Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
1129       work well.  So this will give slightly wrong positions for the
1130       Format_desc/Rotate/Stop events which the slave writes to its
1131       relay log. For example, the initial Format_desc will have
1132       end_log_pos=91 instead of 95. Because after writing the first 4
1133       bytes of the relay log, my_b_tell() still reports 0. Because
1134       my_b_append() does not update the counter which my_b_tell()
1135       later uses (one should probably use my_b_append_tell() to work
1136       around this).  To get right positions even when writing to the
1137       relay log, we use the (new) my_b_safe_tell().
1138 
1139       Note that this raises a question on the correctness of all these
1140       assert(my_b_tell()=rli->event_relay_log_pos).
1141 
1142       If in a transaction, the log_pos which we calculate below is not
1143       very good (because then my_b_safe_tell() returns start position
1144       of the BEGIN, so it's like the statement was at the BEGIN's
1145       place), but it's not a very serious problem (as the slave, when
1146       it is in a transaction, does not take those end_log_pos into
1147       account (as it calls inc_event_relay_log_pos()). To be fixed
1148       later, so that it looks less strange. But not bug.
1149     */
1150 
1151     common_header->log_pos= my_b_safe_tell(file) + common_header->data_written;
1152   }
1153 
1154   write_header_to_memory(header);
1155 
1156   const bool is_format_description_and_need_checksum= need_checksum() &&
1157        ((common_header->flags & LOG_EVENT_BINLOG_IN_USE_F) != 0);
1158 
1159   /*
1160     Update the checksum.
1161 
1162     In case this is a Format_description_log_event, we need to clear
1163     the LOG_EVENT_BINLOG_IN_USE_F flag before computing the checksum,
1164     since the flag will be cleared when the binlog is closed.  On
1165     verification, the flag is dropped before computing the checksum
1166     too. We need to compute the checksum before we encrypt the header,
1167     in case binlog encryption is turned on.
1168   */
1169 
1170   if (is_format_description_and_need_checksum)
1171   {
1172     common_header->flags&= ~LOG_EVENT_BINLOG_IN_USE_F;
1173     int2store(header + FLAGS_OFFSET, common_header->flags);
1174   }
1175   crc= my_checksum(crc, header, LOG_EVENT_HEADER_LEN);
1176 
1177   // restore IN_USE flag after calculating the checksum
1178   if (is_format_description_and_need_checksum)
1179   {
1180     common_header->flags|= LOG_EVENT_BINLOG_IN_USE_F;
1181     int2store(header + FLAGS_OFFSET, common_header->flags);
1182   }
1183 
1184   uchar *pos= header;
1185   size_t len= sizeof(header);
1186 
1187   if (event_encrypter.is_encryption_enabled() &&
1188       event_encrypter.init(file, pos, len))
1189     DBUG_RETURN(true);
1190 
1191   DBUG_RETURN(event_encrypter.encrypt_and_write(file, pos, len));
1192 }
1193 
1194 /**
1195   This needn't be format-tolerant, because we only read
1196   LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
1197 
1198   The caller should allocate the packet buffer before calling this function.
1199 */
1200 
read_log_event(IO_CACHE * file,String * packet,const Format_description_log_event * fdle,mysql_mutex_t * log_lock,enum_binlog_checksum_alg checksum_alg_arg,const char * log_file_name_arg,bool * is_binlog_active,char * event_header)1201 int Log_event::read_log_event(IO_CACHE* file, String* packet,
1202                               const Format_description_log_event *fdle,
1203                               mysql_mutex_t* log_lock,
1204                               enum_binlog_checksum_alg checksum_alg_arg,
1205                               const char *log_file_name_arg,
1206                               bool* is_binlog_active,
1207                               char *event_header)
1208 {
1209 
1210   ulong data_len;
1211   int result=0;
1212   char local_buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1213   char *buf= event_header != NULL ? event_header : local_buf;
1214   size_t ev_offset= packet->length();
1215   DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, String *, mysql_mutex_t, uint8)");
1216 
1217   if (log_lock)
1218     mysql_mutex_lock(log_lock);
1219 
1220   if (log_file_name_arg)
1221     *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
1222 
1223   /* If the event header wasn't passed, we need to read it. */
1224   if (buf == local_buf)
1225   {
1226     if (my_b_read(file, (uchar*) buf, LOG_EVENT_MINIMAL_HEADER_LEN))
1227     {
1228       /*
1229         If the read hits eof, we must report it as eof so the caller
1230         will know it can go into cond_wait to be woken up on the next
1231         update to the log.
1232       */
1233       DBUG_PRINT("error",("my_b_read failed. file->error: %d", file->error));
1234       if (!file->error)
1235         result= LOG_READ_EOF;
1236       else
1237         result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1238       goto end;
1239     }
1240   }
1241   else
1242     DBUG_PRINT("info",("Skipped reading the event header. Using the provided one."));
1243 
1244   data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1245   if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
1246       data_len > max(current_thd->variables.max_allowed_packet,
1247                      opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
1248   {
1249     DBUG_PRINT("error",("data_len is out of bounds. data_len: %lu", data_len));
1250     result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
1251 	     LOG_READ_TOO_LARGE);
1252     goto end;
1253   }
1254 
1255   /*
1256     If the event header wasn't passed, the caller doesn't know the event size
1257     yet, so the packet size may not have enough space to load the entire
1258     event. We need to adjust the packet size here since the call to my_b_read()
1259     below expects the buffer to be allocated.
1260   */
1261   if (buf == local_buf)
1262   {
1263     ulong new_alloc_len= packet->length() + data_len;
1264     if (new_alloc_len > packet->alloced_length() &&
1265         packet->mem_realloc(new_alloc_len))
1266     {
1267       /* Failed to allocate packet */
1268       result= LOG_READ_MEM;
1269       goto end;
1270     }
1271   }
1272 
1273   /* Check packet buffer size and append the log event header to it */
1274   if (packet->alloced_length() - packet->length() < data_len ||
1275       packet->append(buf, LOG_EVENT_MINIMAL_HEADER_LEN))
1276   {
1277     DBUG_PRINT("info", ("first packet->append failed (out of memory)"));
1278     /* Failed to allocate packet */
1279     result= LOG_READ_MEM;
1280     goto end;
1281   }
1282   data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
1283   if (data_len)
1284   {
1285     /*
1286       Append rest of event, read directly from file into packet.
1287 
1288       We are avoiding to call packet->append(IO_CACHE, size_t) at this point
1289       because the String::append logic will call String::mem_realloc() that
1290       might resize the buffer (changing its pointer) in order to reserve a
1291       space for a trailing '\0' that we don't need.
1292     */
1293     char *event_data_buffer= const_cast<char*>(packet->ptr() +
1294                                                packet->length());
1295     result= my_b_read(file,
1296                       reinterpret_cast<uchar*>(event_data_buffer),
1297                       data_len);
1298     if (result)
1299     {
1300       /*
1301         Fatal error occured when appending rest of the event
1302         to packet, possible failures:
1303 	1. EOF occured when reading from file, it's really an error
1304            as data_len is >=0 there's supposed to be more bytes available.
1305            file->error will have been set to number of bytes left to read
1306         2. Read was interrupted, file->error would normally be set to -1
1307         3. Failed to allocate memory for packet, my_errno
1308            will be ENOMEM(file->error shuold be 0, but since the
1309            memory allocation occurs before the call to read it might
1310            be uninitialized)
1311       */
1312       DBUG_PRINT("info", ("second packet->append failed (out of memory)"));
1313       result= (my_errno() == ENOMEM ? LOG_READ_MEM :
1314                (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1315       goto end;
1316     }
1317     else
1318     {
1319       packet->length(packet->length() + data_len);
1320 
1321       if (fdle != NULL && fdle->crypto_data.is_enabled())
1322       {
1323         size_t true_data_len= data_len + LOG_EVENT_MINIMAL_HEADER_LEN;
1324 
1325         char *decrypted_packet=
1326           reinterpret_cast<char*>(my_malloc(key_memory_log_event, true_data_len + ev_offset + 1,
1327                                             MYF(MY_WME)));
1328         if (!decrypted_packet)
1329           DBUG_RETURN(LOG_READ_MEM);
1330         memcpy(decrypted_packet, packet->ptr(), ev_offset);
1331 
1332         uchar *src= (uchar*)packet->ptr() + ev_offset;
1333         uchar *dst= (uchar*)decrypted_packet + ev_offset;
1334         memcpy(src + EVENT_LEN_OFFSET, src, 4);
1335 
1336         if (decrypt_event(my_b_tell(file) - true_data_len, fdle->crypto_data, src, dst, true_data_len))
1337         {
1338           my_free(decrypted_packet);
1339           DBUG_RETURN(LOG_READ_DECRYPT);
1340         }
1341 
1342         packet->length(0);  // size of the content
1343         packet->append(decrypted_packet, true_data_len + ev_offset);
1344         my_free(decrypted_packet);
1345       }
1346       /*
1347         Corrupt the event for Dump thread.
1348         We also need to exclude Previous_gtids_log_event and Gtid_log_event
1349         events from injected corruption to allow dump thread to move forward
1350         on binary log until the missing transactions from slave when
1351         MASTER_AUTO_POSITION= 1.
1352       */
1353       DBUG_EXECUTE_IF("corrupt_read_log_event",
1354 	uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
1355         if (debug_event_buf_c[EVENT_TYPE_OFFSET] != binary_log::FORMAT_DESCRIPTION_EVENT &&
1356             debug_event_buf_c[EVENT_TYPE_OFFSET] != binary_log::PREVIOUS_GTIDS_LOG_EVENT &&
1357             debug_event_buf_c[EVENT_TYPE_OFFSET] != binary_log::GTID_LOG_EVENT &&
1358             debug_event_buf_c[EVENT_TYPE_OFFSET] != binary_log::START_ENCRYPTION_EVENT)
1359         {
1360           int debug_cor_pos = rand() % (data_len + LOG_EVENT_MINIMAL_HEADER_LEN -
1361                               BINLOG_CHECKSUM_LEN);
1362           debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1363           DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
1364 	}
1365       );
1366       /*
1367         CRC verification of the Dump thread
1368       */
1369       binary_log_debug::debug_checksum_test=
1370         DBUG_EVALUATE_IF("simulate_checksum_test_failure", true, false);
1371 
1372       if (opt_master_verify_checksum &&
1373         Log_event_footer::event_checksum_test((uchar*)packet->ptr() + ev_offset,
1374                                               data_len + LOG_EVENT_MINIMAL_HEADER_LEN,
1375                                               checksum_alg_arg))
1376       {
1377         DBUG_PRINT("info", ("checksum test failed"));
1378         result= LOG_READ_CHECKSUM_FAILURE;
1379         goto end;
1380       }
1381     }
1382   }
1383 
1384 end:
1385   if (log_lock)
1386     mysql_mutex_unlock(log_lock);
1387   DBUG_PRINT("info", ("read_log_event returns %d", result));
1388   DBUG_RETURN(result);
1389 }
1390 #endif /* !MYSQL_CLIENT */
1391 
1392 #ifndef MYSQL_CLIENT
1393 #define UNLOCK_MUTEX if (log_lock) mysql_mutex_unlock(log_lock);
1394 #define LOCK_MUTEX if (log_lock) mysql_mutex_lock(log_lock);
1395 #else
1396 #define UNLOCK_MUTEX
1397 #define LOCK_MUTEX
1398 #endif
1399 
1400 #ifndef MYSQL_CLIENT
1401 /**
1402   @note
1403     Allocates memory;  The caller is responsible for clean-up.
1404 */
read_log_event(IO_CACHE * file,mysql_mutex_t * log_lock,const Format_description_log_event * description_event,my_bool crc_check)1405 Log_event* Log_event::read_log_event(IO_CACHE* file,
1406                                      mysql_mutex_t* log_lock,
1407                                      const Format_description_log_event
1408                                      *description_event,
1409                                      my_bool crc_check)
1410 #else
1411 Log_event* Log_event::read_log_event(IO_CACHE* file,
1412                                      const Format_description_log_event
1413                                      *description_event,
1414                                      my_bool crc_check,
1415                                      read_log_event_filter_function f)
1416 #endif
1417 {
1418   DBUG_ENTER("Log_event::read_log_event(IO_CACHE *[, mysql_mutex_t *], Format_description_log_event *, my_bool)");
1419   assert(description_event != 0);
1420   char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1421   /*
1422     First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1423     check the event for sanity and to know its length; no need to really parse
1424     it. We say "at most" because this could be a 3.23 master, which has header
1425     of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
1426     "minimal" over the set {MySQL >=4.0}).
1427   */
1428   uint header_size= min<uint>(description_event->common_header_len,
1429                               LOG_EVENT_MINIMAL_HEADER_LEN);
1430 
1431   LOCK_MUTEX;
1432   DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
1433   if (my_b_read(file, (uchar *) head, header_size))
1434   {
1435     DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) "
1436                         "failed in my_b_read((IO_CACHE*)%p, (uchar*)%p, %u)",
1437                         file, head, header_size));
1438     UNLOCK_MUTEX;
1439     /*
1440       No error here; it could be that we are at the file's end. However
1441       if the next my_b_read() fails (below), it will be an error as we
1442       were able to read the first bytes.
1443     */
1444     DBUG_RETURN(0);
1445   }
1446   ulong data_len = uint4korr(head + EVENT_LEN_OFFSET);
1447   char *buf= 0;
1448   const char *error= 0;
1449   Log_event *res=  0;
1450 #if !defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
1451   ulong log_max_allowed_packet = 0;
1452   mysql_get_option(NULL, MYSQL_OPT_MAX_ALLOWED_PACKET,
1453                    &log_max_allowed_packet);
1454 #else
1455   THD *thd=current_thd;
1456   uint log_max_allowed_packet= thd ? slave_max_allowed_packet : ~0U;
1457 #endif
1458 
1459   ulong const max_size=
1460     max<ulong>(log_max_allowed_packet,
1461                opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER);
1462   if (data_len > max_size)
1463   {
1464     error = "Event too big";
1465     goto err;
1466   }
1467 
1468   if (data_len < header_size)
1469   {
1470     error = "Event invalid";
1471     goto err;
1472   }
1473 
1474   // some events use the extra byte to null-terminate strings
1475   if (!(buf = (char*) my_malloc(key_memory_log_event,
1476                                 data_len+1, MYF(MY_WME))))
1477   {
1478     error = "Out of memory";
1479     goto err;
1480   }
1481   buf[data_len] = 0;
1482   memcpy(buf, head, header_size);
1483   if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1484   {
1485     error = "read error";
1486     goto err;
1487   }
1488 
1489   if (description_event->crypto_data.is_enabled())
1490   {
1491 #if defined(MYSQL_CLIENT)
1492     // Clients do not have access to keyring and thus cannot decrypt
1493     // binlog events
1494     error= "Decryption error as clients do not have access to keyring and thus "
1495            "cannot decrypt binlog events.";
1496     goto err;
1497 #endif
1498     char *dst_buf=
1499       reinterpret_cast<char*>(my_malloc(key_memory_log_event, data_len + 1, MYF(MY_WME)));
1500     dst_buf[data_len]=0;
1501     memcpy(dst_buf, buf, data_len);
1502 
1503     if (decrypt_event(my_b_tell(file) - data_len, description_event->crypto_data, (uchar*)buf, (uchar*)dst_buf, data_len))
1504     {
1505       my_free(dst_buf);
1506       error= "decryption error";
1507       goto err;
1508     }
1509 
1510     my_free(buf);
1511     buf= dst_buf;
1512   }
1513 
1514 #if defined(MYSQL_CLIENT)
1515   if (f && f(&buf, &data_len, description_event))
1516   {
1517     error = "Error applying filter while reading event";
1518     goto err;
1519   }
1520 #endif
1521   if ((res= read_log_event(buf, data_len, &error, description_event, crc_check)))
1522     res->register_temp_buf(buf);
1523 
1524 err:
1525   UNLOCK_MUTEX;
1526   if (!res)
1527   {
1528     assert(error != 0);
1529     /* Don't log error if read_log_event invoked from SHOW BINLOG EVENTS */
1530 #ifdef MYSQL_CLIENT
1531     if (force_opt)
1532       DBUG_RETURN(new Unknown_log_event());
1533 #endif
1534 #ifdef MYSQL_SERVER
1535     THD *thd= current_thd;
1536     if (!(thd && thd->lex &&
1537           thd->lex->sql_command == SQLCOM_SHOW_BINLOG_EVENTS)) {
1538 #endif
1539       sql_print_error("Error in Log_event::read_log_event(): "
1540                       "'%s', data_len: %lu, event_type: %d",
1541 		      error,data_len,head[EVENT_TYPE_OFFSET]);
1542 #ifdef MYSQL_SERVER
1543     }
1544 #endif
1545     my_free(buf);
1546     /*
1547       The SQL slave thread will check if file->error<0 to know
1548       if there was an I/O error. Even if there is no "low-level" I/O errors
1549       with 'file', any of the high-level above errors is worrying
1550       enough to stop the SQL thread now ; as we are skipping the current event,
1551       going on with reading and successfully executing other events can
1552       only corrupt the slave's databases. So stop.
1553       The file->error is also checked to record the position of
1554       the last valid event when master server recovers.
1555     */
1556     file->error= -1;
1557   }
1558   DBUG_RETURN(res);
1559 }
1560 
1561 
1562 /**
1563   Binlog format tolerance is in (buf, event_len, description_event)
1564   constructors.
1565 */
1566 
read_log_event(const char * buf,uint event_len,const char ** error,const Format_description_log_event * description_event,my_bool crc_check)1567 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1568 				     const char **error,
1569                                      const Format_description_log_event *description_event,
1570                                      my_bool crc_check)
1571 {
1572   Log_event* ev= NULL;
1573   enum_binlog_checksum_alg  alg;
1574   DBUG_ENTER("Log_event::read_log_event(char *, uint, char **, Format_description_log_event *, my_bool)");
1575   assert(description_event != 0);
1576   DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1577   DBUG_DUMP("data", (unsigned char*) buf, event_len);
1578 
1579 #ifdef MYSQL_CLIENT
1580     static bool was_start_encryption_event = false;
1581     if (was_start_encryption_event)
1582     {
1583       // We know that binlog is encrypted (as we read Start_encryption event) and we know that
1584       // client applications cannot decrypt encrypted binlogs as they have no access to
1585       // keyring. Thus we return Unknown_event for all encrypted events when force is used
1586       // and close mysqlbinlog when no force.
1587       if (!force_opt)
1588       {
1589         *error= "No point in reading encrypted binlog - quitting. "
1590                 "Start mysqlbinlog with --force-read if you want to attempt "
1591                 "to read an encrypted binlog without decryption.";
1592         DBUG_RETURN(0);
1593       }
1594       DBUG_RETURN(new Unknown_log_event);
1595     }
1596 #endif
1597 
1598   /* Check the integrity */
1599   if (event_len < EVENT_LEN_OFFSET ||
1600       event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1601   {
1602     DBUG_PRINT("error", ("event_len=%u EVENT_LEN_OFFSET=%d "
1603                          "buf[EVENT_TYPE_OFFSET]=%d ENUM_END_EVENT=%d "
1604                          "uint4korr(buf+EVENT_LEN_OFFSET)=%d",
1605                          event_len, EVENT_LEN_OFFSET,
1606                          buf[EVENT_TYPE_OFFSET], binary_log::ENUM_END_EVENT,
1607                          uint4korr(buf+EVENT_LEN_OFFSET)));
1608     *error="Sanity check failed";		// Needed to free buffer
1609     DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1610   }
1611 
1612   uint event_type= static_cast<uchar>(buf[EVENT_TYPE_OFFSET]);
1613   // all following START events in the current file are without checksum
1614   if (event_type == binary_log::START_EVENT_V3)
1615     (const_cast<Format_description_log_event*>(description_event))->
1616             common_footer->checksum_alg= binary_log::BINLOG_CHECKSUM_ALG_OFF;
1617   // Sanity check for Format description event
1618   if (event_type == binary_log::FORMAT_DESCRIPTION_EVENT)
1619   {
1620     if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN +
1621         ST_COMMON_HEADER_LEN_OFFSET)
1622     {
1623       *error= "Found invalid Format description event in binary log";
1624       DBUG_RETURN(0);
1625     }
1626     uint tmp_header_len= buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET];
1627     if (event_len < tmp_header_len + ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
1628     {
1629       *error= "Found invalid Format description event in binary log";
1630       DBUG_RETURN(0);
1631     }
1632   }
1633   /*
1634     CRC verification by SQL and Show-Binlog-Events master side.
1635     The caller has to provide @description_event->checksum_alg to
1636     be the last seen FD's (A) descriptor.
1637     If event is FD the descriptor is in it.
1638     Notice, FD of the binlog can be only in one instance and therefore
1639     Show-Binlog-Events executing master side thread needs just to know
1640     the only FD's (A) value -  whereas RL can contain more.
1641     In the RL case, the alg is kept in FD_e (@description_event) which is reset
1642     to the newer read-out event after its execution with possibly new alg descriptor.
1643     Therefore in a typical sequence of RL:
1644     {FD_s^0, FD_m, E_m^1} E_m^1
1645     will be verified with (A) of FD_m.
1646 
1647     See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
1648     lines (log.h).
1649 
1650     Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
1651   */
1652   alg= (event_type != binary_log::FORMAT_DESCRIPTION_EVENT) ?
1653        description_event->common_footer->checksum_alg :
1654        Log_event_footer::get_checksum_alg(buf, event_len);
1655   // Emulate the corruption during reading an event
1656   DBUG_EXECUTE_IF("corrupt_read_log_event_char",
1657     if (event_type != binary_log::FORMAT_DESCRIPTION_EVENT &&
1658         event_type != binary_log::START_ENCRYPTION_EVENT)
1659     {
1660       char *debug_event_buf_c = (char *)buf;
1661       int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
1662       debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1663       DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
1664       DBUG_SET("");
1665     }
1666   );
1667 
1668 #ifndef NDEBUG
1669   binary_log_debug::debug_checksum_test=
1670     DBUG_EVALUATE_IF("simulate_checksum_test_failure", true, false);
1671 #endif
1672   if (crc_check &&
1673       Log_event_footer::event_checksum_test((uchar *) buf, event_len, alg) &&
1674       /* Skip the crc check when simulating an unknown ignorable log event. */
1675       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1676   {
1677     *error= "Event crc check failed! Most likely there is event corruption.";
1678 #ifdef MYSQL_CLIENT
1679     if (force_opt)
1680     {
1681       ev= new Unknown_log_event(buf, description_event);
1682       DBUG_RETURN(ev);
1683     }
1684 #endif
1685     DBUG_RETURN(NULL);
1686   }
1687 
1688   if (event_type > description_event->number_of_event_types &&
1689       event_type != binary_log::FORMAT_DESCRIPTION_EVENT &&
1690       event_type != binary_log::START_ENCRYPTION_EVENT &&
1691       /*
1692         Skip the event type check when simulating an
1693         unknown ignorable log event.
1694       */
1695       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1696   {
1697     /*
1698       It is unsafe to use the description_event if its post_header_len
1699       array does not include the event type.
1700     */
1701     DBUG_PRINT("error", ("event type %d found, but the current "
1702                          "Format_description_log_event supports only %d event "
1703                          "types", event_type,
1704                          description_event->number_of_event_types));
1705     ev= NULL;
1706   }
1707   else
1708   {
1709     /*
1710       In some previuos versions (see comment in
1711       Format_description_log_event::Format_description_log_event(char*,...)),
1712       event types were assigned different id numbers than in the
1713       present version. In order to replicate from such versions to the
1714       present version, we must map those event type id's to our event
1715       type id's.  The mapping is done with the event_type_permutation
1716       array, which was set up when the Format_description_log_event
1717       was read.
1718     */
1719     if (description_event->event_type_permutation)
1720     {
1721       uint new_event_type;
1722       if (event_type >= EVENT_TYPE_PERMUTATION_NUM)
1723         /* Safe guard for read out of bounds of event_type_permutation. */
1724         new_event_type= binary_log::UNKNOWN_EVENT;
1725       else
1726         new_event_type= description_event->event_type_permutation[event_type];
1727 
1728       DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1729                  event_type, new_event_type,
1730                  get_type_str((Log_event_type)new_event_type)));
1731       event_type= new_event_type;
1732     }
1733 
1734     if (alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF &&
1735         (event_type == binary_log::FORMAT_DESCRIPTION_EVENT ||
1736          alg != binary_log::BINLOG_CHECKSUM_ALG_OFF))
1737       event_len= event_len - BINLOG_CHECKSUM_LEN;
1738 
1739     switch(event_type) {
1740     case binary_log::QUERY_EVENT:
1741 #ifndef NDEBUG
1742       binary_log_debug::debug_query_mts_corrupt_db_names=
1743         DBUG_EVALUATE_IF("query_log_event_mts_corrupt_db_names", true, false);
1744 #endif
1745       ev  = new Query_log_event(buf, event_len, description_event,
1746                                 binary_log::QUERY_EVENT);
1747       break;
1748     case binary_log::LOAD_EVENT:
1749     case binary_log::NEW_LOAD_EVENT:
1750 #ifndef NDEBUG
1751       binary_log_debug::debug_simulate_invalid_address=
1752         DBUG_EVALUATE_IF("simulate_invalid_address", true, false);
1753 #endif
1754       ev = new Load_log_event(buf, event_len, description_event);
1755       break;
1756     case binary_log::ROTATE_EVENT:
1757       ev = new Rotate_log_event(buf, event_len, description_event);
1758       break;
1759     case binary_log::CREATE_FILE_EVENT:
1760 #ifndef NDEBUG
1761       binary_log_debug::debug_simulate_invalid_address=
1762         DBUG_EVALUATE_IF("simulate_invalid_address", true, false);
1763 #endif
1764       ev = new Create_file_log_event(buf, event_len, description_event);
1765       break;
1766     case binary_log::APPEND_BLOCK_EVENT:
1767       ev = new Append_block_log_event(buf, event_len, description_event);
1768       break;
1769     case binary_log::DELETE_FILE_EVENT:
1770       ev = new Delete_file_log_event(buf, event_len, description_event);
1771       break;
1772     case binary_log::EXEC_LOAD_EVENT:
1773       ev = new Execute_load_log_event(buf, event_len, description_event);
1774       break;
1775     case binary_log::START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1776       ev = new Start_log_event_v3(buf, event_len, description_event);
1777       break;
1778     case binary_log::STOP_EVENT:
1779       ev = new Stop_log_event(buf, description_event);
1780       break;
1781     case binary_log::INTVAR_EVENT:
1782       ev = new Intvar_log_event(buf, description_event);
1783       break;
1784     case binary_log::XID_EVENT:
1785       ev = new Xid_log_event(buf, description_event);
1786       break;
1787     case binary_log::RAND_EVENT:
1788       ev = new Rand_log_event(buf, description_event);
1789       break;
1790     case binary_log::USER_VAR_EVENT:
1791       ev = new User_var_log_event(buf, event_len, description_event);
1792       break;
1793     case binary_log::FORMAT_DESCRIPTION_EVENT:
1794       ev = new Format_description_log_event(buf, event_len, description_event);
1795       break;
1796 #if defined(HAVE_REPLICATION)
1797     case binary_log::PRE_GA_WRITE_ROWS_EVENT:
1798       ev = new Write_rows_log_event_old(buf, event_len, description_event);
1799       break;
1800     case binary_log::PRE_GA_UPDATE_ROWS_EVENT:
1801       ev = new Update_rows_log_event_old(buf, event_len, description_event);
1802       break;
1803     case binary_log::PRE_GA_DELETE_ROWS_EVENT:
1804       ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1805       break;
1806     case binary_log::WRITE_ROWS_EVENT_V1:
1807       if (!(description_event->post_header_len.empty()))
1808         ev = new Write_rows_log_event(buf, event_len, description_event);
1809       break;
1810     case binary_log::UPDATE_ROWS_EVENT_V1:
1811       if (!(description_event->post_header_len.empty()))
1812         ev = new Update_rows_log_event(buf, event_len, description_event);
1813       break;
1814     case binary_log::DELETE_ROWS_EVENT_V1:
1815       if (!(description_event->post_header_len.empty()))
1816         ev = new Delete_rows_log_event(buf, event_len, description_event);
1817       break;
1818     case binary_log::TABLE_MAP_EVENT:
1819       if (!(description_event->post_header_len.empty()))
1820         ev = new Table_map_log_event(buf, event_len, description_event);
1821       break;
1822 #endif
1823     case binary_log::BEGIN_LOAD_QUERY_EVENT:
1824       ev = new Begin_load_query_log_event(buf, event_len, description_event);
1825       break;
1826     case binary_log::EXECUTE_LOAD_QUERY_EVENT:
1827       ev= new Execute_load_query_log_event(buf, event_len, description_event);
1828       break;
1829     case binary_log::INCIDENT_EVENT:
1830       ev = new Incident_log_event(buf, event_len, description_event);
1831       break;
1832     case binary_log::START_ENCRYPTION_EVENT:
1833       ev = new Start_encryption_log_event(buf, event_len, description_event);
1834 #ifdef MYSQL_CLIENT
1835       was_start_encryption_event= true;
1836 #endif
1837       break;
1838     case binary_log::ROWS_QUERY_LOG_EVENT:
1839       ev= new Rows_query_log_event(buf, event_len, description_event);
1840       break;
1841     case binary_log::GTID_LOG_EVENT:
1842     case binary_log::ANONYMOUS_GTID_LOG_EVENT:
1843       ev= new Gtid_log_event(buf, event_len, description_event);
1844       break;
1845     case binary_log::PREVIOUS_GTIDS_LOG_EVENT:
1846       ev= new Previous_gtids_log_event(buf, event_len, description_event);
1847       break;
1848 #if defined(HAVE_REPLICATION)
1849     case binary_log::WRITE_ROWS_EVENT:
1850       ev = new Write_rows_log_event(buf, event_len, description_event);
1851       break;
1852     case binary_log::UPDATE_ROWS_EVENT:
1853       ev = new Update_rows_log_event(buf, event_len, description_event);
1854       break;
1855     case binary_log::DELETE_ROWS_EVENT:
1856       ev = new Delete_rows_log_event(buf, event_len, description_event);
1857       break;
1858     case binary_log::TRANSACTION_CONTEXT_EVENT:
1859       ev = new Transaction_context_log_event(buf, event_len, description_event);
1860       break;
1861     case binary_log::VIEW_CHANGE_EVENT:
1862       ev = new View_change_log_event(buf, event_len, description_event);
1863       break;
1864 #endif
1865     case binary_log::XA_PREPARE_LOG_EVENT:
1866       ev= new XA_prepare_log_event(buf, description_event);
1867       break;
1868     default:
1869       /*
1870         Create an object of Ignorable_log_event for unrecognized sub-class.
1871         So that SLAVE SQL THREAD will only update the position and continue.
1872       */
1873       if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1874       {
1875         ev= new Ignorable_log_event(buf, description_event);
1876       }
1877       else
1878       {
1879         DBUG_PRINT("error",("Unknown event code: %d",
1880                             (int) buf[EVENT_TYPE_OFFSET]));
1881         ev= NULL;
1882       }
1883       break;
1884     }
1885   }
1886 
1887   if (ev)
1888   {
1889     ev->common_footer->checksum_alg= alg;
1890     if (ev->common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF &&
1891         ev->common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
1892       ev->crc= uint4korr(buf + (event_len));
1893   }
1894 
1895   DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1896                             ev ? ev->get_type_str() : "<unknown>",
1897                             buf[EVENT_TYPE_OFFSET],
1898                             event_len));
1899   /*
1900     is_valid is used for small event-specific sanity tests which are
1901     important; for example there are some my_malloc() in constructors
1902     (e.g. Query_log_event::Query_log_event(char*...)); when these
1903     my_malloc() fail we can't return an error out of the constructor
1904     (because constructor is "void") ; so instead we leave the pointer we
1905     wanted to allocate (e.g. 'query') to 0 and we test it and set the
1906     value of is_valid to true or false based on the test.
1907     Same for Format_description_log_event, member 'post_header_len'.
1908 
1909     SLAVE_EVENT is never used, so it should not be read ever.
1910   */
1911   if (!ev || !ev->is_valid() || (event_type == binary_log::SLAVE_EVENT))
1912   {
1913     DBUG_PRINT("error",("Found invalid event in binary log"));
1914     delete ev;
1915 #ifdef MYSQL_CLIENT
1916     if (!force_opt) /* then mysqlbinlog dies */
1917     {
1918       *error= "Found invalid event in binary log";
1919       DBUG_RETURN(0);
1920     }
1921     ev= new Unknown_log_event(buf, description_event);
1922 #else
1923     *error= "Found invalid event in binary log";
1924     DBUG_RETURN(0);
1925 #endif
1926   }
1927   DBUG_RETURN(ev);
1928 }
1929 
1930 #ifdef MYSQL_CLIENT
1931 
1932 /*
1933   Log_event::print_header()
1934 */
1935 
print_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool is_more MY_ATTRIBUTE ((unused)))1936 void Log_event::print_header(IO_CACHE* file,
1937                              PRINT_EVENT_INFO* print_event_info,
1938                              bool is_more MY_ATTRIBUTE((unused)))
1939 {
1940   MY_ATTRIBUTE((unused)) int write_res;
1941   char llbuff[22];
1942   my_off_t hexdump_from= print_event_info->hexdump_from;
1943   DBUG_ENTER("Log_event::print_header");
1944 
1945   my_b_printf(file, "#");
1946   print_timestamp(file, NULL);
1947   my_b_printf(file, " server id %lu  end_log_pos %s ", (ulong) server_id,
1948               llstr(common_header->log_pos,llbuff));
1949 
1950   /* print the checksum */
1951 
1952   if (common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF &&
1953       common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF)
1954   {
1955     char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
1956     size_t const bytes_written=
1957       my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
1958     my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib,
1959                                       common_footer->checksum_alg));
1960     my_b_printf(file, checksum_buf, bytes_written);
1961   }
1962 
1963   /* mysqlbinlog --hexdump */
1964   if (print_event_info->hexdump_from)
1965   {
1966     my_b_printf(file, "\n");
1967     uchar *ptr= (uchar*)temp_buf;
1968     my_off_t size=
1969       uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1970     my_off_t i;
1971 
1972     /* Header len * 4 >= header len * (2 chars + space + extra space) */
1973     char *h, hex_string[49]= {0};
1974     char *c, char_string[16+1]= {0};
1975 
1976     /* Pretty-print event common header if header is exactly 19 bytes */
1977     if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1978     {
1979       char emit_buf[256];               // Enough for storing one line
1980       my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
1981                   "Size      Master Pos    Flags \n");
1982       size_t const bytes_written=
1983         my_snprintf(emit_buf, sizeof(emit_buf),
1984                     "# %8.8lx %02x %02x %02x %02x   %02x   "
1985                     "%02x %02x %02x %02x   %02x %02x %02x %02x   "
1986                     "%02x %02x %02x %02x   %02x %02x\n",
1987                     (unsigned long) hexdump_from,
1988                     ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1989                     ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1990                     ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1991       assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1992       write_res= my_b_write(file, (uchar*) emit_buf, bytes_written);
1993       assert(write_res == 0);
1994       ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1995       hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1996     }
1997 
1998     /* Rest of event (without common header) */
1999     for (i= 0, c= char_string, h=hex_string;
2000 	 i < size;
2001 	 i++, ptr++)
2002     {
2003       my_snprintf(h, 4, (i % 16 <= 7) ? "%02x " : " %02x", *ptr);
2004       h += 3;
2005 
2006       *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
2007 
2008       if (i % 16 == 15)
2009       {
2010         /*
2011           my_b_printf() does not support full printf() formats, so we
2012           have to do it this way.
2013 
2014           TODO: Rewrite my_b_printf() to support full printf() syntax.
2015          */
2016         char emit_buf[256];
2017         size_t const bytes_written=
2018           my_snprintf(emit_buf, sizeof(emit_buf),
2019                       "# %8.8lx %-48.48s |%16s|\n",
2020                       (unsigned long) (hexdump_from + (i & 0xfffffff0)),
2021                       hex_string, char_string);
2022         assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
2023         write_res= my_b_write(file, (uchar*) emit_buf, bytes_written);
2024         assert(write_res == 0);
2025 	hex_string[0]= 0;
2026 	char_string[0]= 0;
2027 	c= char_string;
2028 	h= hex_string;
2029       }
2030     }
2031     *c= '\0';
2032     assert(hex_string[48] == 0);
2033 
2034     if (hex_string[0])
2035     {
2036       char emit_buf[256];
2037       // Right-pad hex_string with spaces, up to 48 characters.
2038       memset(h, ' ', (sizeof(hex_string) -1) - (h - hex_string));
2039       size_t const bytes_written=
2040         my_snprintf(emit_buf, sizeof(emit_buf),
2041                     "# %8.8lx %-48.48s |%s|\n",
2042                     (unsigned long) (hexdump_from + (i & 0xfffffff0)),
2043                     hex_string, char_string);
2044       assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
2045       write_res= my_b_write(file, (uchar*) emit_buf, bytes_written);
2046       assert(write_res == 0);
2047     }
2048     /*
2049       need a # to prefix the rest of printouts for example those of
2050       Rows_log_event::print_helper().
2051     */
2052     write_res= my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
2053     assert(write_res == 0);
2054   }
2055   DBUG_VOID_RETURN;
2056 }
2057 
2058 
2059 /**
2060   Prints a quoted string to io cache.
2061   Control characters are displayed as hex sequence, e.g. \x00
2062 
2063   @param[in] file              IO cache
2064   @param[in] prt               Pointer to string
2065   @param[in] length            String length
2066 */
2067 
2068 static void
my_b_write_quoted(IO_CACHE * file,const uchar * ptr,uint length)2069 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
2070 {
2071   MY_ATTRIBUTE((unused)) int write_res;
2072   const uchar *s;
2073   my_b_printf(file, "'");
2074   for (s= ptr; length > 0 ; s++, length--)
2075   {
2076     if (*s > 0x1F && *s != '\'' && *s != '\\')
2077     {
2078       write_res= my_b_write(file, s, 1);
2079       assert(write_res == 0);
2080     }
2081     else
2082     {
2083       uchar hex[10];
2084       size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
2085       write_res = my_b_write(file, hex, len);
2086       assert(write_res == 0);
2087     }
2088   }
2089   my_b_printf(file, "'");
2090 }
2091 
2092 /**
2093   Prints a bit string to io cache in format  b'1010'.
2094 
2095   @param[in] file              IO cache
2096   @param[in] ptr               Pointer to string
2097   @param[in] nbits             Number of bits
2098 */
2099 static void
my_b_write_bit(IO_CACHE * file,const uchar * ptr,uint nbits)2100 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
2101 {
2102   uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
2103   my_b_printf(file, "b'");
2104   for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
2105   {
2106     int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8))  & 0x01;
2107     MY_ATTRIBUTE((unused)) int write_res=
2108       my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
2109     assert(write_res == 0);
2110   }
2111   my_b_printf(file, "'");
2112 }
2113 
2114 
2115 /**
2116   Prints a packed string to io cache.
2117   The string consists of length packed to 1 or 2 bytes,
2118   followed by string data itself.
2119 
2120   @param[in] file              IO cache
2121   @param[in] ptr               Pointer to string
2122   @param[in] length            String size
2123 
2124   @retval   - number of bytes scanned.
2125 */
2126 static size_t
my_b_write_quoted_with_length(IO_CACHE * file,const uchar * ptr,uint length)2127 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
2128 {
2129   if (length < 256)
2130   {
2131     length= *ptr;
2132     my_b_write_quoted(file, ptr + 1, length);
2133     return length + 1;
2134   }
2135   else
2136   {
2137     length= uint2korr(ptr);
2138     my_b_write_quoted(file, ptr + 2, length);
2139     return length + 2;
2140   }
2141 }
2142 
2143 
2144 /**
2145   Prints a 32-bit number in both signed and unsigned representation
2146 
2147   @param[in] file              IO cache
2148   @param[in] sl                Signed number
2149   @param[in] ul                Unsigned number
2150 */
2151 static void
my_b_write_sint32_and_uint32(IO_CACHE * file,int32 si,uint32 ui)2152 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
2153 {
2154   my_b_printf(file, "%d", si);
2155   if (si < 0)
2156     my_b_printf(file, " (%u)", ui);
2157 }
2158 
2159 
2160 /**
2161   Print a packed value of the given SQL type into IO cache
2162 
2163   @param[in] file              IO cache
2164   @param[in] ptr               Pointer to string
2165   @param[in] type              Column type
2166   @param[in] meta              Column meta information
2167   @param[out] typestr          SQL type string buffer (for verbose output)
2168   @param[out] typestr_length   Size of typestr
2169 
2170   @retval   - number of bytes scanned from ptr.
2171 */
2172 static size_t
log_event_print_value(IO_CACHE * file,const uchar * ptr,uint type,uint meta,char * typestr,size_t typestr_length)2173 log_event_print_value(IO_CACHE *file, const uchar *ptr,
2174                       uint type, uint meta,
2175                       char *typestr, size_t typestr_length)
2176 {
2177   uint32 length= 0;
2178 
2179   if (type == MYSQL_TYPE_STRING)
2180   {
2181     if (meta >= 256)
2182     {
2183       uint byte0= meta >> 8;
2184       uint byte1= meta & 0xFF;
2185 
2186       if ((byte0 & 0x30) != 0x30)
2187       {
2188         /* a long CHAR() field: see #37426 */
2189         length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
2190         type= byte0 | 0x30;
2191       }
2192       else
2193         length = meta & 0xFF;
2194     }
2195     else
2196       length= meta;
2197   }
2198 
2199   switch (type) {
2200   case MYSQL_TYPE_LONG:
2201     {
2202       my_snprintf(typestr, typestr_length, "INT");
2203       if(!ptr)
2204         return my_b_printf(file, "NULL");
2205       int32 si= sint4korr(ptr);
2206       uint32 ui= uint4korr(ptr);
2207       my_b_write_sint32_and_uint32(file, si, ui);
2208       return 4;
2209     }
2210 
2211   case MYSQL_TYPE_TINY:
2212     {
2213       my_snprintf(typestr, typestr_length, "TINYINT");
2214       if(!ptr)
2215         return my_b_printf(file, "NULL");
2216       my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
2217                                   (uint) (unsigned char) *ptr);
2218       return 1;
2219     }
2220 
2221   case MYSQL_TYPE_SHORT:
2222     {
2223       my_snprintf(typestr, typestr_length, "SHORTINT");
2224       if(!ptr)
2225         return my_b_printf(file, "NULL");
2226       int32 si= (int32) sint2korr(ptr);
2227       uint32 ui= (uint32) uint2korr(ptr);
2228       my_b_write_sint32_and_uint32(file, si, ui);
2229       return 2;
2230     }
2231 
2232   case MYSQL_TYPE_INT24:
2233     {
2234       my_snprintf(typestr, typestr_length, "MEDIUMINT");
2235       if(!ptr)
2236         return my_b_printf(file, "NULL");
2237       int32 si= sint3korr(ptr);
2238       uint32 ui= uint3korr(ptr);
2239       my_b_write_sint32_and_uint32(file, si, ui);
2240       return 3;
2241     }
2242 
2243   case MYSQL_TYPE_LONGLONG:
2244     {
2245       my_snprintf(typestr, typestr_length, "LONGINT");
2246       if(!ptr)
2247         return my_b_printf(file, "NULL");
2248       char tmp[64];
2249       longlong si= sint8korr(ptr);
2250       longlong10_to_str(si, tmp, -10);
2251       my_b_printf(file, "%s", tmp);
2252       if (si < 0)
2253       {
2254         ulonglong ui= uint8korr(ptr);
2255         longlong10_to_str((longlong) ui, tmp, 10);
2256         my_b_printf(file, " (%s)", tmp);
2257       }
2258       return 8;
2259     }
2260 
2261   case MYSQL_TYPE_NEWDECIMAL:
2262     {
2263       uint precision= meta >> 8;
2264       uint decimals= meta & 0xFF;
2265       my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2266                   precision, decimals);
2267       if(!ptr)
2268         return my_b_printf(file, "NULL");
2269       uint bin_size= my_decimal_get_binary_size(precision, decimals);
2270       my_decimal dec;
2271       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2272                         precision, decimals);
2273       int len= DECIMAL_MAX_STR_LENGTH;
2274       char buff[DECIMAL_MAX_STR_LENGTH + 1];
2275       decimal2string(&dec,buff,&len, 0, 0, 0);
2276       my_b_printf(file, "%s", buff);
2277       return bin_size;
2278     }
2279 
2280   case MYSQL_TYPE_FLOAT:
2281     {
2282       my_snprintf(typestr, typestr_length, "FLOAT");
2283       if(!ptr)
2284         return my_b_printf(file, "NULL");
2285       float fl;
2286       float4get(&fl, ptr);
2287       char tmp[320];
2288       sprintf(tmp, "%-20g", (double) fl);
2289       my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2290       return 4;
2291     }
2292 
2293   case MYSQL_TYPE_DOUBLE:
2294     {
2295       strcpy(typestr, "DOUBLE");
2296       if(!ptr)
2297         return my_b_printf(file, "NULL");
2298       double dbl;
2299       float8get(&dbl, ptr);
2300       char tmp[320];
2301       sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
2302       my_b_printf(file, "%s", tmp);
2303       return 8;
2304     }
2305 
2306   case MYSQL_TYPE_BIT:
2307     {
2308       /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2309       uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2310       my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2311       if(!ptr)
2312         return my_b_printf(file, "NULL");
2313       length= (nbits + 7) / 8;
2314       my_b_write_bit(file, ptr, nbits);
2315       return length;
2316     }
2317 
2318   case MYSQL_TYPE_TIMESTAMP:
2319     {
2320       my_snprintf(typestr, typestr_length, "TIMESTAMP");
2321       if(!ptr)
2322         return my_b_printf(file, "NULL");
2323       uint32 i32= uint4korr(ptr);
2324       my_b_printf(file, "%d", i32);
2325       return 4;
2326     }
2327 
2328   case MYSQL_TYPE_TIMESTAMP2:
2329     {
2330       my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2331       if(!ptr)
2332         return my_b_printf(file, "NULL");
2333       char buf[MAX_DATE_STRING_REP_LENGTH];
2334       struct timeval tm;
2335       my_timestamp_from_binary(&tm, ptr, meta);
2336       int buflen= my_timeval_to_str(&tm, buf, meta);
2337       if (my_b_write(file, reinterpret_cast<const uchar*>(buf), buflen))
2338         return 0;
2339       return my_timestamp_binary_length(meta);
2340     }
2341 
2342   case MYSQL_TYPE_DATETIME:
2343     {
2344       my_snprintf(typestr, typestr_length, "DATETIME");
2345       if(!ptr)
2346         return my_b_printf(file, "NULL");
2347       size_t d, t;
2348       uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2349       d= static_cast<size_t>(i64 / 1000000);
2350       t= i64 % 1000000;
2351       my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
2352                   static_cast<int>(d / 10000),
2353                   static_cast<int>(d % 10000) / 100,
2354                   static_cast<int>(d % 100),
2355                   static_cast<int>(t / 10000),
2356                   static_cast<int>(t % 10000) / 100,
2357                   static_cast<int>(t % 100));
2358       return 8;
2359     }
2360 
2361   case MYSQL_TYPE_DATETIME2:
2362     {
2363       my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2364       if(!ptr)
2365         return my_b_printf(file, "NULL");
2366       char buf[MAX_DATE_STRING_REP_LENGTH];
2367       MYSQL_TIME ltime;
2368       longlong packed= my_datetime_packed_from_binary(ptr, meta);
2369       TIME_from_longlong_datetime_packed(&ltime, packed);
2370       int buflen= my_datetime_to_str(&ltime, buf, meta);
2371       my_b_write_quoted(file, (uchar *) buf, buflen);
2372       return my_datetime_binary_length(meta);
2373     }
2374 
2375   case MYSQL_TYPE_TIME:
2376     {
2377       my_snprintf(typestr, typestr_length, "TIME");
2378       if(!ptr)
2379         return my_b_printf(file, "NULL");
2380       uint32 i32= uint3korr(ptr);
2381       my_b_printf(file, "'%02d:%02d:%02d'",
2382                   i32 / 10000, (i32 % 10000) / 100, i32 % 100);
2383       return 3;
2384     }
2385 
2386   case MYSQL_TYPE_TIME2:
2387     {
2388       my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2389       if(!ptr)
2390         return my_b_printf(file, "NULL");
2391       char buf[MAX_DATE_STRING_REP_LENGTH];
2392       MYSQL_TIME ltime;
2393       longlong packed= my_time_packed_from_binary(ptr, meta);
2394       TIME_from_longlong_time_packed(&ltime, packed);
2395       int buflen= my_time_to_str(&ltime, buf, meta);
2396       my_b_write_quoted(file, (uchar *) buf, buflen);
2397       return my_time_binary_length(meta);
2398     }
2399 
2400   case MYSQL_TYPE_NEWDATE:
2401     {
2402       my_snprintf(typestr, typestr_length, "DATE");
2403       if(!ptr)
2404         return my_b_printf(file, "NULL");
2405       uint32 tmp= uint3korr(ptr);
2406       int part;
2407       char buf[11];
2408       char *pos= &buf[10];  // start from '\0' to the beginning
2409 
2410       /* Copied from field.cc */
2411       *pos--=0;					// End NULL
2412       part=(int) (tmp & 31);
2413       *pos--= (char) ('0'+part%10);
2414       *pos--= (char) ('0'+part/10);
2415       *pos--= ':';
2416       part=(int) (tmp >> 5 & 15);
2417       *pos--= (char) ('0'+part%10);
2418       *pos--= (char) ('0'+part/10);
2419       *pos--= ':';
2420       part=(int) (tmp >> 9);
2421       *pos--= (char) ('0'+part%10); part/=10;
2422       *pos--= (char) ('0'+part%10); part/=10;
2423       *pos--= (char) ('0'+part%10); part/=10;
2424       *pos=   (char) ('0'+part);
2425       my_b_printf(file , "'%s'", buf);
2426       return 3;
2427     }
2428 
2429   case MYSQL_TYPE_YEAR:
2430     {
2431       my_snprintf(typestr, typestr_length, "YEAR");
2432       if(!ptr)
2433         return my_b_printf(file, "NULL");
2434       uint32 i32= *ptr;
2435       my_b_printf(file, "%04d", i32+ 1900);
2436       return 1;
2437     }
2438 
2439   case MYSQL_TYPE_ENUM:
2440     switch (meta & 0xFF) {
2441     case 1:
2442       my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
2443       if(!ptr)
2444         return my_b_printf(file, "NULL");
2445       my_b_printf(file, "%d", (int) *ptr);
2446       return 1;
2447     case 2:
2448       {
2449         my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
2450         if(!ptr)
2451           return my_b_printf(file, "NULL");
2452         int32 i32= uint2korr(ptr);
2453         my_b_printf(file, "%d", i32);
2454         return 2;
2455       }
2456     default:
2457       my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2458       return 0;
2459     }
2460     break;
2461 
2462   case MYSQL_TYPE_SET:
2463     my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2464     if(!ptr)
2465       return my_b_printf(file, "NULL");
2466     my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2467     return meta & 0xFF;
2468 
2469   case MYSQL_TYPE_BLOB:
2470     switch (meta) {
2471     case 1:
2472       my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
2473       if(!ptr)
2474         return my_b_printf(file, "NULL");
2475       length= *ptr;
2476       my_b_write_quoted(file, ptr + 1, length);
2477       return length + 1;
2478     case 2:
2479       my_snprintf(typestr, typestr_length, "BLOB/TEXT");
2480       if(!ptr)
2481         return my_b_printf(file, "NULL");
2482       length= uint2korr(ptr);
2483       my_b_write_quoted(file, ptr + 2, length);
2484       return length + 2;
2485     case 3:
2486       my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
2487       if(!ptr)
2488         return my_b_printf(file, "NULL");
2489       length= uint3korr(ptr);
2490       my_b_write_quoted(file, ptr + 3, length);
2491       return length + 3;
2492     case 4:
2493       my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
2494       if(!ptr)
2495         return my_b_printf(file, "NULL");
2496       length= uint4korr(ptr);
2497       my_b_write_quoted(file, ptr + 4, length);
2498       return length + 4;
2499     default:
2500       my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2501       return 0;
2502     }
2503 
2504   case MYSQL_TYPE_VARCHAR:
2505   case MYSQL_TYPE_VAR_STRING:
2506     length= meta;
2507     my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
2508     if(!ptr)
2509       return my_b_printf(file, "NULL");
2510     return my_b_write_quoted_with_length(file, ptr, length);
2511 
2512   case MYSQL_TYPE_STRING:
2513     my_snprintf(typestr, typestr_length, "STRING(%d)", length);
2514     if(!ptr)
2515       return my_b_printf(file, "NULL");
2516     return my_b_write_quoted_with_length(file, ptr, length);
2517 
2518   case MYSQL_TYPE_JSON:
2519     my_snprintf(typestr, typestr_length, "JSON");
2520     if (!ptr)
2521       return my_b_printf(file, "NULL");
2522     length= uint2korr(ptr);
2523     my_b_write_quoted(file, ptr + meta, length);
2524     return length + meta;
2525 
2526   default:
2527     {
2528       char tmp[5];
2529       my_snprintf(tmp, sizeof(tmp), "%04x", meta);
2530       my_b_printf(file,
2531                   "!! Don't know how to handle column type=%d meta=%d (%s)",
2532                   type, meta, tmp);
2533     }
2534     break;
2535   }
2536   *typestr= 0;
2537   return 0;
2538 }
2539 
2540 
2541 /**
2542   Print a packed row into IO cache
2543 
2544   @param[in] file              IO cache
2545   @param[in] td                Table definition
2546   @param[in] print_event_into  Print parameters
2547   @param[in] cols_bitmap       Column bitmaps.
2548   @param[in] value             Pointer to packed row
2549   @param[in] prefix            Row's SQL clause ("SET", "WHERE", etc)
2550 
2551   @retval   - number of bytes scanned.
2552 */
2553 
2554 
2555 size_t
print_verbose_one_row(IO_CACHE * file,table_def * td,PRINT_EVENT_INFO * print_event_info,MY_BITMAP * cols_bitmap,const uchar * value,const uchar * prefix)2556 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
2557                                       PRINT_EVENT_INFO *print_event_info,
2558                                       MY_BITMAP *cols_bitmap,
2559                                       const uchar *value, const uchar *prefix)
2560 {
2561   const uchar *value0= value;
2562   const uchar *null_bits= value;
2563   uint null_bit_index= 0;
2564   char typestr[64]= "";
2565 
2566   /*
2567     Skip metadata bytes which gives the information about nullabity of master
2568     columns. Master writes one bit for each affected column.
2569    */
2570   value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
2571 
2572   my_b_printf(file, "%s", prefix);
2573 
2574   for (size_t i= 0; i < td->size(); i ++)
2575   {
2576     int is_null= (null_bits[null_bit_index / 8]
2577                   >> (null_bit_index % 8))  & 0x01;
2578 
2579     if (bitmap_is_set(cols_bitmap, i) == 0)
2580       continue;
2581 
2582     my_b_printf(file, "###   @%d=", static_cast<int>(i + 1));
2583     if (!is_null)
2584     {
2585       size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
2586       if (value + fsize > m_rows_end)
2587       {
2588         my_b_printf(file, "***Corrupted replication event was detected."
2589                     " Not printing the value***\n");
2590         value+= fsize;
2591         return 0;
2592       }
2593     }
2594     size_t size= log_event_print_value(file,is_null? NULL: value,
2595                                          td->type(i), td->field_metadata(i),
2596                                          typestr, sizeof(typestr));
2597     if (!size)
2598       return 0;
2599 
2600     if(!is_null)
2601       value+= size;
2602 
2603     if (print_event_info->verbose > 1)
2604     {
2605       my_b_printf(file, " /* ");
2606 
2607       my_b_printf(file, "%s ", typestr);
2608 
2609       my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
2610                   td->field_metadata(i),
2611                   td->maybe_null(i), is_null);
2612       my_b_printf(file, "*/");
2613     }
2614 
2615     my_b_printf(file, "\n");
2616 
2617     null_bit_index++;
2618   }
2619   return value - value0;
2620 }
2621 
2622 
2623 /**
2624   Print a row event into IO cache in human readable form (in SQL format)
2625 
2626   @param[in] file              IO cache
2627   @param[in] print_event_into  Print parameters
2628 */
print_verbose(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)2629 void Rows_log_event::print_verbose(IO_CACHE *file,
2630                                    PRINT_EVENT_INFO *print_event_info)
2631 {
2632   // Quoted length of the identifier can be twice the original length
2633   char quoted_db[1 + NAME_LEN * 2 + 2];
2634   char quoted_table[1 + NAME_LEN * 2 + 2];
2635   size_t quoted_db_len, quoted_table_len;
2636   Table_map_log_event *map;
2637   table_def *td;
2638   const char *sql_command, *sql_clause1, *sql_clause2;
2639   Log_event_type general_type_code= get_general_type_code();
2640 
2641   if (m_extra_row_data)
2642   {
2643     uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
2644     uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
2645     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
2646 
2647     my_b_printf(file, "### Extra row data format: %u, len: %u :",
2648                 m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
2649                 extra_payload_len);
2650     if (extra_payload_len)
2651     {
2652       /*
2653          Buffer for hex view of string, including '0x' prefix,
2654          2 hex chars / byte and trailing 0
2655       */
2656       const int buff_len= 2 + (256 * 2) + 1;
2657       char buff[buff_len];
2658       str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
2659                  extra_payload_len);
2660       my_b_printf(file, "%s", buff);
2661     }
2662     my_b_printf(file, "\n");
2663   }
2664 
2665   switch (general_type_code) {
2666   case binary_log::WRITE_ROWS_EVENT:
2667     sql_command= "INSERT INTO";
2668     sql_clause1= "### SET\n";
2669     sql_clause2= NULL;
2670     break;
2671   case binary_log::DELETE_ROWS_EVENT:
2672     sql_command= "DELETE FROM";
2673     sql_clause1= "### WHERE\n";
2674     sql_clause2= NULL;
2675     break;
2676   case binary_log::UPDATE_ROWS_EVENT:
2677     sql_command= "UPDATE";
2678     sql_clause1= "### WHERE\n";
2679     sql_clause2= "### SET\n";
2680     break;
2681   default:
2682     sql_command= sql_clause1= sql_clause2= NULL;
2683     assert(0); /* Not possible */
2684   }
2685 
2686   if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2687       !(td= map->create_table_def()))
2688   {
2689     char llbuff[22];
2690     my_b_printf(file, "### Row event for unknown table #%s",
2691                 llstr(m_table_id, llbuff));
2692     return;
2693   }
2694 
2695   /* If the write rows event contained no values for the AI */
2696   if (((general_type_code == binary_log::WRITE_ROWS_EVENT) &&
2697       (m_rows_buf==m_rows_end)))
2698   {
2699     my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
2700                       map->get_db_name(), map->get_table_name());
2701     goto end;
2702   }
2703 
2704   for (const uchar *value= m_rows_buf; value < m_rows_end; )
2705   {
2706     size_t length;
2707 #ifdef MYSQL_SERVER
2708     quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2709                                         map->get_db_name(), 0);
2710     quoted_table_len= my_strmov_quoted_identifier(this->thd,
2711                                                   (char *) quoted_table,
2712                                                   map->get_table_name(), 0);
2713 #else
2714     quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2715                                                map->get_db_name());
2716     quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2717                                           map->get_table_name());
2718 #endif
2719     quoted_db[quoted_db_len]= '\0';
2720     quoted_table[quoted_table_len]= '\0';
2721     my_b_printf(file, "### %s %s.%s\n",
2722                       sql_command,
2723                       quoted_db, quoted_table);
2724     /* Print the first image */
2725     if (!(length= print_verbose_one_row(file, td, print_event_info,
2726                                   &m_cols, value,
2727                                   (const uchar*) sql_clause1)))
2728       goto end;
2729     value+= length;
2730 
2731     /* Print the second image (for UPDATE only) */
2732     if (sql_clause2)
2733     {
2734       if (!(length= print_verbose_one_row(file, td, print_event_info,
2735                                       &m_cols_ai, value,
2736                                       (const uchar*) sql_clause2)))
2737         goto end;
2738       value+= length;
2739     }
2740   }
2741 
2742 end:
2743   delete td;
2744 }
2745 
2746 #ifdef MYSQL_CLIENT
free_table_map_log_event(Table_map_log_event * event)2747 void free_table_map_log_event(Table_map_log_event *event)
2748 {
2749   delete event;
2750 }
2751 #endif
2752 
print_base64(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool more)2753 void Log_event::print_base64(IO_CACHE* file,
2754                              PRINT_EVENT_INFO* print_event_info,
2755                              bool more)
2756 {
2757   const uchar *ptr= (const uchar *)temp_buf;
2758   uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2759   DBUG_ENTER("Log_event::print_base64");
2760 
2761   uint64 const tmp_str_sz= base64_needed_encoded_length((uint64) size);
2762   char *const tmp_str= (char *) my_malloc(key_memory_log_event,
2763                                           tmp_str_sz, MYF(MY_WME));
2764   if (!tmp_str) {
2765     fprintf(stderr, "\nError: Out of memory. "
2766             "Could not print correct binlog event.\n");
2767     DBUG_VOID_RETURN;
2768   }
2769 
2770   if (base64_encode(ptr, (size_t) size, tmp_str))
2771   {
2772     assert(0);
2773   }
2774 
2775   if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2776   {
2777     if (my_b_tell(file) == 0)
2778       my_b_printf(file, "\nBINLOG '\n");
2779 
2780     my_b_printf(file, "%s\n", tmp_str);
2781 
2782     if (!more)
2783       my_b_printf(file, "'%s\n", print_event_info->delimiter);
2784   }
2785 
2786   if (print_event_info->verbose)
2787   {
2788     Rows_log_event *ev= NULL;
2789     Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
2790 
2791     if (common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_UNDEF &&
2792         common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF)
2793       size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
2794 
2795     const Format_description_event fd_evt=
2796           Format_description_event(glob_description_event->binlog_version,
2797                                    server_version);
2798     switch(et)
2799     {
2800     case binary_log::TABLE_MAP_EVENT:
2801     {
2802       Table_map_log_event *map;
2803       map= new Table_map_log_event((const char*) ptr, size,
2804                                    &fd_evt);
2805       print_event_info->m_table_map.set_table(map->get_table_id(), map);
2806       break;
2807     }
2808     case binary_log::WRITE_ROWS_EVENT:
2809     case binary_log::WRITE_ROWS_EVENT_V1:
2810     {
2811       ev= new Write_rows_log_event((const char*) ptr, size,
2812                                    &fd_evt);
2813       break;
2814     }
2815     case binary_log::DELETE_ROWS_EVENT:
2816     case binary_log::DELETE_ROWS_EVENT_V1:
2817     {
2818       ev= new Delete_rows_log_event((const char*) ptr, size,
2819                                     &fd_evt);
2820       break;
2821     }
2822     case binary_log::UPDATE_ROWS_EVENT:
2823     case binary_log::UPDATE_ROWS_EVENT_V1:
2824     {
2825       ev= new Update_rows_log_event((const char*) ptr, size,
2826                                     &fd_evt);
2827       break;
2828     }
2829     default:
2830       break;
2831     }
2832 
2833     if (ev)
2834     {
2835       ev->print_verbose(&print_event_info->footer_cache, print_event_info);
2836       delete ev;
2837     }
2838   }
2839 
2840   my_free(tmp_str);
2841   DBUG_VOID_RETURN;
2842 }
2843 
2844 
2845 /*
2846   Log_event::print_timestamp()
2847 */
2848 
print_timestamp(IO_CACHE * file,time_t * ts)2849 void Log_event::print_timestamp(IO_CACHE* file, time_t *ts)
2850 {
2851   struct tm *res;
2852   /*
2853     In some Windows versions timeval.tv_sec is defined as "long",
2854     not as "time_t" and can be of a different size.
2855     Let's use a temporary time_t variable to execute localtime()
2856     with a correct argument type.
2857   */
2858   time_t ts_tmp= ts ? *ts : (ulong)common_header->when.tv_sec;
2859   DBUG_ENTER("Log_event::print_timestamp");
2860   struct tm tm_tmp;
2861   localtime_r(&ts_tmp, (res= &tm_tmp));
2862   my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2863               res->tm_year % 100,
2864               res->tm_mon+1,
2865               res->tm_mday,
2866               res->tm_hour,
2867               res->tm_min,
2868               res->tm_sec);
2869   DBUG_VOID_RETURN;
2870 }
2871 
2872 #endif /* MYSQL_CLIENT */
2873 
2874 
2875 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2876 inline Log_event::enum_skip_reason
continue_group(Relay_log_info * rli)2877 Log_event::continue_group(Relay_log_info *rli)
2878 {
2879   if (rli->slave_skip_counter == 1)
2880     return Log_event::EVENT_SKIP_IGNORE;
2881   return Log_event::do_shall_skip(rli);
2882 }
2883 
2884 /**
2885    @param end_group_sets_max_dbs  when true the group terminal event
2886                           can carry partition info, see a note below.
2887    @return true  in cases the current event
2888                  carries partition data,
2889            false otherwise
2890 
2891    @note Some events combination may force to adjust partition info.
2892          In particular BEGIN, BEGIN_LOAD_QUERY_EVENT, COMMIT
2893          where none of the events holds partitioning data
2894          causes the sequential applying of the group through
2895          assigning OVER_MAX_DBS_IN_EVENT_MTS to mts_accessed_dbs
2896          of the group terminator (e.g COMMIT query) event.
2897 */
contains_partition_info(bool end_group_sets_max_dbs)2898 bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2899 {
2900   bool res;
2901 
2902   switch (get_type_code()) {
2903   case binary_log::TABLE_MAP_EVENT:
2904   case binary_log::EXECUTE_LOAD_QUERY_EVENT:
2905     res= true;
2906 
2907     break;
2908 
2909   case binary_log::QUERY_EVENT:
2910   {
2911     Query_log_event *qev= static_cast<Query_log_event*>(this);
2912     if ((ends_group() && end_group_sets_max_dbs) ||
2913         (qev->is_query_prefix_match(STRING_WITH_LEN("XA COMMIT")) ||
2914          qev->is_query_prefix_match(STRING_WITH_LEN("XA ROLLBACK"))))
2915     {
2916       res= true;
2917       qev->mts_accessed_dbs= OVER_MAX_DBS_IN_EVENT_MTS;
2918     }
2919     else
2920       res= (!ends_group() && !starts_group()) ? true : false;
2921     break;
2922   }
2923   default:
2924     res= false;
2925   }
2926 
2927   return res;
2928 }
2929 /*
2930   SYNOPSIS
2931     This function assigns a parent ID to the job group being scheduled in parallel.
2932     It also checks if we can schedule the new event in parallel with the previous ones
2933     being executed.
2934 
2935   @param        ev log event that has to be scheduled next.
2936   @param       rli Pointer to coordinato's relay log info.
2937   @return      true if error
2938                false otherwise
2939  */
schedule_next_event(Log_event * ev,Relay_log_info * rli)2940 bool schedule_next_event(Log_event* ev, Relay_log_info* rli)
2941 {
2942   int error;
2943   // Check if we can schedule this event
2944   error= rli->current_mts_submode->schedule_next_event(rli, ev);
2945   switch (error)
2946   {
2947   case ER_MTS_CANT_PARALLEL:
2948     char llbuff[22];
2949     llstr(rli->get_event_relay_log_pos(), llbuff);
2950     my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2951     ev->get_type_str(), rli->get_event_relay_log_name(), llbuff,
2952              "The master event is logically timestamped incorrectly.");
2953     return true;
2954   case ER_MTS_INCONSISTENT_DATA:
2955     /* Don't have to do anything. */
2956     return true;
2957   case -1:
2958     /* Unable to schedule: wait_for_last_committed_trx has failed */
2959     return true;
2960   default:
2961     return false;
2962   }
2963   /* Keep compiler happy */
2964   return false;
2965 }
2966 
2967 
2968 /**
2969    The method maps the event to a Worker and return a pointer to it.
2970    Sending the event to the Worker is done by the caller.
2971 
2972    Irrespective of the type of Group marking (DB partioned or BGC) the
2973    following holds true:
2974 
2975    - recognize the beginning of a group to allocate the group descriptor
2976      and queue it;
2977    - associate an event with a Worker (which also handles possible conflicts
2978      detection and waiting for their termination);
2979    - finalize the group assignement when the group closing event is met.
2980 
2981    When parallelization mode is BGC-based the partitioning info in the event
2982    is simply ignored. Thereby association with a Worker does not require
2983    Assigned Partition Hash of the partitioned method.
2984    This method is not interested in all the taxonomy of the event group
2985    property, what we care about is the boundaries of the group.
2986 
2987    As a part of the group, an event belongs to one of the following types:
2988 
2989    B - beginning of a group of events (BEGIN query_log_event)
2990    g - mini-group representative event containing the partition info
2991       (any Table_map, a Query_log_event)
2992    p - a mini-group internal event that *p*receeding its g-parent
2993       (int_, rand_, user_ var:s)
2994    r - a mini-group internal "regular" event that follows its g-parent
2995       (Delete, Update, Write -rows)
2996    T - terminator of the group (XID, COMMIT, ROLLBACK, auto-commit query)
2997 
2998    Only the first g-event computes the assigned Worker which once
2999    is determined remains to be for the rest of the group.
3000    That is the g-event solely carries partitioning info.
3001    For B-event the assigned Worker is NULL to indicate Coordinator
3002    has not yet decided. The same applies to p-event.
3003 
3004    Notice, these is a special group consisting of optionally multiple p-events
3005    terminating with a g-event.
3006    Such case is caused by old master binlog and a few corner-cases of
3007    the current master version (todo: to fix).
3008 
3009    In case of the event accesses more than OVER_MAX_DBS the method
3010    has to ensure sure previously assigned groups to all other workers are
3011    done.
3012 
3013 
3014    @note The function updates GAQ queue directly, updates APH hash
3015          plus relocates some temporary tables from Coordinator's list into
3016          involved entries of APH through @c map_db_to_worker.
3017          There's few memory allocations commented where to be freed.
3018 
3019    @return a pointer to the Worker struct or NULL.
3020 */
3021 
get_slave_worker(Relay_log_info * rli)3022 Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
3023 {
3024   Slave_job_group group= Slave_job_group(), *ptr_group= NULL;
3025   bool is_s_event;
3026   Slave_worker *ret_worker= NULL;
3027   char llbuff[22];
3028   Slave_committed_queue *gaq= rli->gaq;
3029   DBUG_ENTER("Log_event::get_slave_worker");
3030 
3031   /* checking partioning properties and perform corresponding actions */
3032 
3033   // Beginning of a group designated explicitly with BEGIN or GTID
3034   if ((is_s_event= starts_group()) || is_gtid_event(this) ||
3035       // or DDL:s or autocommit queries possibly associated with own p-events
3036       (!rli->curr_group_seen_begin && !rli->curr_group_seen_gtid &&
3037        /*
3038          the following is a special case of B-free still multi-event group like
3039          { p_1,p_2,...,p_k, g }.
3040          In that case either GAQ is empty (the very first group is being
3041          assigned) or the last assigned group index points at one of
3042          mapped-to-a-worker.
3043        */
3044        (gaq->empty() ||
3045         gaq->get_job_group(rli->gaq->assigned_group_index)->
3046         worker_id != MTS_WORKER_UNDEF)))
3047   {
3048     if (!rli->curr_group_seen_gtid && !rli->curr_group_seen_begin)
3049     {
3050       rli->mts_groups_assigned++;
3051 
3052       rli->curr_group_isolated= FALSE;
3053       group.reset(common_header->log_pos, rli->mts_groups_assigned);
3054       // the last occupied GAQ's array index
3055       gaq->assigned_group_index= gaq->en_queue(&group);
3056       DBUG_PRINT("info",("gaq_idx= %ld  gaq->size=%ld",
3057                          gaq->assigned_group_index,
3058                          gaq->size));
3059       assert(gaq->assigned_group_index != MTS_WORKER_UNDEF);
3060       assert(gaq->assigned_group_index < gaq->size);
3061       assert(gaq->get_job_group(rli->gaq->assigned_group_index)->
3062              group_relay_log_name == NULL);
3063       assert(rli->last_assigned_worker == NULL ||
3064              !is_mts_db_partitioned(rli));
3065 
3066       if (is_s_event || is_gtid_event(this))
3067       {
3068         Slave_job_item job_item= {this, rli->get_event_relay_log_number(),
3069                                   rli->get_event_start_pos()};
3070         // B-event is appended to the Deferred Array associated with GCAP
3071         rli->curr_group_da.push_back(job_item);
3072 
3073         assert(rli->curr_group_da.size() == 1);
3074 
3075         if (starts_group())
3076         {
3077           // mark the current group as started with explicit B-event
3078           rli->mts_end_group_sets_max_dbs= true;
3079           rli->curr_group_seen_begin= true;
3080         }
3081 
3082         if (is_gtid_event(this))
3083           // mark the current group as started with explicit Gtid-event
3084           rli->curr_group_seen_gtid= true;
3085         if (schedule_next_event(this, rli))
3086         {
3087           rli->abort_slave= 1;
3088           DBUG_RETURN(NULL);
3089         }
3090         DBUG_RETURN(ret_worker);
3091       }
3092     }
3093     else
3094     {
3095       /*
3096        The block is a result of not making GTID event as group starter.
3097        TODO: Make GITD event as B-event that is starts_group() to
3098        return true.
3099       */
3100       Slave_job_item job_item= {this, rli->get_event_relay_log_number(),
3101                                 rli->get_event_relay_log_pos()};
3102 
3103       // B-event is appended to the Deferred Array associated with GCAP
3104       rli->curr_group_da.push_back(job_item);
3105       rli->curr_group_seen_begin= true;
3106       rli->mts_end_group_sets_max_dbs= true;
3107       if (!rli->curr_group_seen_gtid && schedule_next_event(this, rli))
3108       {
3109         rli->abort_slave= 1;
3110         DBUG_RETURN(NULL);
3111       }
3112 
3113       assert(rli->curr_group_da.size() == 2);
3114       assert(starts_group());
3115       DBUG_RETURN (ret_worker);
3116     }
3117     if (schedule_next_event(this, rli))
3118     {
3119       rli->abort_slave= 1;
3120       DBUG_RETURN(NULL);
3121     }
3122   }
3123 
3124   ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3125   if (!is_mts_db_partitioned(rli))
3126   {
3127     /* Get least occupied worker */
3128     ret_worker=
3129       rli->current_mts_submode->get_least_occupied_worker(rli, &rli->workers,
3130                                                           this);
3131     if (ret_worker == NULL)
3132     {
3133       /* get_least_occupied_worker may return NULL if the thread is killed */
3134       Slave_job_item job_item= {this, rli->get_event_relay_log_number(),
3135                                 rli->get_event_start_pos()};
3136       rli->curr_group_da.push_back(job_item);
3137 
3138       assert(thd->killed);
3139       DBUG_RETURN(NULL);
3140     }
3141     ptr_group->worker_id= ret_worker->id;
3142   }
3143   else if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
3144   {
3145     int i= 0;
3146     Mts_db_names mts_dbs;
3147 
3148     get_mts_dbs(&mts_dbs);
3149     /*
3150       Bug 12982188 - MTS: SBR ABORTS WITH ERROR 1742 ON LOAD DATA
3151       Logging on master can create a group with no events holding
3152       the partition info.
3153       The following assert proves there's the only reason
3154       for such group.
3155     */
3156 #ifndef NDEBUG
3157     {
3158       bool empty_group_with_gtids= rli->curr_group_seen_begin &&
3159                                    rli->curr_group_seen_gtid &&
3160                                    ends_group();
3161 
3162       bool begin_load_query_event=
3163         ((rli->curr_group_da.size() == 3 && rli->curr_group_seen_gtid) ||
3164          (rli->curr_group_da.size() == 2 && !rli->curr_group_seen_gtid)) &&
3165         (rli->curr_group_da.back().data->
3166          get_type_code() == binary_log::BEGIN_LOAD_QUERY_EVENT);
3167 
3168       bool delete_file_event=
3169         ((rli->curr_group_da.size() == 4 && rli->curr_group_seen_gtid) ||
3170          (rli->curr_group_da.size() == 3 && !rli->curr_group_seen_gtid)) &&
3171         (rli->curr_group_da.back().data->
3172          get_type_code() == binary_log::DELETE_FILE_EVENT);
3173 
3174       assert((!ends_group() ||
3175               (get_type_code() == binary_log::QUERY_EVENT &&
3176                static_cast<Query_log_event*>(this)->
3177                is_query_prefix_match(STRING_WITH_LEN("XA ROLLBACK")))) ||
3178              empty_group_with_gtids ||
3179              (rli->mts_end_group_sets_max_dbs &&
3180               (begin_load_query_event || delete_file_event)));
3181     }
3182 #endif
3183 
3184     // partioning info is found which drops the flag
3185     rli->mts_end_group_sets_max_dbs= false;
3186     ret_worker= rli->last_assigned_worker;
3187     if (mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS)
3188     {
3189       // Worker with id 0 to handle serial execution
3190       if (!ret_worker)
3191         ret_worker= rli->workers.at(0);
3192       // No need to know a possible error out of synchronization call.
3193       (void) rli->current_mts_submode->
3194         wait_for_workers_to_finish(rli, ret_worker);
3195       /*
3196         this marking is transferred further into T-event of the current group.
3197       */
3198       rli->curr_group_isolated= TRUE;
3199     }
3200 
3201     /* One run of the loop in the case of over-max-db:s */
3202     for (i= 0; i < ((mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS) ? mts_dbs.num : 1);
3203          i++)
3204     {
3205       /*
3206         The over max db:s case handled through passing to map_db_to_worker
3207         such "all" db as encoded as  the "" empty string.
3208         Note, the empty string is allocated in a large buffer
3209         to satisfy hashcmp() implementation.
3210       */
3211       const char all_db[NAME_LEN]= {0};
3212       if (!(ret_worker=
3213             map_db_to_worker(mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS ?
3214                              all_db : mts_dbs.name[i], rli,
3215                              &mts_assigned_partitions[i],
3216                              /*
3217                                todo: optimize it. Although pure
3218                                rows- event load in insensetive to the flag value
3219                              */
3220                              TRUE,
3221                              ret_worker)))
3222       {
3223         llstr(rli->get_event_relay_log_pos(), llbuff);
3224         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3225                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
3226                  "could not distribute the event to a Worker");
3227         DBUG_RETURN(ret_worker);
3228       }
3229       // all temporary tables are transferred from Coordinator in over-max case
3230       assert(mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
3231       assert(!strcmp(mts_assigned_partitions[i]->db,
3232                      mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS ?
3233                      mts_dbs.name[i] : all_db));
3234       assert(ret_worker == mts_assigned_partitions[i]->worker);
3235       assert(mts_assigned_partitions[i]->usage >= 0);
3236     }
3237 
3238     if ((ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index))->
3239         worker_id == MTS_WORKER_UNDEF)
3240     {
3241       ptr_group->worker_id= ret_worker->id;
3242 
3243       assert(ptr_group->group_relay_log_name == NULL);
3244     }
3245 
3246     assert(i == mts_dbs.num || mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS);
3247   }
3248   else
3249   {
3250     // a mini-group internal "regular" event
3251     if (rli->last_assigned_worker)
3252     {
3253       ret_worker= rli->last_assigned_worker;
3254 
3255       assert(rli->curr_group_assigned_parts.size() > 0 ||
3256              ret_worker->id == 0);
3257     }
3258     else // int_, rand_, user_ var:s, load-data events
3259     {
3260 
3261       if (!(get_type_code() == binary_log::INTVAR_EVENT ||
3262             get_type_code() == binary_log::RAND_EVENT ||
3263             get_type_code() == binary_log::USER_VAR_EVENT ||
3264             get_type_code() == binary_log::BEGIN_LOAD_QUERY_EVENT ||
3265             get_type_code() == binary_log::APPEND_BLOCK_EVENT ||
3266             get_type_code() == binary_log::DELETE_FILE_EVENT ||
3267             is_ignorable_event()))
3268       {
3269         assert(!ret_worker);
3270 
3271         llstr(rli->get_event_relay_log_pos(), llbuff);
3272         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3273                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
3274                  "the event is a part of a group that is unsupported in "
3275                  "the parallel execution mode");
3276 
3277         DBUG_RETURN(ret_worker);
3278       }
3279       /*
3280         In the logical clock scheduler any internal gets scheduled directly.
3281         That is Int_var, @User_var and Rand bypass the deferred array.
3282         Their association with relay-log physical coordinates is provided
3283         by the same mechanism that applies to a regular event.
3284       */
3285       Slave_job_item job_item= {this, rli->get_event_relay_log_number(),
3286                                 rli->get_event_start_pos()};
3287       rli->curr_group_da.push_back(job_item);
3288 
3289       assert(!ret_worker);
3290       DBUG_RETURN (ret_worker);
3291     }
3292   }
3293 
3294   assert(ret_worker);
3295   // T-event: Commit, Xid, a DDL query or dml query of B-less group.4
3296 
3297   /*
3298     Preparing event physical coordinates info for Worker before any
3299     event got scheduled so when Worker error-stopped at the first
3300     event it would be aware of where exactly in the event stream.
3301   */
3302   if (!ret_worker->master_log_change_notified)
3303   {
3304     if (!ptr_group)
3305       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3306     ptr_group->group_master_log_name=
3307       my_strdup(key_memory_log_event, rli->get_group_master_log_name(), MYF(MY_WME));
3308     ret_worker->master_log_change_notified= true;
3309 
3310     assert(!ptr_group->notified);
3311 #ifndef NDEBUG
3312     ptr_group->notified= true;
3313 #endif
3314   }
3315 
3316   /* Notify the worker about new FD */
3317   if (!ret_worker->fd_change_notified)
3318   {
3319     if (!ptr_group)
3320       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3321     /*
3322       Increment the usage counter on behalf of Worker.
3323       This avoids inadvertent FD deletion in a race case where Coordinator
3324       would install a next new FD before Worker has noticed the previous one.
3325     */
3326     rli->get_rli_description_event()->usage_counter.atomic_add(1);
3327     ptr_group->new_fd_event= rli->get_rli_description_event();
3328     ret_worker->fd_change_notified= true;
3329   }
3330 
3331   if (ends_group() ||
3332       (!rli->curr_group_seen_begin &&
3333        (get_type_code() == binary_log::QUERY_EVENT ||
3334         /*
3335           When applying an old binary log without Gtid_log_event and
3336           Anonymous_gtid_log_event, the logic of multi-threaded slave
3337           still need to require that an event (for example, Query_log_event,
3338           User_var_log_event, Intvar_log_event, and Rand_log_event) that
3339           appeared outside of BEGIN...COMMIT was treated as a transaction
3340           of its own. This was just a technicality in the code and did not
3341           cause a problem, since the event and the following Query_log_event
3342           would both be assigned to dedicated worker 0.
3343         */
3344         !rli->curr_group_seen_gtid)))
3345   {
3346     rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
3347     if (rli->curr_group_isolated)
3348       set_mts_isolate_group();
3349     if (!ptr_group)
3350       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3351 
3352     assert(ret_worker != NULL);
3353 
3354     /*
3355       The following two blocks are executed if the worker has not been
3356       notified about new relay-log or a new checkpoints.
3357       Relay-log string is freed by Coordinator, Worker deallocates
3358       strings in the checkpoint block.
3359       However if the worker exits earlier reclaiming for both happens anyway at
3360       GAQ delete.
3361     */
3362     if (!ret_worker->relay_log_change_notified)
3363     {
3364       /*
3365         Prior this event, C rotated the relay log to drop each
3366         Worker's notified flag. Now group terminating event initiates
3367         the new relay-log (where the current event is from) name
3368         delivery to Worker that will receive it in commit_positions().
3369       */
3370       assert(ptr_group->group_relay_log_name == NULL);
3371 
3372       ptr_group->group_relay_log_name= (char *)
3373         my_malloc(key_memory_log_event,
3374                   strlen(rli->
3375                          get_group_relay_log_name()) + 1, MYF(MY_WME));
3376       strcpy(ptr_group->group_relay_log_name,
3377              rli->get_event_relay_log_name());
3378 
3379       assert(ptr_group->group_relay_log_name != NULL);
3380 
3381       ret_worker->relay_log_change_notified= TRUE;
3382     }
3383 
3384     if (!ret_worker->checkpoint_notified)
3385     {
3386       if (!ptr_group)
3387         ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3388       ptr_group->checkpoint_log_name=
3389         my_strdup(key_memory_log_event, rli->get_group_master_log_name(), MYF(MY_WME));
3390       ptr_group->checkpoint_log_pos= rli->get_group_master_log_pos();
3391       ptr_group->checkpoint_relay_log_name=
3392         my_strdup(key_memory_log_event, rli->get_group_relay_log_name(), MYF(MY_WME));
3393       ptr_group->checkpoint_relay_log_pos= rli->get_group_relay_log_pos();
3394       ptr_group->shifted= ret_worker->bitmap_shifted;
3395       ret_worker->bitmap_shifted= 0;
3396       ret_worker->checkpoint_notified= TRUE;
3397     }
3398     ptr_group->checkpoint_seqno= rli->checkpoint_seqno;
3399     ptr_group->ts= common_header->when.tv_sec + (time_t) exec_time; // Seconds_behind_master related
3400     rli->checkpoint_seqno++;
3401     /*
3402       Coordinator should not use the main memroot however its not
3403       reset elsewhere either, so let's do it safe way.
3404       The main mem root is also reset by the SQL thread in at the end
3405       of applying which Coordinator does not do in this case.
3406       That concludes the memroot reset can't harm anything in SQL thread roles
3407       after Coordinator has finished its current scheduling.
3408     */
3409     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3410 
3411 #ifndef NDEBUG
3412     w_rr++;
3413 #endif
3414 
3415   }
3416 
3417   DBUG_RETURN (ret_worker);
3418 }
3419 
3420 
apply_gtid_event(Relay_log_info * rli)3421 int Log_event::apply_gtid_event(Relay_log_info *rli)
3422 {
3423   DBUG_ENTER("LOG_EVENT:apply_gtid_event");
3424 
3425   int error= 0;
3426   if (rli->curr_group_da.size() < 1)
3427     DBUG_RETURN(1);
3428 
3429   Log_event* ev= rli->curr_group_da[0].data;
3430   assert(ev->get_type_code() == binary_log::GTID_LOG_EVENT ||
3431          ev->get_type_code() ==
3432          binary_log::ANONYMOUS_GTID_LOG_EVENT);
3433 
3434   error= ev->do_apply_event(rli);
3435   /* Clean up */
3436   delete ev;
3437   rli->curr_group_da.clear();
3438   rli->curr_group_seen_gtid= false;
3439   /*
3440     Removes the job from the (G)lobal (A)ssigned (Q)ueue after
3441     applying it.
3442   */
3443   assert(rli->gaq->len > 0);
3444   Slave_job_group g= Slave_job_group();
3445   rli->gaq->de_tail(&g);
3446   /*
3447     The rli->mts_groups_assigned is increased when adding the slave job
3448     generated for the gtid into the (G)lobal (A)ssigned (Q)ueue. So we
3449     decrease it here.
3450   */
3451   rli->mts_groups_assigned--;
3452 
3453   DBUG_RETURN(error);
3454 }
3455 
3456 
3457 /**
3458    Scheduling event to execute in parallel or execute it directly.
3459    In MTS case the event gets associated with either Coordinator or a
3460    Worker.  A special case of the association is NULL when the Worker
3461    can't be decided yet.  In the single threaded sequential mode the
3462    event maps to SQL thread rli.
3463 
3464    @note in case of MTS failure Coordinator destroys all gathered
3465          deferred events.
3466 
3467    @return 0 as success, otherwise a failure.
3468 */
apply_event(Relay_log_info * rli)3469 int Log_event::apply_event(Relay_log_info *rli)
3470 {
3471   DBUG_ENTER("LOG_EVENT:apply_event");
3472   DBUG_PRINT("info", ("event_type=%s", get_type_str()));
3473   bool parallel= FALSE;
3474   enum enum_mts_event_exec_mode actual_exec_mode= EVENT_EXEC_PARALLEL;
3475   THD *rli_thd= rli->info_thd;
3476 
3477   worker= rli;
3478 
3479   if (rli->is_mts_recovery())
3480   {
3481     bool skip=
3482       bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index) &&
3483       (get_mts_execution_mode(::server_id,
3484                               rli->mts_group_status ==
3485                               Relay_log_info::MTS_IN_GROUP,
3486                               rli->current_mts_submode->get_type() ==
3487                               MTS_PARALLEL_TYPE_DB_NAME)
3488        == EVENT_EXEC_PARALLEL);
3489     if (skip)
3490     {
3491       DBUG_RETURN(0);
3492     }
3493     else
3494     {
3495       DBUG_RETURN(do_apply_event(rli));
3496     }
3497   }
3498 
3499   if (!(parallel= rli->is_parallel_exec()) ||
3500       ((actual_exec_mode=
3501         get_mts_execution_mode(::server_id,
3502                                rli->mts_group_status ==
3503                                Relay_log_info::MTS_IN_GROUP,
3504                                rli->current_mts_submode->get_type() ==
3505                                MTS_PARALLEL_TYPE_DB_NAME))
3506        != EVENT_EXEC_PARALLEL))
3507   {
3508     if (parallel)
3509     {
3510       /*
3511          There are two classes of events that Coordinator executes
3512          itself. One e.g the master Rotate requires all Workers to finish up
3513          their assignments. The other async class, e.g the slave Rotate,
3514          can't have this such synchronization because Worker might be waiting
3515          for terminal events to finish.
3516       */
3517 
3518       if (actual_exec_mode != EVENT_EXEC_ASYNC)
3519       {
3520         /*
3521           this  event does not split the current group but is indeed
3522           a separator beetwen two master's binlog therefore requiring
3523           Workers to sync.
3524         */
3525         if (rli->curr_group_da.size() > 0 &&
3526             is_mts_db_partitioned(rli) &&
3527             get_type_code() != binary_log::INCIDENT_EVENT)
3528         {
3529           char llbuff[22];
3530           /*
3531              Possible reason is a old version binlog sequential event
3532              wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var.
3533              MTS has to stop to suggest restart in the permanent sequential mode.
3534           */
3535           llstr(rli->get_event_relay_log_pos(), llbuff);
3536           my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3537                    get_type_str(), rli->get_event_relay_log_name(), llbuff,
3538                    "possible malformed group of events from an old master");
3539 
3540           /* Coordinator cant continue, it marks MTS group status accordingly */
3541           rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
3542 
3543           goto err;
3544         }
3545 
3546         if (get_type_code() == binary_log::INCIDENT_EVENT &&
3547             rli->curr_group_da.size() > 0 &&
3548             rli->current_mts_submode->get_type() ==
3549             MTS_PARALLEL_TYPE_LOGICAL_CLOCK)
3550         {
3551 #ifndef NDEBUG
3552           assert(rli->curr_group_da.size() == 1);
3553           Log_event* ev= rli->curr_group_da[0].data;
3554           assert(ev->get_type_code() == binary_log::GTID_LOG_EVENT ||
3555                  ev->get_type_code() ==
3556                  binary_log::ANONYMOUS_GTID_LOG_EVENT);
3557 #endif
3558           /*
3559             With MTS logical clock mode, when coordinator is applying an
3560             incident event, it must withdraw delegated_job increased by
3561             the incident's GTID before waiting for workers to finish.
3562             So that it can exit from mts_checkpoint_routine.
3563           */
3564           ((Mts_submode_logical_clock*)rli->current_mts_submode)->
3565             withdraw_delegated_job();
3566         }
3567         /*
3568           Marking sure the event will be executed in sequential mode.
3569         */
3570         if (rli->current_mts_submode->wait_for_workers_to_finish(rli) == -1)
3571         {
3572           // handle synchronization error
3573           rli->report(WARNING_LEVEL, 0,
3574                       "Slave worker thread has failed to apply an event. As a "
3575                       "consequence, the coordinator thread is stopping "
3576                       "execution.");
3577           DBUG_RETURN(-1);
3578         }
3579         /*
3580           Given not in-group mark the event handler can invoke checkpoint
3581           update routine in the following course.
3582         */
3583         assert(rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP
3584                || !is_mts_db_partitioned(rli));
3585 
3586         if (get_type_code() == binary_log::INCIDENT_EVENT &&
3587             rli->curr_group_da.size() > 0)
3588         {
3589           assert(rli->curr_group_da.size() == 1);
3590           /*
3591             When MTS is enabled, the incident event must be applied by the
3592             coordinator. So the coordinator applies its GTID right before
3593             applying the incident event..
3594           */
3595           int error= apply_gtid_event(rli);
3596           if (error)
3597             DBUG_RETURN(-1);
3598         }
3599 
3600 #ifndef NDEBUG
3601         /* all Workers are idle as done through wait_for_workers_to_finish */
3602         for (uint k= 0; k < rli->curr_group_da.size(); k++)
3603         {
3604           assert(!(rli->workers[k]->usage_partition));
3605           assert(!(rli->workers[k]->jobs.len));
3606         }
3607 #endif
3608       }
3609       else
3610       {
3611         assert(actual_exec_mode == EVENT_EXEC_ASYNC);
3612       }
3613     }
3614     DBUG_RETURN(do_apply_event(rli));
3615   }
3616 
3617   assert(actual_exec_mode == EVENT_EXEC_PARALLEL);
3618   assert(!(rli->curr_group_seen_begin && ends_group()) ||
3619          /*
3620            This is an empty group being processed due to gtids.
3621          */
3622          (rli->curr_group_seen_begin && rli->curr_group_seen_gtid
3623           && ends_group()) || is_mts_db_partitioned(rli) ||
3624          rli->last_assigned_worker ||
3625          /*
3626            Begin_load_query can be logged w/o db info and within
3627            Begin/Commit. That's a pattern forcing sequential
3628            applying of LOAD-DATA.
3629          */
3630          (rli->curr_group_da.back().data->
3631           get_type_code() == binary_log::BEGIN_LOAD_QUERY_EVENT) ||
3632          /*
3633            Delete_file can also be logged w/o db info and within
3634            Begin/Commit. That's a pattern forcing sequential
3635            applying of LOAD-DATA.
3636          */
3637          (rli->curr_group_da.back().data->
3638           get_type_code() == binary_log::DELETE_FILE_EVENT));
3639 
3640   worker= NULL;
3641   rli->mts_group_status= Relay_log_info::MTS_IN_GROUP;
3642 
3643   worker= (Relay_log_info*)
3644     (rli->last_assigned_worker= get_slave_worker(rli));
3645 
3646 #ifndef NDEBUG
3647   if (rli->last_assigned_worker)
3648     DBUG_PRINT("mts", ("Assigning job to worker %lu",
3649                rli->last_assigned_worker->id));
3650 #endif
3651 
3652 err:
3653   if (rli_thd->is_error() || (!worker && rli->abort_slave))
3654   {
3655     assert(!worker);
3656 
3657     /*
3658       Destroy all deferred buffered events but the current prior to exit.
3659       The current one will be deleted as an event never destined/assigned
3660       to any Worker in Coordinator's regular execution path.
3661     */
3662     for (uint k= 0; k < rli->curr_group_da.size(); k++)
3663     {
3664       Log_event *ev_buf= rli->curr_group_da[k].data;
3665       if (this != ev_buf)
3666         delete ev_buf;
3667     }
3668     rli->curr_group_da.clear();
3669   }
3670   else
3671   {
3672     assert(worker || rli->curr_group_assigned_parts.size() == 0);
3673   }
3674 
3675   DBUG_RETURN((!(rli_thd->is_error() || (!worker && rli->abort_slave)) ||
3676                DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ?
3677               0 : -1);
3678 }
3679 
3680 #endif
3681 
3682 /**************************************************************************
3683 	Query_log_event methods
3684 **************************************************************************/
3685 
3686 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3687 
3688 /**
3689   This (which is used only for SHOW BINLOG EVENTS) could be updated to
3690   print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
3691   only an information, it does not produce suitable queries to replay (for
3692   example it does not print LOAD DATA INFILE).
3693   @todo
3694     show the catalog ??
3695 */
3696 
pack_info(Protocol * protocol)3697 int Query_log_event::pack_info(Protocol *protocol)
3698 {
3699   // TODO: show the catalog ??
3700   String str_buf;
3701   // Add use `DB` to the string if required
3702   if (!(common_header->flags & LOG_EVENT_SUPPRESS_USE_F)
3703       && db && db_len)
3704   {
3705     str_buf.append("use ");
3706     append_identifier(this->thd, &str_buf, db, db_len);
3707     str_buf.append("; ");
3708   }
3709   // Add the query to the string
3710   if (query && q_len)
3711     str_buf.append(query);
3712  // persist the buffer in protocol
3713   protocol->store(str_buf.ptr(), str_buf.length(), &my_charset_bin);
3714   return 0;
3715 }
3716 #endif
3717 
3718 #ifndef MYSQL_CLIENT
3719 
3720 /**
3721   Utility function for the next method (Query_log_event::write()) .
3722 */
write_str_with_code_and_len(uchar ** dst,const char * src,size_t len,uint code)3723 static void write_str_with_code_and_len(uchar **dst, const char *src,
3724                                         size_t len, uint code)
3725 {
3726   /*
3727     only 1 byte to store the length of catalog, so it should not
3728     surpass 255
3729   */
3730   assert(len <= 255);
3731   assert(src);
3732   *((*dst)++)= code;
3733   *((*dst)++)= (uchar) len;
3734   memmove(*dst, src, len);
3735   (*dst)+= len;
3736 }
3737 
3738 
3739 /**
3740   Query_log_event::write().
3741 
3742   @note
3743     In this event we have to modify the header to have the correct
3744     EVENT_LEN_OFFSET as we don't yet know how many status variables we
3745     will print!
3746 */
3747 
write(IO_CACHE * file)3748 bool Query_log_event::write(IO_CACHE* file)
3749 {
3750   uchar buf[Binary_log_event::QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3751   uchar *start, *start_of_status;
3752   size_t event_length;
3753 
3754   if (!query)
3755     return 1;                                   // Something wrong with event
3756 
3757   /*
3758     We want to store the thread id:
3759     (- as an information for the user when he reads the binlog)
3760     - if the query uses temporary table: for the slave SQL thread to know to
3761     which master connection the temp table belongs.
3762     Now imagine we (write()) are called by the slave SQL thread (we are
3763     logging a query executed by this thread; the slave runs with
3764     --log-slave-updates). Then this query will be logged with
3765     thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
3766     the same name were created simultaneously on the master (in the masters
3767     binlog you have
3768     CREATE TEMPORARY TABLE t; (thread 1)
3769     CREATE TEMPORARY TABLE t; (thread 2)
3770     ...)
3771     then in the slave's binlog there will be
3772     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3773     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3774     which is bad (same thread id!).
3775 
3776     To avoid this, we log the thread's thread id EXCEPT for the SQL
3777     slave thread for which we log the original (master's) thread id.
3778     Now this moves the bug: what happens if the thread id on the
3779     master was 10 and when the slave replicates the query, a
3780     connection number 10 is opened by a normal client on the slave,
3781     and updates a temp table of the same name? We get a problem
3782     again. To avoid this, in the handling of temp tables (sql_base.cc)
3783     we use thread_id AND server_id.  TODO when this is merged into
3784     4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
3785     and is a session variable: that's to make mysqlbinlog work with
3786     temp tables. We probably need to introduce
3787 
3788     SET PSEUDO_SERVER_ID
3789     for mysqlbinlog in 4.1. mysqlbinlog would print:
3790     SET PSEUDO_SERVER_ID=
3791     SET PSEUDO_THREAD_ID=
3792     for each query using temp tables.
3793   */
3794   int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
3795   int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
3796   buf[Q_DB_LEN_OFFSET] = (char) db_len;
3797   int2store(buf + Q_ERR_CODE_OFFSET, error_code);
3798 
3799   /*
3800     You MUST always write status vars in increasing order of code. This
3801     guarantees that a slightly older slave will be able to parse those he
3802     knows.
3803   */
3804   start_of_status= start= buf+Binary_log_event::QUERY_HEADER_LEN;
3805   if (flags2_inited)
3806   {
3807     *start++= Q_FLAGS2_CODE;
3808     int4store(start, flags2);
3809     start+= 4;
3810   }
3811   if (sql_mode_inited)
3812   {
3813     *start++= Q_SQL_MODE_CODE;
3814     int8store(start, sql_mode);
3815     start+= 8;
3816   }
3817   if (catalog_len) // i.e. this var is inited (false for 4.0 events)
3818   {
3819     write_str_with_code_and_len(&start,
3820                                 catalog, catalog_len, Q_CATALOG_NZ_CODE);
3821     /*
3822       In 5.0.x where x<4 masters we used to store the end zero here. This was
3823       a waste of one byte so we don't do it in x>=4 masters. We change code to
3824       Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
3825       of this x>=4 master segfault (expecting a zero when there is
3826       none). Remaining compatibility problems are: the older slave will not
3827       find the catalog; but it is will not crash, and it's not an issue
3828       that it does not find the catalog as catalogs were not used in these
3829       older MySQL versions (we store it in binlog and read it from relay log
3830       but do nothing useful with it). What is an issue is that the older slave
3831       will stop processing the Q_* blocks (and jumps to the db/query) as soon
3832       as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
3833       Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
3834       various ways. Documented that you should not mix alpha/beta versions if
3835       they are not exactly the same version, with example of 5.0.3->5.0.2 and
3836       5.0.4->5.0.3. If replication is from older to new, the new will
3837       recognize Q_CATALOG_CODE and have no problem.
3838     */
3839   }
3840   if (auto_increment_increment != 1 || auto_increment_offset != 1)
3841   {
3842     *start++= Q_AUTO_INCREMENT;
3843     int2store(start, static_cast<uint16>(auto_increment_increment));
3844     int2store(start+2, static_cast<uint16>(auto_increment_offset));
3845     start+= 4;
3846   }
3847   if (charset_inited)
3848   {
3849     *start++= Q_CHARSET_CODE;
3850     memcpy(start, charset, 6);
3851     start+= 6;
3852   }
3853   if (time_zone_len)
3854   {
3855     /* In the TZ sys table, column Name is of length 64 so this should be ok */
3856     assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
3857     write_str_with_code_and_len(&start,
3858                                 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
3859   }
3860   if (lc_time_names_number)
3861   {
3862     assert(lc_time_names_number <= 0xFF);
3863     *start++= Q_LC_TIME_NAMES_CODE;
3864     int2store(start, lc_time_names_number);
3865     start+= 2;
3866   }
3867   if (charset_database_number)
3868   {
3869     assert(charset_database_number <= 0xFF);
3870     *start++= Q_CHARSET_DATABASE_CODE;
3871     int2store(start, charset_database_number);
3872     start+= 2;
3873   }
3874   if (table_map_for_update)
3875   {
3876     *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
3877     int8store(start, table_map_for_update);
3878     start+= 8;
3879   }
3880   if (master_data_written != 0)
3881   {
3882     /*
3883       Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
3884       has binlog_version<4 and the slave has binlog_version=4. See comment
3885       for master_data_written in log_event.h for details.
3886     */
3887     *start++= Q_MASTER_DATA_WRITTEN_CODE;
3888     int4store(start, static_cast<uint32>(master_data_written));
3889     start+= 4;
3890   }
3891 
3892   if (thd && thd->need_binlog_invoker())
3893   {
3894     LEX_CSTRING invoker_user;
3895     LEX_CSTRING invoker_host;
3896     memset(&invoker_user, 0, sizeof(invoker_user));
3897     memset(&invoker_host, 0, sizeof(invoker_host));
3898 
3899     if (thd->slave_thread && thd->has_invoker())
3900     {
3901       /* user will be null, if master is older than this patch */
3902       invoker_user= thd->get_invoker_user();
3903       invoker_host= thd->get_invoker_host();
3904     }
3905     else
3906     {
3907       Security_context *ctx= thd->security_context();
3908       LEX_CSTRING priv_user= ctx->priv_user();
3909       LEX_CSTRING priv_host= ctx->priv_host();
3910 
3911       invoker_user.length= priv_user.length;
3912       invoker_user.str= (char *) priv_user.str;
3913       if (priv_host.str[0] != '\0')
3914       {
3915         invoker_host.str= (char *) priv_host.str;
3916         invoker_host.length= priv_host.length;
3917       }
3918     }
3919 
3920     *start++= Q_INVOKER;
3921 
3922     /*
3923       Store user length and user. The max length of use is 16, so 1 byte is
3924       enough to store the user's length.
3925      */
3926     *start++= (uchar)invoker_user.length;
3927     memcpy(start, invoker_user.str, invoker_user.length);
3928     start+= invoker_user.length;
3929 
3930     /*
3931       Store host length and host. The max length of host is 60, so 1 byte is
3932       enough to store the host's length.
3933      */
3934     *start++= (uchar)invoker_host.length;
3935     memcpy(start, invoker_host.str, invoker_host.length);
3936     start+= invoker_host.length;
3937   }
3938 
3939   if (thd && thd->get_binlog_accessed_db_names() != NULL)
3940   {
3941     uchar dbs;
3942     *start++= Q_UPDATED_DB_NAMES;
3943 
3944     compile_time_assert(MAX_DBS_IN_EVENT_MTS <= OVER_MAX_DBS_IN_EVENT_MTS);
3945 
3946     /*
3947        In case of the number of db:s exceeds MAX_DBS_IN_EVENT_MTS
3948        no db:s is written and event will require the sequential applying on slave.
3949     */
3950     dbs=
3951       (thd->get_binlog_accessed_db_names()->elements <= MAX_DBS_IN_EVENT_MTS) ?
3952       thd->get_binlog_accessed_db_names()->elements : OVER_MAX_DBS_IN_EVENT_MTS;
3953 
3954     assert(dbs != 0);
3955 
3956     if (dbs <= MAX_DBS_IN_EVENT_MTS)
3957     {
3958       List_iterator_fast<char> it(*thd->get_binlog_accessed_db_names());
3959       char *db_name= it++;
3960       /*
3961          the single "" db in the acccessed db list corresponds to the same as
3962          exceeds MAX_DBS_IN_EVENT_MTS case, so dbs is set to the over-max.
3963       */
3964       if (dbs == 1 && !strcmp(db_name, ""))
3965         dbs= OVER_MAX_DBS_IN_EVENT_MTS;
3966       *start++= dbs;
3967       if (dbs != OVER_MAX_DBS_IN_EVENT_MTS)
3968         do
3969         {
3970           strcpy((char*) start, db_name);
3971           start += strlen(db_name) + 1;
3972         } while ((db_name= it++));
3973     }
3974     else
3975     {
3976       *start++= dbs;
3977     }
3978   }
3979 
3980   if (thd && thd->query_start_usec_used)
3981   {
3982     *start++= Q_MICROSECONDS;
3983     get_time();
3984     int3store(start, common_header->when.tv_usec);
3985     start+= 3;
3986   }
3987 
3988   if (thd && thd->binlog_need_explicit_defaults_ts == true)
3989   {
3990     *start++= Q_EXPLICIT_DEFAULTS_FOR_TIMESTAMP;
3991     *start++= thd->variables.explicit_defaults_for_timestamp;
3992   }
3993   /*
3994     NOTE: When adding new status vars, please don't forget to update
3995     the MAX_SIZE_LOG_EVENT_STATUS in log_event.h
3996 
3997     Here there could be code like
3998     if (command-line-option-which-says-"log_this_variable" && inited)
3999     {
4000     *start++= Q_THIS_VARIABLE_CODE;
4001     int4store(start, this_variable);
4002     start+= 4;
4003     }
4004   */
4005 
4006   /* Store length of status variables */
4007   status_vars_len= (uint) (start-start_of_status);
4008   assert(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
4009   int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
4010 
4011   /*
4012     Calculate length of whole event
4013     The "1" below is the \0 in the db's length
4014   */
4015   event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
4016 
4017   return (write_header(file, event_length) ||
4018           wrapper_my_b_safe_write(file, (uchar*) buf, Binary_log_event::QUERY_HEADER_LEN) ||
4019           write_post_header_for_derived(file) ||
4020           wrapper_my_b_safe_write(file, start_of_status,
4021                           (uint) (start-start_of_status)) ||
4022           wrapper_my_b_safe_write(file, db ? (uchar*) db : (uchar*)"", db_len + 1) ||
4023           wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
4024 	  write_footer(file)) ? 1 : 0;
4025 }
4026 
4027 
4028 /**
4029   The simplest constructor that could possibly work.  This is used for
4030   creating static objects that have a special meaning and are invisible
4031   to the log.
4032 */
Query_log_event()4033 Query_log_event::Query_log_event()
4034   : binary_log::Query_event(),
4035     Log_event(header(), footer()),
4036     data_buf(NULL)
4037 {}
4038 
4039 /**
4040   Creates a Query Log Event.
4041 
4042   @param thd_arg      Thread handle
4043   @param query_arg    Array of char representing the query
4044   @param query_length Size of the 'query_arg' array
4045   @param using_trans  Indicates that there are transactional changes.
4046   @param immediate    After being written to the binary log, the event
4047                       must be flushed immediately. This indirectly implies
4048                       the stmt-cache.
4049   @param suppress_use Suppress the generation of 'USE' statements
4050   @param errcode      The error code of the query
4051   @param ignore       Ignore user's statement, i.e. lex information, while
4052                       deciding which cache must be used.
4053 */
Query_log_event(THD * thd_arg,const char * query_arg,size_t query_length,bool using_trans,bool immediate,bool suppress_use,int errcode,bool ignore_cmd_internals)4054 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
4055 				 size_t query_length, bool using_trans,
4056 				 bool immediate, bool suppress_use,
4057                                  int errcode, bool ignore_cmd_internals)
4058 
4059 : binary_log::Query_event(query_arg,
4060                           thd_arg->catalog().str,
4061                           thd_arg->db().str,
4062                           query_length,
4063                           thd_arg->thread_id(),
4064                           thd_arg->variables.sql_mode,
4065                           thd_arg->variables.auto_increment_increment,
4066                           thd_arg->variables.auto_increment_offset,
4067                           thd_arg->variables.lc_time_names->number,
4068                           (ulonglong)thd_arg->table_map_for_update,
4069                           errcode,
4070                           thd_arg->db().str ? strlen(thd_arg->db().str) : 0,
4071                           thd_arg->catalog().str ? strlen(thd_arg->catalog().str) : 0),
4072   Log_event(thd_arg,
4073             (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
4074              0) |
4075             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
4076             using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
4077                           Log_event::EVENT_STMT_CACHE,
4078             Log_event::EVENT_NORMAL_LOGGING,
4079             header(), footer()),
4080   data_buf(0)
4081 {
4082   DBUG_EXECUTE_IF("debug_lock_before_query_log_event",
4083                   DBUG_SYNC_POINT("debug_lock.before_query_log_event", 10););
4084 
4085   /* save the original thread id; we already know the server id */
4086   slave_proxy_id= thd_arg->variables.pseudo_thread_id;
4087   if (query != 0)
4088     is_valid_param= true;
4089   /*
4090   exec_time calculation has changed to use the same method that is used
4091   to fill out "thd_arg->start_time"
4092   */
4093 
4094   struct timeval end_time;
4095   ulonglong micro_end_time= my_micro_time();
4096   my_micro_time_to_timeval(micro_end_time, &end_time);
4097 
4098   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
4099 
4100   /**
4101     @todo this means that if we have no catalog, then it is replicated
4102     as an existing catalog of length zero. is that safe? /sven
4103   */
4104   catalog_len = (catalog) ? strlen(catalog) : 0;
4105   /* status_vars_len is set just before writing the event */
4106   db_len = (db) ? strlen(db) : 0;
4107   if (thd_arg->variables.collation_database != thd_arg->db_charset)
4108     charset_database_number= thd_arg->variables.collation_database->number;
4109 
4110   /*
4111     We only replicate over the bits of flags2 that we need: the rest
4112     are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
4113 
4114     We also force AUTOCOMMIT=1.  Rationale (cf. BUG#29288): After
4115     fixing BUG#26395, we always write BEGIN and COMMIT around all
4116     transactions (even single statements in autocommit mode).  This is
4117     so that replication from non-transactional to transactional table
4118     and error recovery from XA to non-XA table should work as
4119     expected.  The BEGIN/COMMIT are added in log.cc. However, there is
4120     one exception: MyISAM bypasses log.cc and writes directly to the
4121     binlog.  So if autocommit is off, master has MyISAM, and slave has
4122     a transactional engine, then the slave will just see one long
4123     never-ending transaction.  The only way to bypass explicit
4124     BEGIN/COMMIT in the binlog is by using a non-transactional table.
4125     So setting AUTOCOMMIT=1 will make this work as expected.
4126 
4127     Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
4128     assume AUTOCOMMIT=1 on slave; the slave still reads the state of
4129     the autocommit flag as written by the master to the binlog. This
4130     behavior may change after WL#4162 has been implemented.
4131   */
4132   flags2= (uint32) (thd_arg->variables.option_bits &
4133                     (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
4134   assert(thd_arg->variables.character_set_client->number < 256*256);
4135   assert(thd_arg->variables.collation_connection->number < 256*256);
4136   assert(thd_arg->variables.collation_server->number < 256*256);
4137   assert(thd_arg->variables.character_set_client->mbminlen == 1);
4138   int2store(charset, thd_arg->variables.character_set_client->number);
4139   int2store(charset+2, thd_arg->variables.collation_connection->number);
4140   int2store(charset+4, thd_arg->variables.collation_server->number);
4141   if (thd_arg->time_zone_used)
4142   {
4143     /*
4144       Note that our event becomes dependent on the Time_zone object
4145       representing the time zone. Fortunately such objects are never deleted
4146       or changed during mysqld's lifetime.
4147     */
4148     time_zone_len= thd_arg->variables.time_zone->get_name()->length();
4149     time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
4150   }
4151   else
4152     time_zone_len= 0;
4153 
4154   /*
4155     In what follows, we define in which cache, trx-cache or stmt-cache,
4156     this Query Log Event will be written to.
4157 
4158     If ignore_cmd_internals is defined, we rely on the is_trans flag to
4159     choose the cache and this is done in the base class Log_event. False
4160     means that the stmt-cache will be used and upon statement commit/rollback
4161     the cache will be flushed to disk. True means that the trx-cache will
4162     be used and upon transaction commit/rollback the cache will be flushed
4163     to disk.
4164 
4165     If set immediate cache is defined, for convenience, we automatically
4166     use the stmt-cache. This mean that the statement will be written
4167     to the stmt-cache and immediately flushed to disk without waiting
4168     for a commit/rollback notification.
4169 
4170     For example, the cluster/ndb captures a request to execute a DDL
4171     statement and synchronously propagate it to all available MySQL
4172     servers. Unfortunately, the current protocol assumes that the
4173     generated events are immediately written to diks and does not check
4174     for commit/rollback.
4175 
4176     Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are
4177     generated and in this case the statements have the immediate flag
4178     set because there is no commit/rollback.
4179 
4180     If the immediate flag is not set, the decision on the cache is based
4181     on the current statement and the flag is_trans, which indicates if
4182     a transactional engine was updated.
4183 
4184     Statements are classifed as row producers (i.e. can_generate_row_events())
4185     or non-row producers. Non-row producers, DDL in general, are treated
4186     as the immediate flag was set and for convenience are written to the
4187     stmt-cache and immediately flushed to disk.
4188 
4189     Row producers are handled in general according to the is_trans flag.
4190     False means that the stmt-cache will be used and upon statement
4191     commit/rollback the cache will be flushed to disk. True means that the
4192     trx-cache will be used and upon transaction commit/rollback the cache
4193     will be flushed to disk.
4194 
4195     Unfortunately, there are exceptions to this non-row and row producer
4196     rules:
4197 
4198       . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not
4199         have the flag is_trans set because there is no updated engine but
4200         must be written to the trx-cache.
4201 
4202       . SET If auto-commit is on, it must not go through a cache.
4203 
4204       . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY
4205         must be handled as row producer.
4206 
4207       . DROP TABLE is classfied as non-row producer but DROP TEMPORARY
4208         must be handled as row producer.
4209 
4210     Finally, some statements that does not have the flag is_trans set may
4211     be written to the trx-cache based on the following criteria:
4212 
4213       . updated both a transactional and a non-transactional engine (i.e.
4214         stmt_has_updated_trans_table()).
4215 
4216       . accessed both a transactional and a non-transactional engine and
4217         is classified as unsafe (i.e. is_mixed_stmt_unsafe()).
4218 
4219       . is executed within a transaction and previously a transactional
4220         engine was updated and the flag binlog_direct_non_trans_update
4221         is set.
4222   */
4223   if (ignore_cmd_internals)
4224     return;
4225 
4226   /*
4227     TRUE defines that the trx-cache must be used.
4228   */
4229   bool cmd_can_generate_row_events= FALSE;
4230   /*
4231     TRUE defines that the trx-cache must be used.
4232   */
4233   bool cmd_must_go_to_trx_cache= FALSE;
4234 
4235   LEX *lex= thd->lex;
4236   if (!immediate)
4237   {
4238     switch (lex->sql_command)
4239     {
4240       case SQLCOM_DROP_TABLE:
4241         cmd_can_generate_row_events= lex->drop_temporary &&
4242                                      thd->in_multi_stmt_transaction_mode();
4243       break;
4244       case SQLCOM_CREATE_TABLE:
4245         cmd_must_go_to_trx_cache= lex->select_lex->item_list.elements &&
4246                                   thd->is_current_stmt_binlog_format_row();
4247         cmd_can_generate_row_events=
4248           ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
4249             thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache;
4250         break;
4251       case SQLCOM_SET_OPTION:
4252         if (lex->autocommit)
4253           cmd_can_generate_row_events= cmd_must_go_to_trx_cache= FALSE;
4254         else
4255           cmd_can_generate_row_events= TRUE;
4256         break;
4257       case SQLCOM_RELEASE_SAVEPOINT:
4258       case SQLCOM_ROLLBACK_TO_SAVEPOINT:
4259       case SQLCOM_SAVEPOINT:
4260       case SQLCOM_XA_PREPARE:
4261         cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE;
4262         break;
4263       default:
4264         cmd_can_generate_row_events=
4265           sqlcom_can_generate_row_events(thd->lex->sql_command);
4266         break;
4267     }
4268   }
4269 
4270   if (cmd_can_generate_row_events)
4271   {
4272     cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
4273     if (cmd_must_go_to_trx_cache ||
4274         stmt_has_updated_trans_table(thd->get_transaction()->ha_trx_info(Transaction_ctx::STMT)) ||
4275         thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
4276                                        thd->variables.binlog_direct_non_trans_update,
4277                                        trans_has_updated_trans_table(thd),
4278                                        thd->tx_isolation) ||
4279         (!thd->variables.binlog_direct_non_trans_update && trans_has_updated_trans_table(thd)))
4280     {
4281       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
4282       event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
4283     }
4284     else
4285     {
4286       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
4287       event_cache_type= Log_event::EVENT_STMT_CACHE;
4288     }
4289   }
4290   else
4291   {
4292     event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
4293     event_cache_type= Log_event::EVENT_STMT_CACHE;
4294   }
4295 
4296   assert(event_cache_type != Log_event::EVENT_INVALID_CACHE);
4297   assert(event_logging_type != Log_event::EVENT_INVALID_LOGGING);
4298   DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %llu",
4299                      (ulong) flags2, (ulonglong) sql_mode));
4300 }
4301 #endif /* MYSQL_CLIENT */
4302 
4303 
4304 /**
4305   This is used by the SQL slave thread to prepare the event before execution.
4306 */
Query_log_event(const char * buf,uint event_len,const Format_description_event * description_event,Log_event_type event_type)4307 Query_log_event::Query_log_event(const char* buf, uint event_len,
4308                                  const Format_description_event
4309                                  *description_event,
4310                                  Log_event_type event_type)
4311   :binary_log::Query_event(buf, event_len, description_event, event_type),
4312    Log_event(header(), footer())
4313 {
4314   DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
4315   slave_proxy_id= thread_id;
4316   exec_time= query_exec_time;
4317 
4318   ulong buf_len= catalog_len + 1 +
4319                   time_zone_len + 1 +
4320                   user_len + 1 +
4321                   host_len + 1 +
4322                   data_len + 1;
4323 #if !defined(MYSQL_CLIENT)
4324   buf_len+= sizeof(size_t)/*for db_len */ + db_len + 1 + QUERY_CACHE_FLAGS_SIZE;
4325 #endif
4326 
4327   if (!(data_buf = (Log_event_header::Byte*) my_malloc(key_memory_log_event,
4328                                                        buf_len, MYF(MY_WME))))
4329     DBUG_VOID_RETURN;
4330   /*
4331     The data buffer is used by the slave SQL thread while applying
4332     the event. The catalog, time_zone)str, user, host, db, query
4333     are pointers to this data_buf. The function call below, points these
4334     const pointers to the data buffer.
4335   */
4336   if (!(fill_data_buf(data_buf, buf_len)))
4337     DBUG_VOID_RETURN;
4338 
4339   if (query != 0 && q_len > 0)
4340     is_valid_param= true;
4341 
4342   /**
4343     The buffer contains the following:
4344     +--------+-----------+------+------+---------+----+-------+
4345     | catlog | time_zone | user | host | db name | \0 | Query |
4346     +--------+-----------+------+------+---------+----+-------+
4347 
4348     To support the query cache we append the following buffer to the above
4349     +-------+----------------------------------------+-------+
4350     |db len | uninitiatlized space of size of db len | FLAGS |
4351     +-------+----------------------------------------+-------+
4352 
4353     The area of buffer starting from Query field all the way to the end belongs
4354     to the Query buffer and its structure is described in alloc_query() in
4355     sql_parse.cc
4356 
4357     We append the db length at the end of the buffer. This will be used by
4358     Query_cache::send_result_to_client() in case the query cache is On.
4359    */
4360 #if !defined(MYSQL_CLIENT)
4361   size_t db_length= db_len;
4362   memcpy(data_buf + query_data_written, &db_length, sizeof(size_t));
4363 #endif
4364   DBUG_VOID_RETURN;
4365 }
4366 
4367 
4368 #ifdef MYSQL_CLIENT
4369 /**
4370   Query_log_event::print().
4371 
4372   @todo
4373     print the catalog ??
4374 */
print_query_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)4375 void Query_log_event::print_query_header(IO_CACHE* file,
4376 					 PRINT_EVENT_INFO* print_event_info)
4377 {
4378   // TODO: print the catalog ??
4379   char buff[48], *end;  // Enough for "SET TIMESTAMP=1305535348.123456"
4380   char quoted_id[1+ 2*FN_REFLEN+ 2];
4381   size_t quoted_len= 0;
4382   bool different_db= true;
4383   uint32 tmp;
4384 
4385   if (!print_event_info->short_form)
4386   {
4387     print_header(file, print_event_info, FALSE);
4388     my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
4389                 get_type_str(), (ulong) thread_id, (ulong) exec_time,
4390                 error_code);
4391   }
4392 
4393   if ((common_header->flags & LOG_EVENT_SUPPRESS_USE_F))
4394   {
4395     if (!is_trans_keyword())
4396       print_event_info->db[0]= '\0';
4397   }
4398   else if (db)
4399   {
4400 #ifdef MYSQL_SERVER
4401     quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
4402 #else
4403     quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
4404 #endif
4405     quoted_id[quoted_len]= '\0';
4406     different_db= memcmp(print_event_info->db, db, db_len + 1);
4407     if (different_db)
4408       memcpy(print_event_info->db, db, db_len + 1);
4409     if (db[0] && different_db)
4410       my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
4411   }
4412 
4413   end= int10_to_str((long)common_header->when.tv_sec,
4414                     my_stpcpy(buff,"SET TIMESTAMP="),10);
4415   if (common_header->when.tv_usec)
4416     end+= sprintf(end, ".%06d", (int) common_header->when.tv_usec);
4417   end= my_stpcpy(end, print_event_info->delimiter);
4418   *end++='\n';
4419   assert(end < buff + sizeof(buff));
4420   MY_ATTRIBUTE((unused)) int write_res=
4421     my_b_write(file, (uchar*) buff, (uint) (end-buff));
4422   assert(write_res == 0);
4423   if ((!print_event_info->thread_id_printed ||
4424        ((common_header->flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
4425         thread_id != print_event_info->thread_id)))
4426   {
4427     // If --short-form, print deterministic value instead of pseudo_thread_id.
4428     my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
4429                 short_form ? 999999999 : (ulong)thread_id,
4430                 print_event_info->delimiter);
4431     print_event_info->thread_id= thread_id;
4432     print_event_info->thread_id_printed= 1;
4433   }
4434 
4435   /*
4436     If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
4437     print (remember we don't produce mixed relay logs so there cannot be
4438     5.0 events before that one so there is nothing to reset).
4439   */
4440   if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
4441   {
4442     /* tmp is a bitmask of bits which have changed. */
4443     if (likely(print_event_info->flags2_inited))
4444       /* All bits which have changed */
4445       tmp= (print_event_info->flags2) ^ flags2;
4446     else /* that's the first Query event we read */
4447     {
4448       print_event_info->flags2_inited= 1;
4449       tmp= ~((uint32)0); /* all bits have changed */
4450     }
4451 
4452     if (unlikely(tmp)) /* some bits have changed */
4453     {
4454       bool need_comma= 0;
4455       my_b_printf(file, "SET ");
4456       print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
4457                        "@@session.foreign_key_checks", &need_comma);
4458       print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
4459                        "@@session.sql_auto_is_null", &need_comma);
4460       print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
4461                        "@@session.unique_checks", &need_comma);
4462       print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
4463                        "@@session.autocommit", &need_comma);
4464       my_b_printf(file,"%s\n", print_event_info->delimiter);
4465       print_event_info->flags2= flags2;
4466     }
4467   }
4468 
4469   /*
4470     Now the session variables;
4471     it's more efficient to pass SQL_MODE as a number instead of a
4472     comma-separated list.
4473     FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
4474     variables (they have no global version; they're not listed in
4475     sql_class.h), The tests below work for pure binlogs or pure relay
4476     logs. Won't work for mixed relay logs but we don't create mixed
4477     relay logs (that is, there is no relay log with a format change
4478     except within the 3 first events, which mysqlbinlog handles
4479     gracefully). So this code should always be good.
4480   */
4481 
4482   if (likely(sql_mode_inited) &&
4483       (unlikely(print_event_info->sql_mode != sql_mode ||
4484                 !print_event_info->sql_mode_inited)))
4485   {
4486     my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
4487                 (ulong)sql_mode, print_event_info->delimiter);
4488     print_event_info->sql_mode= sql_mode;
4489     print_event_info->sql_mode_inited= 1;
4490   }
4491   if (print_event_info->auto_increment_increment != auto_increment_increment ||
4492       print_event_info->auto_increment_offset != auto_increment_offset)
4493   {
4494     my_b_printf(file,"SET @@session.auto_increment_increment=%u, @@session.auto_increment_offset=%u%s\n",
4495                 auto_increment_increment,auto_increment_offset,
4496                 print_event_info->delimiter);
4497     print_event_info->auto_increment_increment= auto_increment_increment;
4498     print_event_info->auto_increment_offset=    auto_increment_offset;
4499   }
4500 
4501   /* TODO: print the catalog when we feature SET CATALOG */
4502 
4503   if (likely(charset_inited) &&
4504       (unlikely(!print_event_info->charset_inited ||
4505                 memcmp(print_event_info->charset, charset, 6))))
4506   {
4507     char *charset_p= charset; // Avoid type-punning warning.
4508     CHARSET_INFO *cs_info= get_charset(uint2korr(charset_p), MYF(MY_WME));
4509     if (cs_info)
4510     {
4511       /* for mysql client */
4512       my_b_printf(file, "/*!\\C %s */%s\n",
4513                   cs_info->csname, print_event_info->delimiter);
4514     }
4515     my_b_printf(file,"SET "
4516                 "@@session.character_set_client=%d,"
4517                 "@@session.collation_connection=%d,"
4518                 "@@session.collation_server=%d"
4519                 "%s\n",
4520                 uint2korr(charset_p),
4521                 uint2korr(charset+2),
4522                 uint2korr(charset+4),
4523                 print_event_info->delimiter);
4524     memcpy(print_event_info->charset, charset, 6);
4525     print_event_info->charset_inited= 1;
4526   }
4527   if (time_zone_len)
4528   {
4529     if (memcmp(print_event_info->time_zone_str,
4530                time_zone_str, time_zone_len+1))
4531     {
4532       my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
4533                   time_zone_str, print_event_info->delimiter);
4534       memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
4535     }
4536   }
4537   if (lc_time_names_number != print_event_info->lc_time_names_number)
4538   {
4539     my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
4540                 lc_time_names_number, print_event_info->delimiter);
4541     print_event_info->lc_time_names_number= lc_time_names_number;
4542   }
4543   if (charset_database_number != print_event_info->charset_database_number)
4544   {
4545     if (charset_database_number)
4546       my_b_printf(file, "SET @@session.collation_database=%d%s\n",
4547                   charset_database_number, print_event_info->delimiter);
4548     else
4549       my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
4550                   print_event_info->delimiter);
4551     print_event_info->charset_database_number= charset_database_number;
4552   }
4553   if (explicit_defaults_ts != TERNARY_UNSET)
4554     my_b_printf(file, "SET @@session.explicit_defaults_for_timestamp=%d%s\n",
4555                 explicit_defaults_ts == TERNARY_OFF? 0 : 1,
4556                 print_event_info->delimiter);
4557 }
4558 
4559 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)4560 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4561 {
4562   IO_CACHE *const head= &print_event_info->head_cache;
4563 
4564   /**
4565     reduce the size of io cache so that the write function is called
4566     for every call to my_b_write().
4567    */
4568   DBUG_EXECUTE_IF ("simulate_file_write_error",
4569                    {head->write_pos= head->write_end- 500;});
4570   print_query_header(head, print_event_info);
4571   MY_ATTRIBUTE((unused)) int write_res=
4572     my_b_write(head, (uchar*)query, q_len);
4573   assert(write_res == 0);
4574   my_b_printf(head, "\n%s\n", print_event_info->delimiter);
4575 }
4576 #endif /* MYSQL_CLIENT */
4577 
4578 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4579 
4580 /**
4581    Associating slave Worker thread to a subset of temporary tables.
4582 
4583    @param thd_arg THD instance pointer
4584    @param rli     Relay_log_info of the worker
4585 */
attach_temp_tables_worker(THD * thd_arg,const Relay_log_info * rli)4586 void Query_log_event::attach_temp_tables_worker(THD *thd_arg,
4587                                                 const Relay_log_info* rli)
4588 {
4589   rli->current_mts_submode->attach_temp_tables(thd_arg, rli, this);
4590 }
4591 
4592 /**
4593    Dissociating slave Worker thread from its thd->temporary_tables
4594    to possibly update the involved entries of db-to-worker hash
4595    with new values of temporary_tables.
4596 
4597    @param thd_arg THD instance pointer
4598    @param rli     relay log info of the worker thread
4599 */
detach_temp_tables_worker(THD * thd_arg,const Relay_log_info * rli)4600 void Query_log_event::detach_temp_tables_worker(THD *thd_arg,
4601                                                 const Relay_log_info *rli)
4602 {
4603   rli->current_mts_submode->detach_temp_tables(thd_arg, rli, this);
4604 }
4605 
4606 /*
4607   Query_log_event::do_apply_event()
4608 */
do_apply_event(Relay_log_info const * rli)4609 int Query_log_event::do_apply_event(Relay_log_info const *rli)
4610 {
4611   return do_apply_event(rli, query, q_len);
4612 }
4613 
4614 /*
4615   is_silent_error
4616 
4617   Return true if the thread has an error which should be
4618   handled silently
4619 */
4620 
is_silent_error(THD * thd)4621 static bool is_silent_error(THD* thd)
4622 {
4623   DBUG_ENTER("is_silent_error");
4624   Diagnostics_area::Sql_condition_iterator it=
4625     thd->get_stmt_da()->sql_conditions();
4626   const Sql_condition *err;
4627   while ((err= it++))
4628   {
4629     DBUG_PRINT("info", ("has condition %d %s", err->mysql_errno(),
4630                         err->message_text()));
4631     switch (err->mysql_errno())
4632     {
4633     case ER_SLAVE_SILENT_RETRY_TRANSACTION:
4634     {
4635       DBUG_RETURN(true);
4636     }
4637     default:
4638       break;
4639     }
4640   }
4641   DBUG_RETURN(false);
4642 }
4643 
4644 /**
4645   @todo
4646   Compare the values of "affected rows" around here. Something
4647   like:
4648   @code
4649      if ((uint32) affected_in_event != (uint32) affected_on_slave)
4650      {
4651      sql_print_error("Slave: did not get the expected number of affected \
4652      rows running query from master - expected %d, got %d (this numbers \
4653      should have matched modulo 4294967296).", 0, ...);
4654      thd->query_error = 1;
4655      }
4656   @endcode
4657   We may also want an option to tell the slave to ignore "affected"
4658   mismatch. This mismatch could be implemented with a new ER_ code, and
4659   to ignore it you would use --slave-skip-errors...
4660 */
do_apply_event(Relay_log_info const * rli,const char * query_arg,size_t q_len_arg)4661 int Query_log_event::do_apply_event(Relay_log_info const *rli,
4662                                       const char *query_arg, size_t q_len_arg)
4663 {
4664   DBUG_ENTER("Query_log_event::do_apply_event");
4665   int expected_error,actual_error= 0;
4666   HA_CREATE_INFO db_options;
4667 
4668   DBUG_PRINT("info", ("query=%s, q_len_arg=%lu",
4669                       query, static_cast<unsigned long>(q_len_arg)));
4670 
4671   /*
4672     Colleagues: please never free(thd->catalog) in MySQL. This would
4673     lead to bugs as here thd->catalog is a part of an alloced block,
4674     not an entire alloced block (see
4675     Query_log_event::do_apply_event()). Same for thd->db().str.  Thank
4676     you.
4677   */
4678 
4679   if (catalog_len)
4680   {
4681     LEX_CSTRING catalog_lex_cstr= { catalog, catalog_len};
4682     thd->set_catalog(catalog_lex_cstr);
4683   }
4684   else
4685     thd->set_catalog(EMPTY_CSTR);
4686 
4687   size_t valid_len;
4688   bool len_error;
4689   bool is_invalid_db_name= validate_string(system_charset_info, db, db_len,
4690                                            &valid_len, &len_error);
4691 
4692   DBUG_PRINT("debug",("is_invalid_db_name= %s, valid_len=%zu, len_error=%s",
4693                       is_invalid_db_name ? "true" : "false",
4694                       valid_len,
4695                       len_error ? "true" : "false"));
4696 
4697   if (is_invalid_db_name || len_error)
4698   {
4699     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4700                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4701                 "Invalid database name in Query event.");
4702     thd->is_slave_error= true;
4703     goto end;
4704   }
4705 
4706   set_thd_db(thd, db, db_len);
4707 
4708   /*
4709     Setting the character set and collation of the current database thd->db.
4710    */
4711   load_db_opt_by_name(thd, thd->db().str, &db_options);
4712   if (db_options.default_table_charset)
4713     thd->db_charset= db_options.default_table_charset;
4714   thd->variables.auto_increment_increment= auto_increment_increment;
4715   thd->variables.auto_increment_offset=    auto_increment_offset;
4716   if (explicit_defaults_ts != TERNARY_UNSET)
4717     thd->variables.explicit_defaults_for_timestamp=
4718       explicit_defaults_ts == TERNARY_OFF? 0 : 1;
4719 
4720   /*
4721     todo: such cleanup should not be specific to Query event and therefore
4722           is preferable at a common with other event pre-execution point
4723   */
4724   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4725   if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock != NULL)
4726   {
4727     /*
4728       Cleaning-up the last statement context:
4729       the terminal event of the current statement flagged with
4730       STMT_END_F got filtered out in ndb circular replication.
4731     */
4732     int error;
4733     char llbuff[22];
4734     if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
4735     {
4736       const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
4737                   "Error in cleaning up after an event preceding the commit; "
4738                   "the group log file/position: %s %s",
4739                   const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
4740                   llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
4741                         llbuff));
4742     }
4743     /*
4744       Executing a part of rli->stmt_done() logics that does not deal
4745       with group position change. The part is redundant now but is
4746       future-change-proof addon, e.g if COMMIT handling will start checking
4747       invariants like IN_STMT flag must be off at committing the transaction.
4748     */
4749     const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
4750     const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
4751   }
4752   else
4753   {
4754     const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
4755   }
4756 
4757   {
4758     thd->set_time(&(common_header->when));
4759     thd->set_query(query_arg, q_len_arg);
4760     thd->set_query_for_display(query_arg, q_len_arg);
4761     thd->set_query_id(next_query_id());
4762     thd->variables.pseudo_thread_id= thread_id;		// for temp tables
4763     attach_temp_tables_worker(thd, rli);
4764     DBUG_PRINT("query",("%s", thd->query().str));
4765 
4766     if (ignored_error_code((expected_error= error_code)) ||
4767 	!unexpected_error_code(expected_error))
4768     {
4769       if (flags2_inited)
4770         /*
4771           all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
4772           must take their value from flags2.
4773         */
4774         thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
4775       /*
4776         else, we are in a 3.23/4.0 binlog; we previously received a
4777         Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
4778         nothing to do.
4779       */
4780       /*
4781         We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
4782         slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
4783         force us to ignore the dir too. Imagine you are a ring of machines, and
4784         one has a disk problem so that you temporarily need
4785         MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
4786         elsewhere (you don't want all slaves to start ignoring the dirs).
4787       */
4788       if (sql_mode_inited)
4789         thd->variables.sql_mode=
4790           (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
4791                        (sql_mode & ~(ulonglong) MODE_NO_DIR_IN_CREATE));
4792       if (charset_inited)
4793       {
4794         if (rli->cached_charset_compare(charset))
4795         {
4796           char *charset_p= charset; // Avoid type-punning warning.
4797           /* Verify that we support the charsets found in the event. */
4798           if (!(thd->variables.character_set_client=
4799                 get_charset(uint2korr(charset_p), MYF(MY_WME))) ||
4800               !(thd->variables.collation_connection=
4801                 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
4802               !(thd->variables.collation_server=
4803                 get_charset(uint2korr(charset+4), MYF(MY_WME))))
4804           {
4805             /*
4806               We updated the thd->variables with nonsensical values (0). Let's
4807               set them to something safe (i.e. which avoids crash), and we'll
4808               stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
4809               ignore this error).
4810             */
4811             set_slave_thread_default_charset(thd, rli);
4812             goto compare_errors;
4813           }
4814           thd->update_charset(); // for the charset change to take effect
4815           /*
4816             We cannot ask for parsing a statement using a character set
4817             without state_maps (parser internal data).
4818           */
4819           if (!thd->variables.character_set_client->state_maps)
4820           {
4821             rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4822                         ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4823                         "character_set cannot be parsed");
4824             thd->is_slave_error= true;
4825             goto end;
4826           }
4827           /*
4828             Reset thd->query_string.cs to the newly set value.
4829             Note, there is a small flaw here. For a very short time frame
4830             if the new charset is different from the old charset and
4831             if another thread executes "SHOW PROCESSLIST" after
4832             the above thd->set_query() and before this thd->set_query(),
4833             and if the current query has some non-ASCII characters,
4834             the another thread may see some '?' marks in the PROCESSLIST
4835             result. This should be acceptable now. This is a reminder
4836             to fix this if any refactoring happens here sometime.
4837           */
4838           thd->set_query(query_arg, q_len_arg);
4839           thd->reset_query_for_display();
4840         }
4841       }
4842       if (time_zone_len)
4843       {
4844         String tmp(time_zone_str, time_zone_len, &my_charset_bin);
4845         if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
4846         {
4847           my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
4848           thd->variables.time_zone= global_system_variables.time_zone;
4849           goto compare_errors;
4850         }
4851       }
4852       if (lc_time_names_number)
4853       {
4854         if (!(thd->variables.lc_time_names=
4855               my_locale_by_number(lc_time_names_number)))
4856         {
4857           my_printf_error(ER_UNKNOWN_ERROR,
4858                       "Unknown locale: '%d'", MYF(0), lc_time_names_number);
4859           thd->variables.lc_time_names= &my_locale_en_US;
4860           goto compare_errors;
4861         }
4862       }
4863       else
4864         thd->variables.lc_time_names= &my_locale_en_US;
4865       if (charset_database_number)
4866       {
4867         CHARSET_INFO *cs;
4868         if (!(cs= get_charset(charset_database_number, MYF(0))))
4869         {
4870           char buf[20];
4871           int10_to_str((int) charset_database_number, buf, -10);
4872           my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
4873           goto compare_errors;
4874         }
4875         thd->variables.collation_database= cs;
4876       }
4877       else
4878         thd->variables.collation_database= thd->db_charset;
4879 
4880       thd->table_map_for_update= (table_map)table_map_for_update;
4881 
4882       LEX_STRING user_lex= LEX_STRING();
4883       LEX_STRING host_lex= LEX_STRING();
4884       if (user)
4885       {
4886         user_lex.str= const_cast<char*>(user);
4887         user_lex.length= strlen(user);
4888       }
4889       if (host)
4890       {
4891         host_lex.str= const_cast<char*>(host);
4892         host_lex.length= strlen(host);
4893       }
4894       thd->set_invoker(&user_lex, &host_lex);
4895       /*
4896         Flag if we need to rollback the statement transaction on
4897         slave if it by chance succeeds.
4898         If we expected a non-zero error code and get nothing and,
4899         it is a concurrency issue or ignorable issue, effects
4900         of the statement should be rolled back.
4901       */
4902       if (expected_error &&
4903           (ignored_error_code(expected_error) ||
4904            concurrency_error_code(expected_error)))
4905       {
4906         thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
4907       }
4908       /* Execute the query (note that we bypass dispatch_command()) */
4909       Parser_state parser_state;
4910       if (!parser_state.init(thd, thd->query().str, thd->query().length))
4911       {
4912         parser_state.m_input.m_has_digest = true;
4913         assert(thd->m_digest == NULL);
4914         thd->m_digest= & thd->m_digest_state;
4915         assert(thd->m_statement_psi == NULL);
4916         thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
4917                                                     stmt_info_rpl.m_key,
4918                                                     thd->db().str,
4919                                                     thd->db().length,
4920                                                     thd->charset(), NULL);
4921         THD_STAGE_INFO(thd, stage_starting);
4922 
4923         if (thd->m_digest != NULL)
4924           thd->m_digest->reset(thd->m_token_array, max_digest_length);
4925 
4926         mysql_parse(thd, &parser_state, true);
4927 
4928         /*
4929           Transaction isolation level of pure row based replicated transactions
4930           can be optimized to ISO_READ_COMMITTED by the applier when applying
4931           the Gtid_log_event.
4932 
4933           If we are applying a statement other than transaction control ones
4934           after having optimized the transactions isolation level, we must warn
4935           about the non-standard situation we have found.
4936         */
4937         if (is_sbr_logging_format() &&
4938             thd->variables.tx_isolation > ISO_READ_COMMITTED &&
4939             thd->tx_isolation == ISO_READ_COMMITTED)
4940         {
4941           String message;
4942           message.append("The isolation level for the current transaction "
4943                          "was changed to READ_COMMITTED based on the "
4944                          "assumption that it had only row events and was "
4945                          "not mixed with statements. "
4946                          "However, an unexpected statement was found in "
4947                          "the middle of the transaction."
4948                          "Query: '");
4949           message.append(thd->query().str);
4950           message.append("'");
4951           rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4952                       ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4953                       message.c_ptr());
4954           thd->is_slave_error= true;
4955           goto end;
4956         }
4957 
4958         if (sqlcom_can_generate_row_events(thd->lex->sql_command) &&
4959             thd->get_row_count_func() > 0) {
4960           for (TABLE_LIST* tbl= thd->lex->query_tables; tbl;
4961                tbl= tbl->next_global) {
4962             if (!tbl->is_placeholder() && tbl->table->file) {
4963               if (!tbl->table->file->rpl_can_handle_stm_event()) {
4964                 String message;
4965                 message.append("Masters binlog format is not ROW and storage "
4966                                "engine can not handle non-ROW events at this "
4967                                "time. Table: '");
4968                 message.append(tbl->get_db_name());
4969                 message.append(".");
4970                 message.append(tbl->get_table_name());
4971                 message.append("' Query: '");
4972                 message.append(thd->query().str);
4973                 message.append("'");
4974                 rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4975                             ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4976                             message.c_ptr());
4977                 thd->is_slave_error= true;
4978                 goto end;
4979               }
4980             }
4981           }
4982         }
4983 
4984         /* Finalize server status flags after executing a statement. */
4985         thd->update_server_status();
4986         log_slow_statement(thd);
4987       }
4988 
4989       thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
4990 
4991       /*
4992         Resetting the enable_slow_log thd variable.
4993 
4994         We need to reset it back to the opt_log_slow_slave_statements
4995         value after the statement execution (and slow logging
4996         is done). It might have changed if the statement was an
4997         admin statement (in which case, down in mysql_parse execution
4998         thd->enable_slow_log is set to the value of
4999         opt_log_slow_admin_statements).
5000       */
5001       thd->enable_slow_log= opt_log_slow_slave_statements;
5002     }
5003     else
5004     {
5005       /*
5006         The query got a really bad error on the master (thread killed etc),
5007         which could be inconsistent. Parse it to test the table names: if the
5008         replicate-*-do|ignore-table rules say "this query must be ignored" then
5009         we exit gracefully; otherwise we warn about the bad error and tell DBA
5010         to check/fix it.
5011       */
5012       if (mysql_test_parse_for_slave(thd))
5013         clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
5014       else
5015       {
5016         rli->report(ERROR_LEVEL, ER_ERROR_ON_MASTER, ER(ER_ERROR_ON_MASTER),
5017                     expected_error, thd->query().str);
5018         thd->is_slave_error= 1;
5019       }
5020       goto end;
5021     }
5022 
5023     /* If the query was not ignored, it is printed to the general log */
5024     if (!thd->is_error() ||
5025         thd->get_stmt_da()->mysql_errno() != ER_SLAVE_IGNORED_TABLE)
5026     {
5027       /*
5028         Log the rewritten query if the query was rewritten
5029         and the option to log raw was not set.
5030 
5031         There is an assumption here. We assume that query log
5032         events can never have multi-statement queries, thus the
5033         parsed statement is the same as the raw one.
5034       */
5035       if (opt_general_log_raw || thd->rewritten_query().length() == 0)
5036         query_logger.general_log_write(thd, COM_QUERY, thd->query().str,
5037                                        thd->query().length);
5038       else
5039         query_logger.general_log_write(thd, COM_QUERY,
5040                                        thd->rewritten_query().ptr(),
5041                                        thd->rewritten_query().length());
5042     }
5043 
5044 compare_errors:
5045     /* Parser errors shall be ignored when (GTID) skipping statements */
5046     if (thd->is_error() &&
5047         thd->get_stmt_da()->mysql_errno() == ER_PARSE_ERROR &&
5048         gtid_pre_statement_checks(thd) == GTID_STATEMENT_SKIP)
5049     {
5050       thd->get_stmt_da()->reset_diagnostics_area();
5051     }
5052     /*
5053       In the slave thread, we may sometimes execute some DROP / * 40005
5054       TEMPORARY * / TABLE that come from parts of binlogs (likely if we
5055       use RESET SLAVE or CHANGE MASTER TO), while the temporary table
5056       has already been dropped. To ignore such irrelevant "table does
5057       not exist errors", we silently clear the error if TEMPORARY was used.
5058     */
5059     if (thd->lex->sql_command == SQLCOM_DROP_TABLE &&
5060         thd->lex->drop_temporary &&
5061         thd->is_error() &&
5062         thd->get_stmt_da()->mysql_errno() == ER_BAD_TABLE_ERROR &&
5063         !expected_error)
5064       thd->get_stmt_da()->reset_diagnostics_area();
5065     /*
5066       If we expected a non-zero error code, and we don't get the same error
5067       code, and it should be ignored or is related to a concurrency issue.
5068     */
5069     actual_error= thd->is_error() ? thd->get_stmt_da()->mysql_errno() : 0;
5070     DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
5071                        expected_error, actual_error));
5072 
5073     /*
5074       If a statement with expected error is received on slave and if the
5075       statement is not filtered on the slave, only then compare the expected
5076       error with the actual error that happened on slave.
5077     */
5078     if ((expected_error && rpl_filter->db_ok(thd->db().str) &&
5079          expected_error != actual_error &&
5080          !concurrency_error_code(expected_error)) &&
5081         !ignored_error_code(actual_error) &&
5082         !ignored_error_code(expected_error))
5083     {
5084       if (!ignored_error_code(ER_INCONSISTENT_ERROR))
5085       {
5086         rli->report(ERROR_LEVEL, ER_INCONSISTENT_ERROR,
5087                     ER(ER_INCONSISTENT_ERROR),
5088                     ER_THD(thd, expected_error), expected_error,
5089                     (actual_error ?
5090                      thd->get_stmt_da()->message_text() :
5091                      "no error"),
5092                     actual_error, print_slave_db_safe(db), query_arg);
5093         thd->is_slave_error= 1;
5094       }
5095       else
5096       {
5097         rli->report(INFORMATION_LEVEL, actual_error,
5098                     "The actual error and expected error on slave are"
5099                     " different that will result in ER_INCONSISTENT_ERROR but"
5100                     " that is passed as an argument to slave_skip_errors so no"
5101                     " error is thrown. "
5102                     "The expected error was %s with, Error_code: %d. "
5103                     "The actual error is %s with ",
5104                     ER(expected_error), expected_error,
5105                     thd->get_stmt_da()->message_text());
5106         clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
5107       }
5108     }
5109     /*
5110       If we get the same error code as expected and it is not a concurrency
5111       issue, or should be ignored.
5112     */
5113     else if ((expected_error == actual_error &&
5114               !concurrency_error_code(expected_error)) ||
5115              ignored_error_code(actual_error))
5116     {
5117       DBUG_PRINT("info",("error ignored"));
5118       if (actual_error && ignored_error_code(actual_error))
5119       {
5120         if (actual_error == ER_SLAVE_IGNORED_TABLE)
5121         {
5122           if (!slave_ignored_err_throttle.log())
5123             rli->report(INFORMATION_LEVEL, actual_error,
5124                         "Could not execute %s event. Detailed error: %s;"
5125                         " Error log throttle is enabled. This error will not be"
5126                         " displayed for next %lu secs. It will be suppressed",
5127                         get_type_str(), thd->get_stmt_da()->message_text(),
5128                         (window_size / 1000000));
5129         }
5130         else
5131           rli->report(INFORMATION_LEVEL, actual_error,
5132                       "Could not execute %s event. Detailed error: %s;",
5133                       get_type_str(), thd->get_stmt_da()->message_text());
5134       }
5135       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
5136       thd->killed= THD::NOT_KILLED;
5137     }
5138     /*
5139       Other cases: mostly we expected no error and get one.
5140     */
5141     else if (thd->is_slave_error || thd->is_fatal_error)
5142     {
5143       if (!is_silent_error(thd))
5144       {
5145         rli->report(ERROR_LEVEL, actual_error,
5146                     "Error '%s' on query. Default database: '%s'. Query: '%s'",
5147                     (actual_error ?
5148                      thd->get_stmt_da()->message_text() :
5149                      "unexpected success or fatal error"),
5150                     print_slave_db_safe(thd->db().str), query_arg);
5151       }
5152       thd->is_slave_error= 1;
5153     }
5154 
5155     /*
5156       TODO: compare the values of "affected rows" around here. Something
5157       like:
5158       if ((uint32) affected_in_event != (uint32) affected_on_slave)
5159       {
5160       sql_print_error("Slave: did not get the expected number of affected \
5161       rows running query from master - expected %d, got %d (this numbers \
5162       should have matched modulo 4294967296).", 0, ...);
5163       thd->is_slave_error = 1;
5164       }
5165       We may also want an option to tell the slave to ignore "affected"
5166       mismatch. This mismatch could be implemented with a new ER_ code, and
5167       to ignore it you would use --slave-skip-errors...
5168 
5169       To do the comparison we need to know the value of "affected" which the
5170       above mysql_parse() computed. And we need to know the value of
5171       "affected" in the master's binlog. Both will be implemented later. The
5172       important thing is that we now have the format ready to log the values
5173       of "affected" in the binlog. So we can release 5.0.0 before effectively
5174       logging "affected" and effectively comparing it.
5175     */
5176   } /* End of if (db_ok(... */
5177 
5178   {
5179     /**
5180       The following failure injecion works in cooperation with tests
5181       setting @@global.debug= 'd,stop_slave_middle_group'.
5182       The sql thread receives the killed status and will proceed
5183       to shutdown trying to finish incomplete events group.
5184     */
5185 
5186     // TODO: address the middle-group killing in MTS case
5187 
5188     DBUG_EXECUTE_IF("stop_slave_middle_group",
5189                     if (strcmp("COMMIT", query) != 0 &&
5190                         strcmp("BEGIN", query) != 0)
5191                     {
5192                       if (thd->get_transaction()->cannot_safely_rollback(
5193                           Transaction_ctx::SESSION))
5194                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;
5195                     };);
5196   }
5197 
5198 end:
5199 
5200   if (thd->temporary_tables)
5201     detach_temp_tables_worker(thd, rli);
5202   /*
5203     Probably we have set thd->query, thd->db, thd->catalog to point to places
5204     in the data_buf of this event. Now the event is going to be deleted
5205     probably, so data_buf will be freed, so the thd->... listed above will be
5206     pointers to freed memory.
5207     So we must set them to 0, so that those bad pointers values are not later
5208     used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
5209     don't suffer from these assignments to 0 as DROP TEMPORARY
5210     TABLE uses the db.table syntax.
5211   */
5212   thd->set_catalog(NULL_CSTR);
5213   thd->set_db(NULL_CSTR);                 /* will free the current database */
5214   thd->reset_query();
5215   thd->lex->sql_command= SQLCOM_END;
5216   DBUG_PRINT("info", ("end: query= 0"));
5217 
5218   /* Mark the statement completed. */
5219   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
5220   thd->reset_rewritten_query();
5221   thd->m_statement_psi= NULL;
5222   thd->m_digest= NULL;
5223 
5224   /*
5225     Prevent rewritten query from getting "stuck" in SHOW PROCESSLIST,
5226     and performance_schema.threads.
5227   */
5228   thd->reset_rewritten_query();
5229   thd->reset_query_for_display();
5230 
5231   /*
5232     As a disk space optimization, future masters will not log an event for
5233     LAST_INSERT_ID() if that function returned 0 (and thus they will be able
5234     to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
5235     variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
5236     resetting below we are ready to support that.
5237   */
5238   thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
5239   thd->first_successful_insert_id_in_prev_stmt= 0;
5240   thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5241   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5242   DBUG_RETURN(thd->is_slave_error);
5243 }
5244 
do_update_pos(Relay_log_info * rli)5245 int Query_log_event::do_update_pos(Relay_log_info *rli)
5246 {
5247   int ret= Log_event::do_update_pos(rli);
5248 
5249   DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
5250        if (!strcmp("COMMIT", query))
5251        {
5252          sql_print_information("Crashing crash_after_commit_and_update_pos.");
5253          rli->flush_info(true);
5254          ha_flush_logs(0);
5255          DBUG_SUICIDE();
5256        }
5257   );
5258 
5259   return ret;
5260 }
5261 
5262 
5263 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5264 Query_log_event::do_shall_skip(Relay_log_info *rli)
5265 {
5266   DBUG_ENTER("Query_log_event::do_shall_skip");
5267   DBUG_PRINT("debug", ("query: %s; q_len: %d", query, static_cast<int>(q_len)));
5268   assert(query && q_len > 0);
5269 
5270   if (rli->slave_skip_counter > 0)
5271   {
5272     if (strcmp("BEGIN", query) == 0)
5273     {
5274       thd->variables.option_bits|= OPTION_BEGIN;
5275       DBUG_RETURN(Log_event::continue_group(rli));
5276     }
5277 
5278     if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
5279     {
5280       thd->variables.option_bits&= ~OPTION_BEGIN;
5281       DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5282     }
5283   }
5284   Log_event::enum_skip_reason ret= Log_event::do_shall_skip(rli);
5285   DBUG_RETURN(ret);
5286 }
5287 
5288 #endif
5289 
5290 /**
5291    Return the query string pointer (and its size) from a Query log event
5292    using only the event buffer (we don't instantiate a Query_log_event
5293    object for this).
5294 
5295    @param buf               Pointer to the event buffer.
5296    @param length            The size of the event buffer.
5297    @param description_event The description event of the master which logged
5298                             the event.
5299    @param[out] query        The pointer to receive the query pointer.
5300 
5301    @return                  The size of the query.
5302 */
get_query(const char * buf,size_t length,const Format_description_log_event * fd_event,char ** query)5303 size_t Query_log_event::get_query(const char *buf, size_t length,
5304                                   const Format_description_log_event *fd_event,
5305                                   char** query)
5306 {
5307   assert((Log_event_type)buf[EVENT_TYPE_OFFSET] ==
5308          binary_log::QUERY_EVENT);
5309 
5310   char db_len;                                  /* size of db name */
5311   uint status_vars_len= 0;                      /* size of status_vars */
5312   size_t qlen;                                  /* size of the query */
5313   int checksum_size= 0;                         /* size of trailing checksum */
5314   const char *end_of_query;
5315 
5316   uint common_header_len= fd_event->common_header_len;
5317   uint query_header_len= fd_event->post_header_len[binary_log::QUERY_EVENT-1];
5318 
5319   /* Error if the event content is too small */
5320   if (length < (common_header_len + query_header_len))
5321     goto err;
5322 
5323   /* Skip the header */
5324   buf+= common_header_len;
5325 
5326   /* Check if there are status variables in the event */
5327   if ((query_header_len - QUERY_HEADER_MINIMAL_LEN) > 0)
5328   {
5329     status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
5330   }
5331 
5332   /* Check if the event has trailing checksum */
5333   if (fd_event->common_footer->checksum_alg != binary_log::BINLOG_CHECKSUM_ALG_OFF)
5334     checksum_size= 4;
5335 
5336   db_len= (uchar)buf[Q_DB_LEN_OFFSET];
5337 
5338   /* Error if the event content is too small */
5339   if (length < (common_header_len + query_header_len +
5340                 db_len + 1 + status_vars_len + checksum_size))
5341     goto err;
5342 
5343   *query= (char *)buf + query_header_len + db_len + 1 + status_vars_len;
5344 
5345   /* Calculate the query length */
5346   end_of_query= buf + (length - common_header_len) - /* we skipped the header */
5347                 checksum_size;
5348   qlen= end_of_query - *query;
5349   return qlen;
5350 
5351 err:
5352   *query= NULL;
5353   return 0;
5354 }
5355 
5356 
5357 /**************************************************************************
5358 	Start_log_event_v3 methods
5359 **************************************************************************/
5360 #ifndef MYSQL_CLIENT
Start_log_event_v3()5361 Start_log_event_v3::Start_log_event_v3()
5362   : binary_log::Start_event_v3(),
5363     Log_event(header(), footer(), Log_event::EVENT_INVALID_CACHE,
5364               Log_event::EVENT_INVALID_LOGGING)
5365 {
5366   is_valid_param= true;
5367 }
5368 #endif
5369 
5370 /*
5371   Start_log_event_v3::pack_info()
5372 */
5373 
5374 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5375 int Start_log_event_v3::pack_info(Protocol *protocol)
5376 {
5377   char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5378   pos= my_stpcpy(buf, "Server ver: ");
5379   pos= my_stpcpy(pos, server_version);
5380   pos= my_stpcpy(pos, ", Binlog ver: ");
5381   pos= int10_to_str(binlog_version, pos, 10);
5382   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5383   return 0;
5384 }
5385 #endif
5386 
5387 
5388 /*
5389   Start_log_event_v3::print()
5390 */
5391 
5392 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5393 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5394 {
5395   DBUG_ENTER("Start_log_event_v3::print");
5396 
5397   IO_CACHE *const head= &print_event_info->head_cache;
5398 
5399   if (!print_event_info->short_form)
5400   {
5401     print_header(head, print_event_info, FALSE);
5402     my_b_printf(head, "\tStart: binlog v %d, server v %s created ",
5403                 binlog_version, server_version);
5404     print_timestamp(head, NULL);
5405     if (created)
5406       my_b_printf(head," at startup");
5407     my_b_printf(head, "\n");
5408     if (common_header->flags & LOG_EVENT_BINLOG_IN_USE_F)
5409       my_b_printf(head, "# Warning: this binlog is either in use or was not "
5410                   "closed properly.\n");
5411   }
5412 
5413   if (is_relay_log_event())
5414   {
5415     my_b_printf(head, "# This Format_description_event appears in a relay log "
5416                 "and was generated by the slave thread.\n");
5417     DBUG_VOID_RETURN;
5418   }
5419 
5420   if (!is_artificial_event() && created)
5421   {
5422 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5423     /*
5424       This is for mysqlbinlog: like in replication, we want to delete the stale
5425       tmp files left by an unclean shutdown of mysqld (temporary tables)
5426       and rollback unfinished transaction.
5427       Probably this can be done with RESET CONNECTION (syntax to be defined).
5428     */
5429     my_b_printf(head,"RESET CONNECTION%s\n", print_event_info->delimiter);
5430 #else
5431     my_b_printf(head,"ROLLBACK%s\n", print_event_info->delimiter);
5432 #endif
5433   }
5434   if (temp_buf &&
5435       print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5436       !print_event_info->short_form)
5437   {
5438     if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
5439       my_b_printf(head, "BINLOG '\n");
5440     print_base64(head, print_event_info, FALSE);
5441     print_event_info->printed_fd_event= TRUE;
5442 
5443     /*
5444       If --skip-gtids is given, the server when it replays the output
5445       should generate a new GTID if gtid_mode=ON.  However, when the
5446       server reads the base64-encoded Format_description_log_event, it
5447       will cleverly detect that this is a binlog to be replayed, and
5448       act a little bit like the replication thread, in the following
5449       sense: if the thread does not see any 'SET GTID_NEXT' statement,
5450       it will assume the binlog was created by an old server and try
5451       to preserve transactions as anonymous.  This is the opposite of
5452       what we want when passing the --skip-gtids flag, so therefore we
5453       output the following statement.
5454 
5455       The behavior where the client preserves transactions following a
5456       Format_description_log_event as anonymous was introduced in
5457       5.6.16.
5458     */
5459     if (print_event_info->skip_gtids)
5460       my_b_printf(head, "/*!50616 SET @@SESSION.GTID_NEXT='AUTOMATIC'*/%s\n",
5461                   print_event_info->delimiter);
5462   }
5463   DBUG_VOID_RETURN;
5464 }
5465 #endif /* MYSQL_CLIENT */
5466 
5467 /*
5468   Start_log_event_v3::Start_log_event_v3()
5469 */
5470 
Start_log_event_v3(const char * buf,uint event_len,const Format_description_event * description_event)5471 Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
5472                                        const Format_description_event
5473                                        *description_event)
5474 : binary_log::Start_event_v3(buf, event_len, description_event),
5475   Log_event(header(), footer())
5476 {
5477   is_valid_param= server_version[0] != 0;
5478   if (event_len < (uint)description_event->common_header_len +
5479       ST_COMMON_HEADER_LEN_OFFSET)
5480   {
5481     server_version[0]= 0;
5482     return;
5483   }
5484   buf+= description_event->common_header_len;
5485   binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
5486   memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
5487 	 ST_SERVER_VER_LEN);
5488   // prevent overrun if log is corrupted on disk
5489   server_version[ST_SERVER_VER_LEN-1]= 0;
5490   created= uint4korr(buf+ST_CREATED_OFFSET);
5491   dont_set_created= 1;
5492 }
5493 
5494 
5495 /*
5496   Start_log_event_v3::write()
5497 */
5498 
5499 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5500 bool Start_log_event_v3::write(IO_CACHE* file)
5501 {
5502   char buff[Binary_log_event::START_V3_HEADER_LEN];
5503   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5504   memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5505   if (!dont_set_created)
5506     created= get_time();
5507   int4store(buff + ST_CREATED_OFFSET, static_cast<uint32>(created));
5508   return (write_header(file, sizeof(buff)) ||
5509           wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
5510 	  write_footer(file));
5511 }
5512 #endif
5513 
5514 
5515 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5516 
5517 /**
5518   Start_log_event_v3::do_apply_event() .
5519   The master started
5520 
5521     IMPLEMENTATION
5522     - To handle the case where the master died without having time to write
5523     DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
5524     TODO), we clean up all temporary tables that we got, if we are sure we
5525     can (see below).
5526 
5527   @todo
5528     - Remove all active user locks.
5529     Guilhem 2003-06: this is true but not urgent: the worst it can cause is
5530     the use of a bit of memory for a user lock which will not be used
5531     anymore. If the user lock is later used, the old one will be released. In
5532     other words, no deadlock problem.
5533 */
5534 
do_apply_event(Relay_log_info const * rli)5535 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
5536 {
5537   DBUG_ENTER("Start_log_event_v3::do_apply_event");
5538   int error= 0;
5539   switch (binlog_version)
5540   {
5541   case 3:
5542   case 4:
5543     /*
5544       This can either be 4.x (then a Start_log_event_v3 is only at master
5545       startup so we are sure the master has restarted and cleared his temp
5546       tables; the event always has 'created'>0) or 5.0 (then we have to test
5547       'created').
5548     */
5549     if (created)
5550     {
5551       error= close_temporary_tables(thd);
5552       cleanup_load_tmpdir();
5553     }
5554     else
5555     {
5556       /*
5557         Set all temporary tables thread references to the current thread
5558         as they may point to the "old" SQL slave thread in case of its
5559         restart.
5560       */
5561       TABLE *table;
5562       for (table= thd->temporary_tables; table; table= table->next)
5563         table->in_use= thd;
5564     }
5565     break;
5566 
5567     /*
5568        Now the older formats; in that case load_tmpdir is cleaned up by the I/O
5569        thread.
5570     */
5571   case 1:
5572     if (strncmp(rli->get_rli_description_event()->server_version,
5573                 "3.23.57",7) >= 0 && created)
5574     {
5575       /*
5576         Can distinguish, based on the value of 'created': this event was
5577         generated at master startup.
5578       */
5579       error= close_temporary_tables(thd);
5580     }
5581     /*
5582       Otherwise, can't distinguish a Start_log_event generated at
5583       master startup and one generated by master FLUSH LOGS, so cannot
5584       be sure temp tables have to be dropped. So do nothing.
5585     */
5586     break;
5587   default:
5588     /*
5589       This case is not expected. It can be either an event corruption or an
5590       unsupported binary log version.
5591     */
5592     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5593                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5594                 "Binlog version not supported");
5595     DBUG_RETURN(1);
5596   }
5597   DBUG_RETURN(error);
5598 }
5599 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5600 
Start_encryption_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5601 Start_encryption_log_event::Start_encryption_log_event(
5602     const char* buf, uint event_len,
5603     const Format_description_log_event* description_event)
5604  : Binary_log_event(&buf, description_event->binlog_version,
5605                     description_event->server_version),
5606    Log_event(header(), footer())
5607 {
5608   if ((int)event_len ==
5609      (int)LOG_EVENT_MINIMAL_HEADER_LEN + (int)Start_encryption_log_event::get_data_size())
5610   {
5611     crypto_scheme = *(uchar*)buf;
5612     key_version = uint4korr(buf + Binlog_crypt_data::BINLOG_CRYPTO_SCHEME_LENGTH);
5613     memcpy(nonce,
5614            buf + Binlog_crypt_data::BINLOG_CRYPTO_SCHEME_LENGTH + Binlog_crypt_data::BINLOG_KEY_VERSION_LENGTH,
5615            Binlog_crypt_data::BINLOG_NONCE_LENGTH);
5616   }
5617   else
5618     crypto_scheme= ~0; // invalid
5619 
5620   is_valid_param= crypto_scheme == 1;
5621 }
5622 
5623 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5624 int Start_encryption_log_event::do_apply_event(Relay_log_info const *rli)
5625 {
5626   return rli->get_rli_description_event()->start_decryption(this);
5627 }
5628 
do_update_pos(Relay_log_info * rli)5629 int Start_encryption_log_event::do_update_pos(Relay_log_info *rli)
5630 {
5631   /*
5632     Master never sends Start_encryption_log_event, any SELE that a slave
5633     might see was created locally in MYSQL_BIN_LOG::open() on the slave
5634   */
5635   rli->inc_event_relay_log_pos();
5636   return 0;
5637 }
5638 
5639 #endif
5640 
5641 #ifndef MYSQL_SERVER
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5642 void Start_encryption_log_event::print(FILE* file,
5643                                        PRINT_EVENT_INFO* print_event_info)
5644 {
5645     // Need 2 characters per one hex + 2 for 0x + 1 for \0
5646     char nonce_buf[Binlog_crypt_data::BINLOG_NONCE_LENGTH * 2 + 2 + 1];
5647     str_to_hex(nonce_buf, reinterpret_cast<char*>(nonce),
5648                Binlog_crypt_data::BINLOG_NONCE_LENGTH);
5649 
5650     IO_CACHE *const head= &print_event_info->head_cache;
5651     print_header(head, print_event_info, FALSE);
5652     my_b_printf(head,"Encryption scheme: %d", crypto_scheme);
5653     my_b_printf(head,", key_version: %d", key_version);
5654     my_b_printf(head,", nonce: %s ", nonce_buf);
5655     my_b_printf(head,"\n# The rest of the binlog is encrypted!\n");
5656 }
5657 #endif
5658 
5659 
5660 
5661 /***************************************************************************
5662        Format_description_log_event methods
5663 ****************************************************************************/
5664 
5665 /**
5666   Format_description_log_event 1st ctor.
5667 
5668     Ctor. Can be used to create the event to write to the binary log (when the
5669     server starts or when FLUSH LOGS), or to create artificial events to parse
5670     binlogs from MySQL 3.23 or 4.x.
5671     When in a client, only the 2nd use is possible.
5672 
5673   @param binlog_version         the binlog version for which we want to build
5674                                 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
5675                                 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
5676                                 old 4.0 (binlog version 2) is not supported;
5677                                 it should not be used for replication with
5678                                 5.0.
5679   @param server_ver             a string containing the server version.
5680 */
5681 
5682 Format_description_log_event::
Format_description_log_event(uint8_t binlog_ver,const char * server_ver)5683 Format_description_log_event(uint8_t binlog_ver, const char* server_ver)
5684 : binary_log::Start_event_v3(binary_log::FORMAT_DESCRIPTION_EVENT),
5685   Format_description_event(binlog_ver,  (binlog_ver <= 3 || server_ver != 0) ?
5686                            server_ver : ::server_version)
5687 {
5688   is_valid_param= header_is_valid() && version_is_valid();
5689   common_header->type_code= binary_log::FORMAT_DESCRIPTION_EVENT;
5690   /*
5691    We here have the possibility to simulate a master before we changed
5692    the table map id to be stored in 6 bytes: when it was stored in 4
5693    bytes (=> post_header_len was 6). This is used to test backward
5694    compatibility.
5695    This code can be removed after a few months (today is Dec 21st 2005),
5696    when we know that the 4-byte masters are not deployed anymore (check
5697    with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
5698    too.
5699   */
5700   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5701                   post_header_len[binary_log::TABLE_MAP_EVENT-1]=
5702                   post_header_len[binary_log::WRITE_ROWS_EVENT_V1-1]=
5703                   post_header_len[binary_log::UPDATE_ROWS_EVENT_V1-1]=
5704                   post_header_len[binary_log::DELETE_ROWS_EVENT_V1-1]= 6;);
5705   reset_crypto();
5706 }
5707 
5708 
5709 /**
5710   The problem with this constructor is that the fixed header may have a
5711   length different from this version, but we don't know this length as we
5712   have not read the Format_description_log_event which says it, yet. This
5713   length is in the post-header of the event, but we don't know where the
5714   post-header starts.
5715 
5716   So this type of event HAS to:
5717   - either have the header's length at the beginning (in the header, at a
5718   fixed position which will never be changed), not in the post-header. That
5719   would make the header be "shifted" compared to other events.
5720   - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
5721   versions, so that we know for sure.
5722 
5723   I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
5724   it is sent before Format_description_log_event).
5725 */
5726 
5727 Format_description_log_event::
Format_description_log_event(const char * buf,uint event_len,const Format_description_event * description_event)5728 Format_description_log_event(const char* buf, uint event_len,
5729                              const Format_description_event
5730                              *description_event)
5731   : binary_log::Start_event_v3(buf, event_len, description_event),
5732     Format_description_event(buf, event_len, description_event),
5733     Start_log_event_v3(buf, event_len, description_event)
5734 {
5735   is_valid_param= header_is_valid() && version_is_valid();
5736   common_header->type_code= binary_log::FORMAT_DESCRIPTION_EVENT;
5737 
5738   /*
5739    We here have the possibility to simulate a master of before we changed
5740    the table map id to be stored in 6 bytes: when it was stored in 4
5741    bytes (=> post_header_len was 6). This is used to test backward
5742    compatibility.
5743  */
5744   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5745                   post_header_len[binary_log::TABLE_MAP_EVENT-1]=
5746                   post_header_len[binary_log::WRITE_ROWS_EVENT_V1-1]=
5747                   post_header_len[binary_log::UPDATE_ROWS_EVENT_V1-1]=
5748                   post_header_len[binary_log::DELETE_ROWS_EVENT_V1-1]= 6;);
5749   reset_crypto();
5750 }
5751 
start_decryption(Start_encryption_log_event * sele)5752 bool Format_description_log_event::start_decryption(Start_encryption_log_event* sele)
5753 {
5754   assert(!crypto_data.is_enabled());
5755 
5756   if (!sele->is_valid())
5757     return true;
5758   if (crypto_data.init(sele->crypto_scheme, sele->key_version, sele->nonce))
5759   {
5760     sql_print_error("Failed to fetch percona_binlog key (version %u) from keyring and thus "
5761                      "failed to initialize binlog encryption.", sele->key_version);
5762     return true;
5763   }
5764   return false;
5765 }
5766 
5767 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5768 bool Format_description_log_event::write(IO_CACHE* file)
5769 {
5770   bool ret;
5771   bool no_checksum;
5772   /*
5773     We don't call Start_log_event_v3::write() because this would make 2
5774     my_b_safe_write().
5775   */
5776   uchar buff[Binary_log_event::FORMAT_DESCRIPTION_HEADER_LEN +
5777              BINLOG_CHECKSUM_ALG_DESC_LEN];
5778   size_t rec_size= sizeof(buff);
5779   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5780   memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5781   if (!dont_set_created)
5782     created= get_time();
5783   int4store(buff + ST_CREATED_OFFSET, static_cast<uint32>(created));
5784   buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
5785 
5786   size_t number_of_events;
5787   int post_header_len_size = static_cast<int>(post_header_len.size());
5788 
5789   if (post_header_len_size == Binary_log_event::LOG_EVENT_TYPES)
5790     // Replicating between master and slave with same version.
5791     // number_of_events will be same as Binary_log_event::LOG_EVENT_TYPES
5792     number_of_events = Binary_log_event::LOG_EVENT_TYPES;
5793   else if (post_header_len_size > Binary_log_event::LOG_EVENT_TYPES)
5794     /*
5795       Replicating between new master and old slave.
5796       In that case there won't be any memory issues, as there won't be
5797       any out of memory read.
5798     */
5799     number_of_events = Binary_log_event::LOG_EVENT_TYPES;
5800   else
5801     /*
5802       Replicating between old master and new slave.
5803       In that case it might lead to different number_of_events on master and
5804       slave. When the relay log is rotated, the FDE from master is used to
5805       create the FDE event on slave, which is being written here. In that case
5806       we might end up reading more bytes as
5807       post_header_len.size() < Binary_log_event::LOG_EVENT_TYPES;
5808       casuing memory issues.
5809     */
5810     number_of_events = post_header_len_size;
5811 
5812   memcpy((char*) buff + ST_COMMON_HEADER_LEN_OFFSET + 1,  &post_header_len.front(),
5813           number_of_events);
5814   /*
5815     if checksum is requested
5816     record the checksum-algorithm descriptor next to
5817     post_header_len vector which will be followed by the checksum value.
5818     Master is supposed to trigger checksum computing by binlog_checksum_options,
5819     slave does it via marking the event according to
5820     FD_queue checksum_alg value.
5821   */
5822   compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
5823 #ifndef NDEBUG
5824   common_header->data_written= 0; // to prepare for need_checksum assert
5825 #endif
5826   buff[Binary_log_event::FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
5827     (uint8) common_footer->checksum_alg :
5828      (uint8) binary_log::BINLOG_CHECKSUM_ALG_OFF;
5829   /*
5830      FD of checksum-aware server is always checksum-equipped, (V) is in,
5831      regardless of @@global.binlog_checksum policy.
5832      Thereby a combination of (A) == 0, (V) != 0 means
5833      it's the checksum-aware server's FD event that heads checksum-free binlog
5834      file.
5835      Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
5836      A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
5837      heading the checksummed binlog.
5838      (A), (V) presence in FD of the checksum-aware server makes the event
5839      1 + 4 bytes bigger comparing to the former FD.
5840   */
5841 
5842   if ((no_checksum= (common_footer->checksum_alg ==
5843                      binary_log::BINLOG_CHECKSUM_ALG_OFF)))
5844   {
5845     // Forcing (V) room to fill anyway
5846     common_footer->checksum_alg= binary_log::BINLOG_CHECKSUM_ALG_CRC32;
5847   }
5848   ret= (write_header(file, rec_size) ||
5849         wrapper_my_b_safe_write(file, buff, rec_size) ||
5850         write_footer(file));
5851   if (no_checksum)
5852     common_footer->checksum_alg= binary_log::BINLOG_CHECKSUM_ALG_OFF;
5853   return ret;
5854 }
5855 #endif
5856 
5857 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5858 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
5859 {
5860   int ret= 0;
5861   DBUG_ENTER("Format_description_log_event::do_apply_event");
5862 
5863   /*
5864     As a transaction NEVER spans on 2 or more binlogs:
5865     if we have an active transaction at this point, the master died
5866     while writing the transaction to the binary log, i.e. while
5867     flushing the binlog cache to the binlog. XA guarantees that master has
5868     rolled back. So we roll back.
5869     Note: this event could be sent by the master to inform us of the
5870     format of its binlog; in other words maybe it is not at its
5871     original place when it comes to us; we'll know this by checking
5872     log_pos ("artificial" events have log_pos == 0).
5873   */
5874   if (!thd->rli_fake && !is_artificial_event() && created &&
5875       thd->get_transaction()->is_active(Transaction_ctx::SESSION))
5876   {
5877     /* This is not an error (XA is safe), just an information */
5878     rli->report(INFORMATION_LEVEL, 0,
5879                 "Rolling back unfinished transaction (no COMMIT "
5880                 "or ROLLBACK in relay log). A probable cause is that "
5881                 "the master died while writing the transaction to "
5882                 "its binary log, thus rolled back too.");
5883     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
5884   }
5885 
5886   /*
5887     If this event comes from ourselves, there is no cleaning task to
5888     perform, we don't call Start_log_event_v3::do_apply_event()
5889     (this was just to update the log's description event).
5890   */
5891   if (server_id != (uint32) ::server_id)
5892   {
5893     /*
5894       If the event was not requested by the slave i.e. the master sent
5895       it while the slave asked for a position >4, the event will make
5896       rli->group_master_log_pos advance. Say that the slave asked for
5897       position 1000, and the Format_desc event's end is 96. Then in
5898       the beginning of replication rli->group_master_log_pos will be
5899       0, then 96, then jump to first really asked event (which is
5900       >96). So this is ok.
5901     */
5902     ret= Start_log_event_v3::do_apply_event(rli);
5903   }
5904 
5905   if (!ret)
5906   {
5907     /* Save the information describing this binlog */
5908     copy_crypto_data(*rli->get_rli_description_event());
5909     const_cast<Relay_log_info *>(rli)->set_rli_description_event(this);
5910   }
5911 
5912   DBUG_RETURN(ret);
5913 }
5914 
do_update_pos(Relay_log_info * rli)5915 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
5916 {
5917   if (server_id == (uint32) ::server_id)
5918   {
5919     /*
5920       We only increase the relay log position if we are skipping
5921       events and do not touch any group_* variables, nor flush the
5922       relay log info.  If there is a crash, we will have to re-skip
5923       the events again, but that is a minor issue.
5924 
5925       If we do not skip stepping the group log position (and the
5926       server id was changed when restarting the server), it might well
5927       be that we start executing at a position that is invalid, e.g.,
5928       at a Rows_log_event or a Query_log_event preceeded by a
5929       Intvar_log_event instead of starting at a Table_map_log_event or
5930       the Intvar_log_event respectively.
5931      */
5932     rli->inc_event_relay_log_pos();
5933     return 0;
5934   }
5935   else
5936   {
5937     return Log_event::do_update_pos(rli);
5938   }
5939 }
5940 
5941 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5942 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
5943 {
5944   return Log_event::EVENT_SKIP_NOT;
5945 }
5946 
5947 #endif
5948 
5949 
5950 
5951   /**************************************************************************
5952         Load_log_event methods
5953    General note about Load_log_event: the binlogging of LOAD DATA INFILE is
5954    going to be changed in 5.0 (or maybe in 5.1; not decided yet).
5955    However, the 5.0 slave could still have to read such events (from a 4.x
5956    master), convert them (which just means maybe expand the header, when 5.0
5957    servers have a UID in events) (remember that whatever is after the header
5958    will be like in 4.x, as this event's format is not modified in 5.0 as we
5959    will use new types of events to log the new LOAD DATA INFILE features).
5960    To be able to read/convert, we just need to not assume that the common
5961    header is of length LOG_EVENT_HEADER_LEN (we must use the description
5962    event).
5963    Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
5964    between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
5965    positions displayed in SHOW SLAVE STATUS then are fine too).
5966   **************************************************************************/
5967 
5968 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_query_buffer_length()5969 uint Load_log_event::get_query_buffer_length()
5970 {
5971   return
5972     //the DB name may double if we escape the quote character
5973     5 + 2*db_len + 3 +
5974     18 + fname_len*4 + 2 +                    // "LOAD DATA INFILE 'file''"
5975     11 +                                    // "CONCURRENT "
5976     7 +					    // LOCAL
5977     9 +                                     // " REPLACE or IGNORE "
5978     13 + table_name_len*2 +                 // "INTO TABLE `table`"
5979     21 + sql_ex.data_info.field_term_len*4 + 2 +
5980                                             // " FIELDS TERMINATED BY 'str'"
5981     23 + sql_ex.data_info.enclosed_len*4 + 2 +
5982                                             // " OPTIONALLY ENCLOSED BY 'str'"
5983     12 + sql_ex.data_info.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
5984     21 + sql_ex.data_info.line_term_len*4 + 2 +
5985                                             // " LINES TERMINATED BY 'str'"
5986     19 + sql_ex.data_info.line_start_len*4 + 2 +
5987                                             // " LINES STARTING BY 'str'"
5988     15 + 22 +                               // " IGNORE xxx  LINES"
5989     3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
5990 }
5991 
5992 
print_query(bool need_db,const char * cs,char * buf,char ** end,char ** fn_start,char ** fn_end)5993 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
5994                                  char **end, char **fn_start, char **fn_end)
5995 {
5996   char quoted_id[1 + NAME_LEN * 2 + 2];//quoted  length
5997   size_t  quoted_id_len= 0;
5998   char *pos= buf;
5999 
6000   if (need_db && db && db_len)
6001   {
6002     pos= my_stpcpy(pos, "use ");
6003 #ifdef MYSQL_SERVER
6004     quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
6005                                                db, 0);
6006 #else
6007     quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
6008 #endif
6009     quoted_id[quoted_id_len]= '\0';
6010     pos= my_stpcpy(pos, quoted_id);
6011     pos= my_stpcpy(pos, "; ");
6012   }
6013 
6014   pos= my_stpcpy(pos, "LOAD DATA ");
6015 
6016   if (is_concurrent)
6017     pos= my_stpcpy(pos, "CONCURRENT ");
6018 
6019   if (fn_start)
6020     *fn_start= pos;
6021 
6022   if (check_fname_outside_temp_buf())
6023     pos= my_stpcpy(pos, "LOCAL ");
6024   pos= my_stpcpy(pos, "INFILE ");
6025   pos= pretty_print_str(pos, fname, fname_len);
6026   pos= my_stpcpy(pos, " ");
6027 
6028   if (sql_ex.data_info.opt_flags & REPLACE_FLAG)
6029     pos= my_stpcpy(pos, "REPLACE ");
6030   else if (sql_ex.data_info.opt_flags & IGNORE_FLAG)
6031     pos= my_stpcpy(pos, "IGNORE ");
6032 
6033   pos= my_stpcpy(pos ,"INTO");
6034 
6035   if (fn_end)
6036     *fn_end= pos;
6037 
6038   pos= my_stpcpy(pos ," TABLE ");
6039   memcpy(pos, table_name, table_name_len);
6040   pos+= table_name_len;
6041 
6042   if (cs != NULL)
6043   {
6044     pos= my_stpcpy(pos ," CHARACTER SET ");
6045     pos= my_stpcpy(pos ,  cs);
6046   }
6047 
6048   /* We have to create all optional fields as the default is not empty */
6049   pos= my_stpcpy(pos, " FIELDS TERMINATED BY ");
6050   pos= pretty_print_str(pos, sql_ex.data_info.field_term,
6051                         sql_ex.data_info.field_term_len);
6052   if (sql_ex.data_info.opt_flags & OPT_ENCLOSED_FLAG)
6053     pos= my_stpcpy(pos, " OPTIONALLY ");
6054   pos= my_stpcpy(pos, " ENCLOSED BY ");
6055   pos= pretty_print_str(pos, sql_ex.data_info.enclosed,
6056                         sql_ex.data_info.enclosed_len);
6057 
6058   pos= my_stpcpy(pos, " ESCAPED BY ");
6059   pos= pretty_print_str(pos, sql_ex.data_info.escaped,
6060                         sql_ex.data_info.escaped_len);
6061 
6062   pos= my_stpcpy(pos, " LINES TERMINATED BY ");
6063   pos= pretty_print_str(pos, sql_ex.data_info.line_term,
6064                         sql_ex.data_info.line_term_len);
6065   if (sql_ex.data_info.line_start_len)
6066   {
6067     pos= my_stpcpy(pos, " STARTING BY ");
6068     pos= pretty_print_str(pos, sql_ex.data_info.line_start,
6069                           sql_ex.data_info.line_start_len);
6070   }
6071 
6072   if ((long) skip_lines > 0)
6073   {
6074     pos= my_stpcpy(pos, " IGNORE ");
6075     pos= longlong10_to_str((longlong) skip_lines, pos, 10);
6076     pos= my_stpcpy(pos," LINES ");
6077   }
6078 
6079   if (num_fields)
6080   {
6081     uint i;
6082     const char *field= fields;
6083     pos= my_stpcpy(pos, " (");
6084     for (i = 0; i < num_fields; i++)
6085     {
6086       if (i)
6087       {
6088         *pos++= ' ';
6089         *pos++= ',';
6090       }
6091       quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
6092                                                  0);
6093       memcpy(pos, quoted_id, quoted_id_len-1);
6094     }
6095     *pos++= ')';
6096   }
6097 
6098   *end= pos;
6099 }
6100 
6101 
pack_info(Protocol * protocol)6102 int Load_log_event::pack_info(Protocol *protocol)
6103 {
6104   char *buf, *end;
6105 
6106   if (!(buf= (char*) my_malloc(key_memory_log_event,
6107                                get_query_buffer_length(), MYF(MY_WME))))
6108     return 1;
6109   print_query(TRUE, NULL, buf, &end, 0, 0);
6110   protocol->store(buf, end-buf, &my_charset_bin);
6111   my_free(buf);
6112   return 0;
6113 }
6114 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6115 
6116 
6117 #ifndef MYSQL_CLIENT
6118 
6119 /*
6120   Load_log_event::write_data_header()
6121 */
6122 
write_data_header(IO_CACHE * file)6123 bool Load_log_event::write_data_header(IO_CACHE* file)
6124 {
6125   char buf[Binary_log_event::LOAD_HEADER_LEN];
6126   int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
6127   int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
6128   int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
6129   buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
6130   buf[L_DB_LEN_OFFSET] = (char)db_len;
6131   int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
6132   return event_encrypter.encrypt_and_write(file, (uchar*)buf, Binary_log_event::LOAD_HEADER_LEN) != 0;
6133 }
6134 
6135 
6136 /*
6137   Load_log_event::write_data_body()
6138 */
6139 
write_data_body(IO_CACHE * file)6140 bool Load_log_event::write_data_body(IO_CACHE* file)
6141 {
6142   sql_ex.event_encrypter= &event_encrypter;
6143   if (sql_ex.write_data(file))
6144     return 1;
6145   if (num_fields && fields && field_lens)
6146   {
6147     if (event_encrypter.encrypt_and_write(file, (uchar*)field_lens, num_fields) ||
6148 	event_encrypter.encrypt_and_write(file, (uchar*)fields, field_block_len))
6149       return 1;
6150   }
6151   return (event_encrypter.encrypt_and_write(file, (uchar*)table_name, table_name_len + 1) ||
6152 	  event_encrypter.encrypt_and_write(file, (uchar*)db, db_len + 1) ||
6153 	  event_encrypter.encrypt_and_write(file, (uchar*)fname, fname_len));
6154 }
6155 
6156 
6157 /*
6158   Load_log_event::Load_log_event()
6159 */
6160 
Load_log_event(THD * thd_arg,sql_exchange * ex,const char * db_arg,const char * table_name_arg,List<Item> & fields_arg,bool is_concurrent_arg,enum enum_duplicates handle_dup,bool ignore,bool using_trans)6161 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
6162 			       const char *db_arg, const char *table_name_arg,
6163 			       List<Item> &fields_arg,
6164                                bool is_concurrent_arg,
6165 			       enum enum_duplicates handle_dup,
6166 			       bool ignore, bool using_trans)
6167   : binary_log::Load_event(),
6168    Log_event(thd_arg,
6169              thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
6170              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
6171                            Log_event::EVENT_STMT_CACHE,
6172              Log_event::EVENT_NORMAL_LOGGING,
6173              header(), footer())
6174 {
6175   thread_id= thd_arg->thread_id();
6176   slave_proxy_id= thd_arg->variables.pseudo_thread_id;
6177   table_name= table_name_arg ? table_name_arg : "";
6178   db= db_arg;
6179   fname= ex->file_name;
6180   local_fname= FALSE;
6181   is_concurrent= is_concurrent_arg;
6182 
6183   /*
6184   exec_time calculation has changed to use the same method that is used
6185   to fill out "thd_arg->start_time"
6186   */
6187 
6188   struct timeval end_time;
6189   ulonglong micro_end_time= my_micro_time();
6190   my_micro_time_to_timeval(micro_end_time, &end_time);
6191 
6192   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
6193 
6194   /* db can never be a zero pointer in 4.0 */
6195   db_len = strlen(db);
6196   table_name_len =  strlen(table_name);
6197   fname_len = (fname) ?  strlen(fname) : 0;
6198   sql_ex.data_info.field_term = ex->field.field_term->ptr();
6199   sql_ex.data_info.field_term_len = (uint8) ex->field.field_term->length();
6200   sql_ex.data_info.enclosed = ex->field.enclosed->ptr();
6201   sql_ex.data_info.enclosed_len = (uint8) ex->field.enclosed->length();
6202   sql_ex.data_info.line_term = ex->line.line_term->ptr();
6203   sql_ex.data_info.line_term_len = (uint8) ex->line.line_term->length();
6204   sql_ex.data_info.line_start = ex->line.line_start->ptr();
6205   sql_ex.data_info.line_start_len = (uint8) ex->line.line_start->length();
6206   sql_ex.data_info.escaped = (char*) ex->field.escaped->ptr();
6207   sql_ex.data_info.escaped_len = (uint8) ex->field.escaped->length();
6208   sql_ex.data_info.opt_flags = 0;
6209   sql_ex.data_info.cached_new_format = -1;
6210 
6211   if (ex->dumpfile)
6212     sql_ex.data_info.opt_flags|= DUMPFILE_FLAG;
6213   if (ex->field.opt_enclosed)
6214     sql_ex.data_info.opt_flags|= OPT_ENCLOSED_FLAG;
6215 
6216   sql_ex.data_info.empty_flags= 0;
6217 
6218   switch (handle_dup) {
6219   case DUP_REPLACE:
6220     sql_ex.data_info.opt_flags|= REPLACE_FLAG;
6221     break;
6222   case DUP_UPDATE:				// Impossible here
6223   case DUP_ERROR:
6224     break;
6225   }
6226   if (ignore)
6227     sql_ex.data_info.opt_flags|= IGNORE_FLAG;
6228 
6229   if (!ex->field.field_term->length())
6230     sql_ex.data_info.empty_flags |= FIELD_TERM_EMPTY;
6231   if (!ex->field.enclosed->length())
6232     sql_ex.data_info.empty_flags |= ENCLOSED_EMPTY;
6233   if (!ex->line.line_term->length())
6234     sql_ex.data_info.empty_flags |= LINE_TERM_EMPTY;
6235   if (!ex->line.line_start->length())
6236     sql_ex.data_info.empty_flags |= LINE_START_EMPTY;
6237   if (!ex->field.escaped->length())
6238     sql_ex.data_info.empty_flags |= ESCAPED_EMPTY;
6239 
6240   skip_lines = ex->skip_lines;
6241 
6242   List_iterator<Item> li(fields_arg);
6243   field_lens_buf.length(0);
6244   fields_buf.length(0);
6245   Item* item;
6246   while ((item = li++))
6247   {
6248     num_fields++;
6249     uchar len= (uchar) item->item_name.length();
6250     field_block_len += len + 1;
6251     fields_buf.append(item->item_name.ptr(), len + 1);
6252     field_lens_buf.append((char*)&len, 1);
6253   }
6254 
6255   field_lens = (const uchar*)field_lens_buf.ptr();
6256   fields = fields_buf.ptr();
6257   if (table_name != 0)
6258     is_valid_param= true;
6259 
6260   if (sql_ex.data_info.new_format())
6261     common_header->type_code= binary_log::NEW_LOAD_EVENT;
6262   else
6263     common_header->type_code= binary_log::LOAD_EVENT;
6264 }
6265 #endif /* !MYSQL_CLIENT */
6266 
6267 
6268 /**
6269   @note
6270     The caller must do buf[event_len] = 0 before he starts using the
6271     constructed event.
6272 */
Load_log_event(const char * buf,uint event_len,const Format_description_event * description_event)6273 Load_log_event::Load_log_event(const char *buf, uint event_len,
6274                                const Format_description_event *description_event)
6275 : binary_log::Load_event(buf, event_len, description_event),
6276   Log_event(header(), footer())
6277 {
6278   DBUG_ENTER("Load_log_event");
6279   if (table_name != 0)
6280     is_valid_param= true;
6281   thread_id= slave_proxy_id;
6282   if (event_len)
6283   {
6284     /**
6285       We need to set exec_time here, which is ued to calcutate seconds behind
6286       master on the slave.
6287     */
6288     exec_time= load_exec_time;
6289     /*
6290       I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6291       4.0->5.0 and 5.0->5.0 and it works.
6292     */
6293     sql_ex.data_info= sql_ex_data;
6294   }
6295   if (sql_ex.data_info.new_format())
6296     common_header->type_code= binary_log::NEW_LOAD_EVENT;
6297   else
6298     common_header->type_code= binary_log::LOAD_EVENT;
6299   DBUG_VOID_RETURN;
6300 }
6301 
6302 
6303 /*
6304   Load_log_event::print()
6305 */
6306 
6307 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6308 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6309 {
6310   print(file, print_event_info, 0);
6311 }
6312 
6313 
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info,bool commented)6314 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
6315 			   bool commented)
6316 {
6317   IO_CACHE *const head= &print_event_info->head_cache;
6318   size_t id_len= 0;
6319   char str_buf[1 + 2*FN_REFLEN + 2];
6320 
6321   DBUG_ENTER("Load_log_event::print");
6322   if (!print_event_info->short_form)
6323   {
6324     print_header(head, print_event_info, FALSE);
6325     my_b_printf(head, "\tQuery\tthread_id=%u\texec_time=%ld\n",
6326                 thread_id, exec_time);
6327   }
6328 
6329   bool different_db= 1;
6330   if (db)
6331   {
6332     /*
6333       If the database is different from the one of the previous statement, we
6334       need to print the "use" command, and we update the last_db.
6335       But if commented, the "use" is going to be commented so we should not
6336       update the last_db.
6337     */
6338     if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
6339         !commented)
6340       memcpy(print_event_info->db, db, db_len + 1);
6341   }
6342 
6343   if (db && db[0] && different_db)
6344   {
6345 #ifdef MYSQL_SERVER
6346     id_len= my_strmov_quoted_identifier(this->thd, str_buf, db, 0);
6347 #else
6348     id_len= my_strmov_quoted_identifier(str_buf, db);
6349 #endif
6350     str_buf[id_len]= '\0';
6351     my_b_printf(head, "%suse %s%s\n",
6352                 commented ? "# " : "", str_buf, print_event_info->delimiter);
6353   }
6354   if (common_header->flags & LOG_EVENT_THREAD_SPECIFIC_F)
6355     my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
6356             commented ? "# " : "", (ulong)thread_id,
6357             print_event_info->delimiter);
6358   my_b_printf(head, "%sLOAD DATA ",
6359               commented ? "# " : "");
6360   if (check_fname_outside_temp_buf())
6361     my_b_printf(head, "LOCAL ");
6362   my_b_printf(head, "INFILE '%-*s' ", static_cast<int>(fname_len), fname);
6363 
6364   if (sql_ex.data_info.opt_flags & REPLACE_FLAG)
6365     my_b_printf(head,"REPLACE ");
6366   else if (sql_ex.data_info.opt_flags & IGNORE_FLAG)
6367     my_b_printf(head,"IGNORE ");
6368 
6369 #ifdef MYSQL_SERVER
6370     id_len= my_strmov_quoted_identifier(this->thd, str_buf, table_name, 0);
6371 #else
6372     id_len= my_strmov_quoted_identifier(str_buf, table_name);
6373 #endif
6374   str_buf[id_len]= '\0';
6375   my_b_printf(head, "INTO TABLE %s", str_buf);
6376 
6377   my_b_printf(head, " FIELDS TERMINATED BY ");
6378   pretty_print_str(head, sql_ex.data_info.field_term,
6379                    sql_ex.data_info.field_term_len);
6380 
6381   if (sql_ex.data_info.opt_flags & OPT_ENCLOSED_FLAG)
6382     my_b_printf(head," OPTIONALLY ");
6383   my_b_printf(head, " ENCLOSED BY ");
6384   pretty_print_str(head, sql_ex.data_info.enclosed,
6385                    sql_ex.data_info.enclosed_len);
6386 
6387   my_b_printf(head, " ESCAPED BY ");
6388   pretty_print_str(head, sql_ex.data_info.escaped,
6389                    sql_ex.data_info.escaped_len);
6390 
6391   my_b_printf(head," LINES TERMINATED BY ");
6392   pretty_print_str(head, sql_ex.data_info.line_term,
6393                    sql_ex.data_info.line_term_len);
6394 
6395 
6396   if (sql_ex.data_info.line_start)
6397   {
6398     my_b_printf(head," STARTING BY ");
6399     pretty_print_str(head, sql_ex.data_info.line_start,
6400                      sql_ex.data_info.line_start_len);
6401   }
6402   if ((long) skip_lines > 0)
6403     my_b_printf(head, " IGNORE %ld LINES", (long) skip_lines);
6404 
6405   if (num_fields)
6406   {
6407     uint i;
6408     const char* field = fields;
6409     my_b_printf(head, " (");
6410     for (i = 0; i < num_fields; i++)
6411     {
6412       if (i)
6413         my_b_printf(head, ",");
6414       id_len= my_strmov_quoted_identifier((char *) str_buf, field);
6415       str_buf[id_len]= '\0';
6416       my_b_printf(head, "%s", str_buf);
6417 
6418       field += field_lens[i]  + 1;
6419     }
6420     my_b_printf(head, ")");
6421   }
6422 
6423   my_b_printf(head, "%s\n", print_event_info->delimiter);
6424   DBUG_VOID_RETURN;
6425 }
6426 #endif /* MYSQL_CLIENT */
6427 
6428 #ifndef MYSQL_CLIENT
6429 
6430 /**
6431   Load_log_event::set_fields()
6432 
6433   @note
6434     This function can not use the member variable
6435     for the database, since LOAD DATA INFILE on the slave
6436     can be for a different database than the current one.
6437     This is the reason for the affected_db argument to this method.
6438 */
6439 
set_fields(const char * affected_db,List<Item> & field_list,Name_resolution_context * context)6440 void Load_log_event::set_fields(const char* affected_db,
6441 				List<Item> &field_list,
6442                                 Name_resolution_context *context)
6443 {
6444   uint i;
6445   const char* field = fields;
6446   for (i= 0; i < num_fields; i++)
6447   {
6448     field_list.push_back(new Item_field(context,
6449                                         affected_db, table_name, field));
6450     field+= field_lens[i]  + 1;
6451   }
6452 }
6453 #endif /* !MYSQL_CLIENT */
6454 
6455 
6456 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6457 /**
6458   Does the data loading job when executing a LOAD DATA on the slave.
6459 
6460   @param net
6461   @param rli
6462   @param use_rli_only_for_errors     If set to 1, rli is provided to
6463                                      Load_log_event::exec_event only for this
6464                                      function to have rli->get_rpl_log_name and
6465                                      rli->last_slave_error, both being used by
6466                                      error reports.  If set to 0, rli is provided
6467                                      for full use, i.e. for error reports and
6468                                      position advancing.
6469 
6470   @todo
6471     fix this; this can be done by testing rules in
6472     Create_file_log_event::exec_event() and then discarding Append_block and
6473     al.
6474   @todo
6475     this is a bug - this needs to be moved to the I/O thread
6476 
6477   @retval
6478     0           Success
6479   @retval
6480     1           Failure
6481 */
6482 
do_apply_event(NET * net,Relay_log_info const * rli,bool use_rli_only_for_errors)6483 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
6484                                    bool use_rli_only_for_errors)
6485 {
6486   assert(thd->query().str == NULL);
6487   thd->reset_query();                    // Should not be needed
6488   set_thd_db(thd, db, db_len);
6489   thd->is_slave_error= 0;
6490   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
6491 
6492   /* see Query_log_event::do_apply_event() and BUG#13360 */
6493   assert(!rli->m_table_map.count());
6494   /*
6495     Usually lex_start() is called by mysql_parse(), but we need it here
6496     as the present method does not call mysql_parse().
6497   */
6498   lex_start(thd);
6499   thd->lex->local_file= local_fname;
6500   mysql_reset_thd_for_next_command(thd);
6501 
6502   /*
6503     It is possible that the thread does not hold anonymous GTID
6504     ownership here, e.g. in case this is the first event of a relay
6505     log.
6506   */
6507   gtid_reacquire_ownership_if_anonymous(thd);
6508 
6509    /*
6510     We test replicate_*_db rules. Note that we have already prepared
6511     the file to load, even if we are going to ignore and delete it
6512     now. So it is possible that we did a lot of disk writes for
6513     nothing. In other words, a big LOAD DATA INFILE on the master will
6514     still consume a lot of space on the slave (space in the relay log
6515     + space of temp files: twice the space of the file to load...)
6516     even if it will finally be ignored.  TODO: fix this; this can be
6517     done by testing rules in Create_file_log_event::do_apply_event()
6518     and then discarding Append_block and al. Another way is do the
6519     filtering in the I/O thread (more efficient: no disk writes at
6520     all).
6521   */
6522   if (rpl_filter->db_ok(thd->db().str))
6523   {
6524     thd->set_time(&(common_header->when));
6525     thd->set_query_id(next_query_id());
6526     assert(!thd->get_stmt_da()->is_set());
6527 
6528     TABLE_LIST tables;
6529     char table_buf[NAME_LEN + 1];
6530     my_stpcpy(table_buf, table_name);
6531     if (lower_case_table_names)
6532       my_casedn_str(system_charset_info, table_buf);
6533     tables.init_one_table(thd->strmake(thd->db().str, thd->db().length),
6534                           thd->db().length,
6535                           table_buf, strlen(table_buf),
6536                           table_buf, TL_WRITE);
6537     tables.updating= 1;
6538 
6539     // the table will be opened in mysql_load
6540     if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db().str, &tables))
6541     {
6542       // TODO: this is a bug - this needs to be moved to the I/O thread
6543       if (net)
6544         skip_load_data_infile(net);
6545     }
6546     else
6547     {
6548       char llbuff[22];
6549       char *end;
6550       enum enum_duplicates handle_dup;
6551       char *load_data_query;
6552 
6553       /*
6554         Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
6555         and written to slave's binlog if binlogging is on.
6556       */
6557       if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
6558       {
6559         /*
6560           This will set thd->fatal_error in case of OOM. So we surely will notice
6561           that something is wrong.
6562         */
6563         goto error;
6564       }
6565 
6566       print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
6567       *end= 0;
6568       thd->set_query(load_data_query, static_cast<size_t>(end - load_data_query));
6569 
6570       if (sql_ex.data_info.opt_flags & REPLACE_FLAG)
6571         handle_dup= DUP_REPLACE;
6572       else if (sql_ex.data_info.opt_flags & IGNORE_FLAG)
6573       {
6574         thd->lex->set_ignore(true);
6575         handle_dup= DUP_ERROR;
6576       }
6577       else
6578       {
6579         /*
6580           When replication is running fine, if it was DUP_ERROR on the
6581           master then we could choose IGNORE here, because if DUP_ERROR
6582           suceeded on master, and data is identical on the master and slave,
6583           then there should be no uniqueness errors on slave, so IGNORE is
6584           the same as DUP_ERROR. But in the unlikely case of uniqueness errors
6585           (because the data on the master and slave happen to be different
6586           (user error or bug), we want LOAD DATA to print an error message on
6587           the slave to discover the problem.
6588 
6589           If reading from net (a 3.23 master), mysql_load() will change this
6590           to IGNORE.
6591         */
6592         handle_dup= DUP_ERROR;
6593       }
6594       /*
6595         We need to set thd->lex->sql_command and thd->lex->duplicates
6596         since InnoDB tests these variables to decide if this is a LOAD
6597         DATA ... REPLACE INTO ... statement even though mysql_parse()
6598         is not called.  This is not needed in 5.0 since there the LOAD
6599         DATA ... statement is replicated using mysql_parse(), which
6600         sets the thd->lex fields correctly.
6601       */
6602       thd->lex->sql_command= SQLCOM_LOAD;
6603       thd->lex->duplicates= handle_dup;
6604 
6605       sql_exchange ex((char*)fname, sql_ex.data_info.opt_flags & DUMPFILE_FLAG);
6606       String field_term(sql_ex.data_info.field_term,
6607                         sql_ex.data_info.field_term_len,log_cs);
6608       String enclosed(sql_ex.data_info.enclosed,
6609                       sql_ex.data_info.enclosed_len,log_cs);
6610       String line_term(sql_ex.data_info.line_term,
6611                        sql_ex.data_info.line_term_len,log_cs);
6612       String line_start(sql_ex.data_info.line_start,
6613                         sql_ex.data_info.line_start_len,log_cs);
6614       String escaped(sql_ex.data_info.escaped,
6615                      sql_ex.data_info.escaped_len, log_cs);
6616       const String empty_str("", 0, log_cs);
6617       ex.field.field_term= &field_term;
6618       ex.field.enclosed= &enclosed;
6619       ex.line.line_term= &line_term;
6620       ex.line.line_start= &line_start;
6621       ex.field.escaped= &escaped;
6622 
6623       ex.field.opt_enclosed= (sql_ex.data_info.opt_flags & OPT_ENCLOSED_FLAG);
6624       if (sql_ex.data_info.empty_flags & FIELD_TERM_EMPTY)
6625         ex.field.field_term= &empty_str;
6626 
6627       ex.skip_lines= skip_lines;
6628       List<Item> field_list;
6629       thd->lex->select_lex->context.resolve_in_table_list_only(&tables);
6630       set_fields(tables.db, field_list, &thd->lex->select_lex->context);
6631       thd->variables.pseudo_thread_id= thread_id;
6632       if (net)
6633       {
6634         // mysql_load will use thd->net to read the file
6635         thd->get_protocol_classic()->set_vio(net->vio);
6636         // Make sure the client does not get confused about the packet sequence
6637         thd->get_protocol_classic()->set_pkt_nr(net->pkt_nr);
6638       }
6639       /*
6640         It is safe to use tmp_list twice because we are not going to
6641         update it inside mysql_load().
6642       */
6643       List<Item> tmp_list;
6644       /*
6645         Prepare column privilege check for LOAD statement.
6646         This is necessary because the replication code for LOAD bypasses
6647         regular privilege checking, which is done by check_one_table_access()
6648         in regular code path.
6649         We can assign INSERT privileges to the table since the slave thread
6650         operates with all privileges.
6651       */
6652       tables.set_privileges(INSERT_ACL);
6653       tables.set_want_privilege(INSERT_ACL);
6654 
6655       if (open_temporary_tables(thd, &tables) ||
6656           mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
6657                      handle_dup, net != 0))
6658         thd->is_slave_error= 1;
6659       if (thd->cuted_fields)
6660       {
6661         /* log_pos is the position of the LOAD event in the master log */
6662         sql_print_warning("Slave: load data infile on table '%s' at "
6663                           "log position %s in log '%s' produced %ld "
6664                           "warning(s). Default database: '%s'",
6665                           (char*) table_name,
6666                           llstr(common_header->log_pos,llbuff),
6667                           const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
6668                           (ulong) thd->cuted_fields,
6669                           print_slave_db_safe(thd->db().str));
6670       }
6671       if (net)
6672       {
6673         net->pkt_nr= thd->get_protocol_classic()->get_pkt_nr();
6674       }
6675     }
6676   }
6677   else
6678   {
6679     /*
6680       We will just ask the master to send us /dev/null if we do not
6681       want to load the data.
6682       TODO: this a bug - needs to be done in I/O thread
6683     */
6684     if (net)
6685       skip_load_data_infile(net);
6686   }
6687 
6688 error:
6689   thd->get_protocol_classic()->set_vio(NULL);
6690   const char *remember_db= thd->db().str;
6691   thd->set_catalog(NULL_CSTR);
6692   thd->set_db(NULL_CSTR);                   /* will free the current database */
6693   thd->reset_query();
6694   thd->get_stmt_da()->set_overwrite_status(true);
6695   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
6696   thd->get_stmt_da()->set_overwrite_status(false);
6697   close_thread_tables(thd);
6698   /*
6699     - If transaction rollback was requested due to deadlock
6700       perform it and release metadata locks.
6701     - If inside a multi-statement transaction,
6702     defer the release of metadata locks until the current
6703     transaction is either committed or rolled back. This prevents
6704     other statements from modifying the table for the entire
6705     duration of this transaction.  This provides commit ordering
6706     and guarantees serializability across multiple transactions.
6707     - If in autocommit mode, or outside a transactional context,
6708     automatically release metadata locks of the current statement.
6709   */
6710   if (thd->transaction_rollback_request)
6711   {
6712     trans_rollback_implicit(thd);
6713     thd->mdl_context.release_transactional_locks();
6714   }
6715   else if (! thd->in_multi_stmt_transaction_mode())
6716     thd->mdl_context.release_transactional_locks();
6717   else
6718     thd->mdl_context.release_statement_locks();
6719 
6720   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
6721                   thd->is_slave_error= 0; thd->is_fatal_error= 1;);
6722 
6723   if (thd->is_slave_error)
6724   {
6725     /* this err/sql_errno code is copy-paste from net_send_error() */
6726     const char *err;
6727     int sql_errno;
6728     if (thd->is_error())
6729     {
6730       err= thd->get_stmt_da()->message_text();
6731       sql_errno= thd->get_stmt_da()->mysql_errno();
6732     }
6733     else
6734     {
6735       sql_errno=ER_UNKNOWN_ERROR;
6736       err=ER(sql_errno);
6737     }
6738     rli->report(ERROR_LEVEL, sql_errno,"\
6739 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
6740                     err, (char*)table_name, print_slave_db_safe(remember_db));
6741     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6742     return 1;
6743   }
6744   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6745 
6746   if (thd->is_fatal_error)
6747   {
6748     char buf[256];
6749     my_snprintf(buf, sizeof(buf),
6750                 "Running LOAD DATA INFILE on table '%-.64s'."
6751                 " Default database: '%-.64s'",
6752                 (char*)table_name,
6753                 print_slave_db_safe(remember_db));
6754 
6755     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6756                 ER(ER_SLAVE_FATAL_ERROR), buf);
6757     return 1;
6758   }
6759 
6760   return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
6761 }
6762 #endif
6763 
6764 
6765 /**************************************************************************
6766   Rotate_log_event methods
6767 **************************************************************************/
6768 
6769 /*
6770   Rotate_log_event::pack_info()
6771 */
6772 
6773 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6774 int Rotate_log_event::pack_info(Protocol *protocol)
6775 {
6776   char buf1[256], buf[22];
6777   String tmp(buf1, sizeof(buf1), log_cs);
6778   tmp.length(0);
6779   tmp.append(new_log_ident, ident_len);
6780   tmp.append(STRING_WITH_LEN(";pos="));
6781   tmp.append(llstr(pos,buf));
6782   protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
6783   return 0;
6784 }
6785 #endif
6786 
6787 
6788 /*
6789   Rotate_log_event::print()
6790 */
6791 
6792 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6793 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6794 {
6795   char buf[22];
6796   IO_CACHE *const head= &print_event_info->head_cache;
6797 
6798   if (print_event_info->short_form)
6799     return;
6800   print_header(head, print_event_info, FALSE);
6801   my_b_printf(head, "\tRotate to ");
6802   if (new_log_ident)
6803   {
6804     MY_ATTRIBUTE((unused)) int write_res=
6805       my_b_write(head, (uchar*) new_log_ident, (uint)ident_len);
6806     assert(write_res == 0);
6807   }
6808   my_b_printf(head, "  pos: %s\n", llstr(pos, buf));
6809 }
6810 #endif /* MYSQL_CLIENT */
6811 
6812 
6813 
6814 /*
6815   Rotate_log_event::Rotate_log_event() (2 constructors)
6816 */
6817 
6818 
6819 #ifndef MYSQL_CLIENT
Rotate_log_event(const char * new_log_ident_arg,size_t ident_len_arg,ulonglong pos_arg,uint flags_arg)6820 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
6821                                    size_t ident_len_arg, ulonglong pos_arg,
6822                                    uint flags_arg)
6823 : binary_log::Rotate_event(new_log_ident_arg, ident_len_arg, flags_arg, pos_arg),
6824   Log_event(header(), footer(),
6825             Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING)
6826 {
6827 #ifndef NDEBUG
6828   DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
6829 #endif
6830   new_log_ident= new_log_ident_arg;
6831   pos= pos_arg;
6832   ident_len= ident_len_arg ?
6833              ident_len_arg : (uint) strlen(new_log_ident_arg);
6834   flags= flags_arg;
6835 
6836 #ifndef NDEBUG
6837   char buff[22];
6838   DBUG_PRINT("enter",("new_log_ident: %s  pos: %s  flags: %lu", new_log_ident_arg,
6839                       llstr(pos_arg, buff), (ulong) flags));
6840 #endif
6841   if (flags & DUP_NAME)
6842     new_log_ident= my_strndup(key_memory_log_event,
6843                               new_log_ident_arg, ident_len, MYF(MY_WME));
6844   if (new_log_ident != 0)
6845     is_valid_param= true;
6846   if (flags & RELAY_LOG)
6847     set_relay_log_event();
6848   DBUG_VOID_RETURN;
6849 }
6850 #endif
6851 
6852 
Rotate_log_event(const char * buf,uint event_len,const Format_description_event * description_event)6853 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
6854                                    const Format_description_event* description_event)
6855 : binary_log::Rotate_event(buf, event_len, description_event),
6856   Log_event(header(), footer())
6857 {
6858   DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
6859 
6860   if (new_log_ident != 0)
6861     is_valid_param= true;
6862   DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
6863   DBUG_VOID_RETURN;
6864 }
6865 
6866 
6867 /*
6868   Rotate_log_event::write()
6869 */
6870 
6871 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6872 bool Rotate_log_event::write(IO_CACHE* file)
6873 {
6874   char buf[Binary_log_event::ROTATE_HEADER_LEN];
6875   int8store(buf + R_POS_OFFSET, pos);
6876   return (write_header(file, Binary_log_event::ROTATE_HEADER_LEN + ident_len) ||
6877           wrapper_my_b_safe_write(file, (uchar*) buf, Binary_log_event::ROTATE_HEADER_LEN) ||
6878           wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
6879                                      (uint) ident_len) ||
6880           write_footer(file));
6881 }
6882 #endif
6883 
6884 
6885 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6886 
6887 /*
6888   Got a rotate log event from the master.
6889 
6890   This is mainly used so that we can later figure out the logname and
6891   position for the master.
6892 
6893   We can't rotate the slave's BINlog as this will cause infinitive rotations
6894   in a A -> B -> A setup.
6895   The NOTES below is a wrong comment which will disappear when 4.1 is merged.
6896 
6897   This must only be called from the Slave SQL thread, since it calls
6898   flush_relay_log_info().
6899 
6900   @retval
6901     0	ok
6902 */
do_update_pos(Relay_log_info * rli)6903 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
6904 {
6905   int error= 0;
6906   DBUG_ENTER("Rotate_log_event::do_update_pos");
6907 #ifndef NDEBUG
6908   char buf[32];
6909 #endif
6910 
6911   DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
6912                       (ulong) this->server_id, (ulong) ::server_id));
6913   DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
6914   DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
6915 
6916   /*
6917     If we are in a transaction or in a group: the only normal case is
6918     when the I/O thread was copying a big transaction, then it was
6919     stopped and restarted: we have this in the relay log:
6920 
6921     BEGIN
6922     ...
6923     ROTATE (a fake one)
6924     ...
6925     COMMIT or ROLLBACK
6926 
6927     In that case, we don't want to touch the coordinates which
6928     correspond to the beginning of the transaction.  Starting from
6929     5.0.0, there also are some rotates from the slave itself, in the
6930     relay log, which shall not change the group positions.
6931   */
6932 
6933   /*
6934     The way we check if SQL thread is currently in a group is different
6935     for STS and MTS.
6936   */
6937   bool in_group = rli->is_parallel_exec() ?
6938     (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) :
6939     rli->is_in_group();
6940 
6941   if ((server_id != ::server_id || rli->replicate_same_server_id) &&
6942       !is_relay_log_event() &&
6943       !in_group)
6944   {
6945     if (!is_mts_db_partitioned(rli) && server_id != ::server_id)
6946     {
6947       // force the coordinator to start a new binlog segment.
6948       static_cast<Mts_submode_logical_clock*>
6949         (rli->current_mts_submode)->start_new_group();
6950     }
6951     if (rli->is_parallel_exec())
6952     {
6953       /*
6954         Rotate events are special events that are handled as a
6955         synchronization point. For that reason, the checkpoint
6956         routine is being called here.
6957       */
6958       if ((error= mts_checkpoint_routine(rli, 0, false,
6959                                          true/*need_data_lock=true*/)))
6960         goto err;
6961     }
6962 
6963     /*
6964       Acquire protection against global BINLOG lock before rli->data_lock is
6965       locked (otherwise we would also block SHOW SLAVE STATUS).
6966     */
6967     assert(!thd->backup_binlog_lock.is_acquired());
6968     DBUG_PRINT("debug", ("Acquiring binlog protection lock"));
6969     mysql_mutex_assert_not_owner(&rli->data_lock);
6970     const ulong timeout= thd->variables.lock_wait_timeout;
6971     if (thd->backup_binlog_lock.acquire_protection(thd, MDL_EXPLICIT, timeout))
6972     {
6973       error= 1;
6974       goto err;
6975     }
6976 
6977     mysql_mutex_lock(&rli->data_lock);
6978     DBUG_PRINT("info", ("old group_master_log_name: '%s'  "
6979                         "old group_master_log_pos: %lu",
6980                         rli->get_group_master_log_name(),
6981                         (ulong) rli->get_group_master_log_pos()));
6982 
6983     memcpy((void *)rli->get_group_master_log_name(),
6984            new_log_ident, ident_len + 1);
6985     rli->notify_group_master_log_name_update();
6986     if ((error= rli->inc_group_relay_log_pos(pos,
6987                                              false/*need_data_lock=false*/)))
6988     {
6989       mysql_mutex_unlock(&rli->data_lock);
6990       DBUG_PRINT("debug", ("Releasing binlog protection lock"));
6991       thd->backup_binlog_lock.release_protection(thd);
6992       goto err;
6993     }
6994 
6995     DBUG_PRINT("info", ("new group_master_log_name: '%s'  "
6996                         "new group_master_log_pos: %lu",
6997                         rli->get_group_master_log_name(),
6998                         (ulong) rli->get_group_master_log_pos()));
6999     mysql_mutex_unlock(&rli->data_lock);
7000 
7001     DBUG_PRINT("debug", ("Releasing binlog protection lock"));
7002     thd->backup_binlog_lock.release_protection(thd);
7003 
7004     if (rli->is_parallel_exec())
7005     {
7006       bool real_event= server_id && !is_artificial_event();
7007       rli->reset_notified_checkpoint(0,
7008                                      real_event ?
7009                                      common_header->when.tv_sec +
7010                                      (time_t) exec_time : 0,
7011                                      true/*need_data_lock=true*/,
7012                                      real_event? true : false);
7013     }
7014 
7015     /*
7016       Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
7017       a master's downgrade from 5.0 to 4.0.
7018       However, no need to reset rli_description_event: indeed, if the next
7019       master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
7020       master is 4.0 then the events are in the slave's format (conversion).
7021     */
7022     set_slave_thread_options(thd);
7023     set_slave_thread_default_charset(thd, rli);
7024     thd->variables.sql_mode= global_system_variables.sql_mode;
7025     thd->variables.auto_increment_increment=
7026       thd->variables.auto_increment_offset= 1;
7027     /*
7028       Rotate_log_events are generated on Slaves with server_id=0
7029       for all the ignored events, so that the positions in the repository
7030       is updated properly even for ignored events.
7031 
7032       This kind of Rotate_log_event is generated when
7033 
7034         1) the event is generated on the same host and reached due
7035            to circular replication (server_id == ::server_id)
7036 
7037         2) the event is from the host which is listed in ignore_server_ids
7038 
7039         3) IO thread is receiving HEARTBEAT event from the master
7040 
7041         4) IO thread is receiving PREVIOUS_GTID_LOG_EVENT from the master.
7042 
7043       We have to free thd's mem_root here after we update the positions
7044       in the repository table. Otherwise, imagine a situation where
7045       Slave is keep getting ignored events only and no other (non-ignored)
7046       events from the Master, Slave never executes free_root (that generally
7047       happens from Query_log_event::do_apply_event or
7048       Rows_log_event::do_apply_event when they find end of the group event).
7049     */
7050     if (server_id == 0)
7051       free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
7052   }
7053   else
7054     rli->inc_event_relay_log_pos();
7055 
7056 err:
7057   DBUG_RETURN(error);
7058 }
7059 
7060 
7061 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7062 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
7063 {
7064   enum_skip_reason reason= Log_event::do_shall_skip(rli);
7065 
7066   switch (reason) {
7067   case Log_event::EVENT_SKIP_NOT:
7068   case Log_event::EVENT_SKIP_COUNT:
7069     return Log_event::EVENT_SKIP_NOT;
7070 
7071   case Log_event::EVENT_SKIP_IGNORE:
7072     return Log_event::EVENT_SKIP_IGNORE;
7073   }
7074   assert(0);
7075   return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
7076 }
7077 
7078 #endif
7079 
7080 
7081 /**************************************************************************
7082 	Intvar_log_event methods
7083 **************************************************************************/
7084 
7085 /*
7086   Intvar_log_event::pack_info()
7087 */
7088 
7089 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7090 int Intvar_log_event::pack_info(Protocol *protocol)
7091 {
7092   char buf[256], *pos;
7093   pos= strmake(buf, (get_var_type_string()).c_str(), sizeof(buf)-23);
7094   *pos++= '=';
7095   pos= longlong10_to_str(val, pos, -10);
7096   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7097   return 0;
7098 }
7099 #endif
7100 
7101 
7102 /*
7103   Intvar_log_event::Intvar_log_event()
7104 */
Intvar_log_event(const char * buf,const Format_description_event * description_event)7105 Intvar_log_event::Intvar_log_event(const char* buf,
7106                                    const Format_description_event*
7107                                    description_event)
7108 : binary_log::Intvar_event(buf, description_event),
7109   Log_event(header(), footer())
7110 {
7111   is_valid_param= true;
7112 }
7113 
7114 /*
7115   Intvar_log_event::write()
7116 */
7117 
7118 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7119 bool Intvar_log_event::write(IO_CACHE* file)
7120 {
7121   uchar buf[9];
7122   buf[I_TYPE_OFFSET]= (uchar) type;
7123   int8store(buf + I_VAL_OFFSET, val);
7124   return (write_header(file, sizeof(buf)) ||
7125           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7126           write_footer(file));
7127 }
7128 #endif
7129 
7130 
7131 /*
7132   Intvar_log_event::print()
7133 */
7134 
7135 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7136 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7137 {
7138   char llbuff[22];
7139   const char *msg= NULL;
7140   IO_CACHE *const head= &print_event_info->head_cache;
7141 
7142   if (!print_event_info->short_form)
7143   {
7144     print_header(head, print_event_info, FALSE);
7145     my_b_printf(head, "\tIntvar\n");
7146   }
7147 
7148   my_b_printf(head, "SET ");
7149   switch (type) {
7150   case LAST_INSERT_ID_EVENT:
7151     msg="LAST_INSERT_ID";
7152     break;
7153   case INSERT_ID_EVENT:
7154     msg="INSERT_ID";
7155     break;
7156   case INVALID_INT_EVENT:
7157   default: // cannot happen
7158     msg="INVALID_INT";
7159     break;
7160   }
7161   my_b_printf(head, "%s=%s%s\n",
7162               msg, llstr(val,llbuff), print_event_info->delimiter);
7163 }
7164 #endif
7165 
7166 
7167 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
7168 
7169 /*
7170   Intvar_log_event::do_apply_event()
7171 */
7172 
do_apply_event(Relay_log_info const * rli)7173 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
7174 {
7175   /*
7176     We are now in a statement until the associated query log event has
7177     been processed.
7178    */
7179   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7180 
7181   if (rli->deferred_events_collecting)
7182     return rli->deferred_events->add(this);
7183 
7184   switch (type) {
7185   case LAST_INSERT_ID_EVENT:
7186     thd->first_successful_insert_id_in_prev_stmt= val;
7187     thd->substitute_null_with_insert_id= TRUE;
7188     break;
7189   case INSERT_ID_EVENT:
7190     thd->force_one_auto_inc_interval(val);
7191     break;
7192   }
7193   return 0;
7194 }
7195 
do_update_pos(Relay_log_info * rli)7196 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
7197 {
7198   rli->inc_event_relay_log_pos();
7199   return 0;
7200 }
7201 
7202 
7203 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7204 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
7205 {
7206   /*
7207     It is a common error to set the slave skip counter to 1 instead of
7208     2 when recovering from an insert which used a auto increment,
7209     rand, or user var.  Therefore, if the slave skip counter is 1, we
7210     just say that this event should be skipped by ignoring it, meaning
7211     that we do not change the value of the slave skip counter since it
7212     will be decreased by the following insert event.
7213   */
7214   return continue_group(rli);
7215 }
7216 
7217 #endif
7218 
7219 
7220 /**************************************************************************
7221   Rand_log_event methods
7222 **************************************************************************/
7223 
7224 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7225 int Rand_log_event::pack_info(Protocol *protocol)
7226 {
7227   char buf1[256], *pos;
7228   pos= my_stpcpy(buf1,"rand_seed1=");
7229   pos= int10_to_str((long) seed1, pos, 10);
7230   pos= my_stpcpy(pos, ",rand_seed2=");
7231   pos= int10_to_str((long) seed2, pos, 10);
7232   protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
7233   return 0;
7234 }
7235 #endif
7236 
7237 
Rand_log_event(const char * buf,const Format_description_event * description_event)7238 Rand_log_event::Rand_log_event(const char* buf,
7239                                const Format_description_event* description_event)
7240   : binary_log::Rand_event(buf, description_event),
7241     Log_event(header(), footer())
7242 {
7243   is_valid_param= true;
7244 }
7245 
7246 
7247 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7248 bool Rand_log_event::write(IO_CACHE* file)
7249 {
7250   uchar buf[16];
7251   int8store(buf + RAND_SEED1_OFFSET, seed1);
7252   int8store(buf + RAND_SEED2_OFFSET, seed2);
7253   return (write_header(file, sizeof(buf)) ||
7254           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7255 	  write_footer(file));
7256 }
7257 #endif
7258 
7259 
7260 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7261 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7262 {
7263   IO_CACHE *const head= &print_event_info->head_cache;
7264 
7265   char llbuff[22],llbuff2[22];
7266   if (!print_event_info->short_form)
7267   {
7268     print_header(head, print_event_info, FALSE);
7269     my_b_printf(head, "\tRand\n");
7270   }
7271   my_b_printf(head, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
7272               llstr(seed1, llbuff),llstr(seed2, llbuff2),
7273               print_event_info->delimiter);
7274 }
7275 #endif /* MYSQL_CLIENT */
7276 
7277 
7278 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)7279 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
7280 {
7281   /*
7282     We are now in a statement until the associated query log event has
7283     been processed.
7284    */
7285   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7286 
7287   if (rli->deferred_events_collecting)
7288     return rli->deferred_events->add(this);
7289 
7290   thd->rand.seed1= (ulong) seed1;
7291   thd->rand.seed2= (ulong) seed2;
7292   return 0;
7293 }
7294 
do_update_pos(Relay_log_info * rli)7295 int Rand_log_event::do_update_pos(Relay_log_info *rli)
7296 {
7297   rli->inc_event_relay_log_pos();
7298   return 0;
7299 }
7300 
7301 
7302 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7303 Rand_log_event::do_shall_skip(Relay_log_info *rli)
7304 {
7305   /*
7306     It is a common error to set the slave skip counter to 1 instead of
7307     2 when recovering from an insert which used a auto increment,
7308     rand, or user var.  Therefore, if the slave skip counter is 1, we
7309     just say that this event should be skipped by ignoring it, meaning
7310     that we do not change the value of the slave skip counter since it
7311     will be decreased by the following insert event.
7312   */
7313   return continue_group(rli);
7314 }
7315 
7316 /**
7317    Exec deferred Int-, Rand- and User- var events prefixing
7318    a Query-log-event event.
7319 
7320    @param thd THD handle
7321 
7322    @return false on success, true if a failure in an event applying occurred.
7323 */
slave_execute_deferred_events(THD * thd)7324 bool slave_execute_deferred_events(THD *thd)
7325 {
7326   bool res= false;
7327   Relay_log_info *rli= thd->rli_slave;
7328 
7329   assert(rli && (!rli->deferred_events_collecting || rli->deferred_events));
7330 
7331   if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
7332     return res;
7333 
7334   res= rli->deferred_events->execute(rli);
7335   rli->deferred_events->rewind();
7336   return res;
7337 }
7338 
7339 #endif /* !MYSQL_CLIENT */
7340 
7341 
7342 /**************************************************************************
7343   Xid_log_event methods
7344 **************************************************************************/
7345 
7346 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7347 int Xid_log_event::pack_info(Protocol *protocol)
7348 {
7349   char buf[128], *pos;
7350   pos= my_stpcpy(buf, "COMMIT /* xid=");
7351   pos= longlong10_to_str(xid, pos, 10);
7352   pos= my_stpcpy(pos, " */");
7353   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7354   return 0;
7355 }
7356 #endif
7357 
7358 Xid_log_event::
Xid_log_event(const char * buf,const Format_description_event * description_event)7359 Xid_log_event(const char* buf,
7360               const Format_description_event *description_event)
7361   : binary_log::Xid_event(buf, description_event),
7362     Xid_apply_log_event(buf, description_event, header(), footer())
7363 {
7364   is_valid_param= true;
7365 }
7366 
7367 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7368 bool Xid_log_event::write(IO_CACHE* file)
7369 {
7370   DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
7371   return (write_header(file, sizeof(xid)) ||
7372 	  wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
7373 	  write_footer(file));
7374 }
7375 #endif
7376 
7377 
7378 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7379 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7380 {
7381   IO_CACHE *const head= &print_event_info->head_cache;
7382 
7383   if (!print_event_info->short_form)
7384   {
7385     char buf[64];
7386     longlong10_to_str(xid, buf, 10);
7387 
7388     print_header(head, print_event_info, FALSE);
7389     my_b_printf(head, "\tXid = %s\n", buf);
7390   }
7391   my_b_printf(head, "COMMIT%s\n", print_event_info->delimiter);
7392 }
7393 #endif /* MYSQL_CLIENT */
7394 
7395 
7396 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7397 /**
7398    The methods combines few commit actions to make it useable
7399    as in the single- so multi- threaded case.
7400 
7401    @param  thd_arg a pointer to THD handle
7402    @return false  as success and
7403            true   as an error
7404 */
7405 
do_commit(THD * thd_arg)7406 bool Xid_log_event::do_commit(THD *thd_arg)
7407 {
7408   DBUG_EXECUTE_IF("dbug.reached_commit",
7409                   {DBUG_SET("+d,dbug.enabled_commit");});
7410   bool error= trans_commit(thd_arg); /* Automatically rolls back on error. */
7411   DBUG_EXECUTE_IF("crash_after_apply",
7412                   sql_print_information("Crashing crash_after_apply.");
7413                   DBUG_SUICIDE(););
7414   thd_arg->mdl_context.release_transactional_locks();
7415 
7416   error |= mysql_bin_log.gtid_end_transaction(thd_arg);
7417 
7418   /*
7419     The parser executing a SQLCOM_COMMIT or SQLCOM_ROLLBACK will reset the
7420     tx isolation level and access mode when the statement is finishing a
7421     transaction.
7422 
7423     For replicated workload, when dealing with pure transactional workloads,
7424     there will be no QUERY(COMMIT) finishing a transaction, but a
7425     Xid_log_event instead.
7426 
7427     So, if the slave applier changed the current transaction isolation level,
7428     it needs to be restored to the session default value once the current
7429     transaction has been committed.
7430   */
7431   trans_reset_one_shot_chistics(thd);
7432 
7433   /*
7434     Increment the global status commit count variable
7435   */
7436   if (!error)
7437     thd_arg->status_var.com_stat[SQLCOM_COMMIT]++;
7438 
7439   return error;
7440 }
7441 
7442 /**
7443    Worker commits Xid transaction and in case of its transactional
7444    info table marks the current group as done in the Coordnator's
7445    Group Assigned Queue.
7446 
7447    @return zero as success or non-zero as an error
7448 */
do_apply_event_worker(Slave_worker * w)7449 int Xid_apply_log_event::do_apply_event_worker(Slave_worker *w)
7450 {
7451   int error= 0;
7452   bool skipped_commit_pos= true;
7453 
7454   lex_start(thd);
7455   mysql_reset_thd_for_next_command(thd);
7456   Slave_committed_queue *coordinator_gaq= w->c_rli->gaq;
7457 
7458   /* For a slave Xid_log_event is COMMIT */
7459   query_logger.general_log_print(thd, COM_QUERY,
7460                                  "COMMIT /* implicit, from Xid_log_event */");
7461 
7462   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7463                      w->get_group_master_log_name(),
7464                      w->get_group_master_log_pos(),
7465                      w->get_group_relay_log_name(),
7466                      w->get_group_relay_log_pos(),
7467                      w->get_event_relay_log_name(),
7468                      w->get_event_relay_log_pos()));
7469 
7470   DBUG_EXECUTE_IF("crash_before_update_pos",
7471                   sql_print_information("Crashing crash_before_update_pos.");
7472                   DBUG_SUICIDE(););
7473 
7474   ulong gaq_idx= mts_group_idx;
7475   Slave_job_group *ptr_group= coordinator_gaq->get_job_group(gaq_idx);
7476 
7477   if (!thd->get_transaction()->xid_state()->check_in_xa(false) &&
7478       w->is_transactional())
7479   {
7480     /*
7481       Regular (not XA) transaction updates the transactional info table
7482       along with the main transaction. Otherwise, the local flag turned
7483       and given its value the info table is updated after do_commit.
7484       todo: the flag won't be need upon the full xa crash-safety bug76233
7485             gets fixed.
7486     */
7487     skipped_commit_pos= false;
7488     if ((error= w->commit_positions(this, ptr_group,
7489                                     w->is_transactional())))
7490       goto err;
7491   }
7492 
7493   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7494                      w->get_group_master_log_name(),
7495                      w->get_group_master_log_pos(),
7496                      w->get_group_relay_log_name(),
7497                      w->get_group_relay_log_pos(),
7498                      w->get_event_relay_log_name(),
7499                      w->get_event_relay_log_pos()));
7500 
7501   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7502                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7503                   DBUG_SUICIDE(););
7504 
7505   error= do_commit(thd);
7506   if (error)
7507   {
7508     if (!skipped_commit_pos)
7509       w->rollback_positions(ptr_group);
7510   }
7511   else if (skipped_commit_pos)
7512     error= w->commit_positions(this, ptr_group,
7513                                w->is_transactional());
7514 err:
7515   return error;
7516 }
7517 
do_apply_event(Relay_log_info const * rli)7518 int Xid_apply_log_event::do_apply_event(Relay_log_info const *rli)
7519 {
7520   DBUG_ENTER("Xid_log_event::do_apply_event");
7521   int error= 0;
7522   char saved_group_master_log_name[FN_REFLEN];
7523   char saved_group_relay_log_name[FN_REFLEN];
7524   volatile my_off_t saved_group_master_log_pos;
7525   volatile my_off_t saved_group_relay_log_pos;
7526 
7527   char new_group_master_log_name[FN_REFLEN];
7528   char new_group_relay_log_name[FN_REFLEN];
7529   volatile my_off_t new_group_master_log_pos;
7530   volatile my_off_t new_group_relay_log_pos;
7531 
7532   lex_start(thd);
7533   mysql_reset_thd_for_next_command(thd);
7534   /*
7535     Anonymous GTID ownership may be released here if the last
7536     statement before XID updated a non-transactional table and was
7537     written to the binary log as a separate transaction (either
7538     because binlog_format=row or because
7539     binlog_direct_non_transactional_updates=1).  So we need to
7540     re-acquire anonymous ownership.
7541   */
7542   gtid_reacquire_ownership_if_anonymous(thd);
7543   Relay_log_info *rli_ptr= const_cast<Relay_log_info *>(rli);
7544   bool binlog_prot_acquired= false;
7545 
7546   /* For a slave Xid_log_event is COMMIT */
7547   query_logger.general_log_print(thd, COM_QUERY,
7548                                  "COMMIT /* implicit, from Xid_log_event */");
7549 
7550   if (!thd->backup_binlog_lock.is_acquired())
7551   {
7552     const ulong timeout= thd->variables.lock_wait_timeout;
7553 
7554     DBUG_PRINT("debug", ("Acquiring binlog protection lock"));
7555     mysql_mutex_assert_not_owner(&rli->data_lock);
7556     if (thd->backup_binlog_lock.acquire_protection(thd, MDL_EXPLICIT,
7557                                                    timeout))
7558       DBUG_RETURN(1);
7559 
7560     binlog_prot_acquired= true;
7561   }
7562 
7563   mysql_mutex_lock(&rli_ptr->data_lock);
7564 
7565   /*
7566     Save the rli positions. We need them to temporarily reset the positions
7567     just before the commit.
7568    */
7569   strmake(saved_group_master_log_name, rli_ptr->get_group_master_log_name(),
7570           FN_REFLEN - 1);
7571   saved_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7572   strmake(saved_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7573           FN_REFLEN - 1);
7574   saved_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7575 
7576   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7577     rli_ptr->get_group_master_log_name(),
7578     rli_ptr->get_group_master_log_pos(),
7579     rli_ptr->get_group_relay_log_name(),
7580     rli_ptr->get_group_relay_log_pos(),
7581     rli_ptr->get_event_relay_log_name(),
7582     rli_ptr->get_event_relay_log_pos()));
7583 
7584   DBUG_EXECUTE_IF("crash_before_update_pos",
7585                   sql_print_information("Crashing crash_before_update_pos.");
7586                   DBUG_SUICIDE(););
7587 
7588   /*
7589     We need to update the positions in here to make it transactional.
7590   */
7591   rli_ptr->inc_event_relay_log_pos();
7592   rli_ptr->set_group_relay_log_pos(rli_ptr->get_event_relay_log_pos());
7593   rli_ptr->set_group_relay_log_name(rli_ptr->get_event_relay_log_name());
7594 
7595   rli_ptr->notify_group_relay_log_name_update();
7596 
7597   if (common_header->log_pos) // 3.23 binlogs don't have log_posx
7598     rli_ptr->set_group_master_log_pos(common_header->log_pos);
7599 
7600   const bool already_logged_transaction= is_already_logged_transaction(thd);
7601   /*
7602     rli repository being transactional means replication is crash safe.
7603     Positions are written into transactional tables ahead of commit and the
7604     changes are made permanent during commit.
7605     XA transactional does not actually commit so has to defer its flush_info().
7606    */
7607   if (!thd->get_transaction()->xid_state()->check_in_xa(false) &&
7608       rli_ptr->is_transactional() && !already_logged_transaction)
7609   {
7610     if ((error= rli_ptr->flush_info(true)))
7611       goto err;
7612   }
7613 
7614   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7615                       rli_ptr->get_group_master_log_name(),
7616                       rli_ptr->get_group_master_log_pos(),
7617                       rli_ptr->get_group_relay_log_name(),
7618                       rli_ptr->get_group_relay_log_pos(),
7619                       rli_ptr->get_event_relay_log_name(),
7620                       rli_ptr->get_event_relay_log_pos()));
7621 
7622   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7623                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7624                   DBUG_SUICIDE(););
7625 
7626   /**
7627     Commit operation expects the global transaction state variable 'xa_state'to
7628     be set to 'XA_NOTR'. In order to simulate commit failure we set
7629     the 'xa_state' to 'XA_IDLE' so that the commit reports 'ER_XAER_RMFAIL'
7630     error.
7631    */
7632   DBUG_EXECUTE_IF("simulate_commit_failure",
7633                   {
7634                     thd->get_transaction()->xid_state()->set_state(
7635                         XID_STATE::XA_IDLE);
7636                   });
7637 
7638   /*
7639     Save the new rli positions. These positions will be set back to group*
7640     positions on successful completion of the commit operation.
7641    */
7642   strmake(new_group_master_log_name, rli_ptr->get_group_master_log_name(),
7643           FN_REFLEN - 1);
7644   new_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7645   strmake(new_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7646           FN_REFLEN - 1);
7647   new_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7648   /*
7649     Rollback positions in memory just before commit. Position values will be
7650     reset to their new values only on successful commit operation.
7651    */
7652   rli_ptr->set_group_master_log_name(saved_group_master_log_name);
7653   rli_ptr->notify_group_master_log_name_update();
7654   rli_ptr->set_group_master_log_pos(saved_group_master_log_pos);
7655   rli_ptr->set_group_relay_log_name(saved_group_relay_log_name);
7656   rli_ptr->notify_group_relay_log_name_update();
7657   rli_ptr->set_group_relay_log_pos(saved_group_relay_log_pos);
7658 
7659   DBUG_PRINT("info", ("Rolling back to group master %s %llu  group relay %s"
7660                       " %llu\n", rli_ptr->get_group_master_log_name(),
7661                       rli_ptr->get_group_master_log_pos(),
7662                       rli_ptr->get_group_relay_log_name(),
7663                       rli_ptr->get_group_relay_log_pos()));
7664   mysql_mutex_unlock(&rli_ptr->data_lock);
7665   error= do_commit(thd);
7666   mysql_mutex_lock(&rli_ptr->data_lock);
7667   if (error)
7668   {
7669     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
7670                 "Error in Xid_log_event: Commit could not be completed, '%s'",
7671                 thd->get_stmt_da()->message_text());
7672   }
7673   else
7674   {
7675     DBUG_EXECUTE_IF("crash_after_commit_before_update_pos",
7676                     sql_print_information("Crashing "
7677                                           "crash_after_commit_before_update_pos.");
7678                     DBUG_SUICIDE(););
7679     /* Update positions on successful commit */
7680     rli_ptr->set_group_master_log_name(new_group_master_log_name);
7681     rli_ptr->notify_group_master_log_name_update();
7682     rli_ptr->set_group_master_log_pos(new_group_master_log_pos);
7683     rli_ptr->set_group_relay_log_name(new_group_relay_log_name);
7684     rli_ptr->notify_group_relay_log_name_update();
7685     rli_ptr->set_group_relay_log_pos(new_group_relay_log_pos);
7686 
7687     DBUG_PRINT("info", ("Updating positions on succesful commit to group master"
7688                         " %s %llu  group relay %s %llu\n",
7689                         rli_ptr->get_group_master_log_name(),
7690                         rli_ptr->get_group_master_log_pos(),
7691                         rli_ptr->get_group_relay_log_name(),
7692                         rli_ptr->get_group_relay_log_pos()));
7693 
7694     /*
7695       For transactional repository the positions are flushed ahead of commit.
7696       Where as for non transactional rli repository the positions are flushed
7697       only on succesful commit.
7698      */
7699     if (!rli_ptr->is_transactional() && !already_logged_transaction)
7700       rli_ptr->flush_info(false);
7701   }
7702 err:
7703   mysql_cond_broadcast(&rli_ptr->data_cond);
7704   mysql_mutex_unlock(&rli_ptr->data_lock);
7705 
7706   if (binlog_prot_acquired)
7707   {
7708       DBUG_PRINT("debug", ("Releasing binlog protection lock"));
7709       thd->backup_binlog_lock.release_protection(thd);
7710   }
7711 
7712   DBUG_RETURN(error);
7713 }
7714 
7715 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7716 Xid_apply_log_event::do_shall_skip(Relay_log_info *rli)
7717 {
7718   DBUG_ENTER("Xid_log_event::do_shall_skip");
7719   if (rli->slave_skip_counter > 0) {
7720     thd->variables.option_bits&= ~OPTION_BEGIN;
7721     DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
7722   }
7723   DBUG_RETURN(Log_event::do_shall_skip(rli));
7724 }
7725 #endif /* !MYSQL_CLIENT */
7726 
7727 /**************************************************************************
7728   XA_prepare_log_event methods
7729 **************************************************************************/
7730 
7731 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7732 int XA_prepare_log_event::pack_info(Protocol *protocol)
7733 {
7734   char buf[ser_buf_size];
7735   char query[sizeof("XA COMMIT ONE PHASE") + 1 + sizeof(buf)];
7736 
7737   /* RHS of the following assert is unknown to client sources */
7738   compile_time_assert(ser_buf_size == XID::ser_buf_size);
7739   serialize_xid(buf, my_xid.formatID, my_xid.gtrid_length,
7740                 my_xid.bqual_length, my_xid.data);
7741   sprintf(query,
7742           (one_phase ? "XA COMMIT %s ONE PHASE" :  "XA PREPARE %s"),
7743           buf);
7744 
7745   protocol->store(query, strlen(query), &my_charset_bin);
7746   return 0;
7747 }
7748 #endif
7749 
7750 
7751 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7752 bool XA_prepare_log_event::write(IO_CACHE* file)
7753 {
7754   uint8 one_byte= one_phase;
7755   uchar buf_f[4];
7756   uchar buf_g[4];
7757   uchar buf_b[4];
7758   int4store(buf_f, static_cast<XID*>(xid)->get_format_id());
7759   int4store(buf_g, static_cast<XID*>(xid)->get_gtrid_length());
7760   int4store(buf_b, static_cast<XID*>(xid)->get_bqual_length());
7761 
7762   assert(xid_bufs_size == sizeof(buf_f) + sizeof(buf_g) + sizeof(buf_b));
7763 
7764   return write_header(file, sizeof(one_byte) + xid_bufs_size +
7765                       static_cast<XID*>(xid)->get_gtrid_length() +
7766                       static_cast<XID*>(xid)->get_bqual_length())
7767     ||
7768     wrapper_my_b_safe_write(file, &one_byte, sizeof(one_byte)) ||
7769     wrapper_my_b_safe_write(file, buf_f, sizeof(buf_f)) ||
7770     wrapper_my_b_safe_write(file, buf_g, sizeof(buf_g)) ||
7771     wrapper_my_b_safe_write(file, buf_b, sizeof(buf_b)) ||
7772     wrapper_my_b_safe_write(file, (uchar*) static_cast<XID*>(xid)->get_data(),
7773                             static_cast<XID*>(xid)->get_gtrid_length() +
7774                             static_cast<XID*>(xid)->get_bqual_length()) ||
7775     write_footer(file);
7776 }
7777 #endif
7778 
7779 
7780 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7781 void XA_prepare_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7782 {
7783   IO_CACHE *const head= &print_event_info->head_cache;
7784   char buf[ser_buf_size];
7785 
7786   print_header(head, print_event_info, FALSE);
7787   serialize_xid(buf, my_xid.formatID, my_xid.gtrid_length,
7788                         my_xid.bqual_length, my_xid.data);
7789   my_b_printf(head, "\tXA PREPARE %s\n", buf);
7790   my_b_printf(head, one_phase ? "XA COMMIT %s ONE PHASE\n%s\n" : "XA PREPARE %s\n%s\n",
7791               buf, print_event_info->delimiter);
7792 }
7793 #endif /* MYSQL_CLIENT */
7794 
7795 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7796 
7797 /**
7798   Differs from Xid_log_event::do_commit in that it carries out
7799   XA prepare (not the commit).
7800   It also can commit on one phase when the event's member @c one_phase
7801   set to true.
7802 
7803   @param  thd    a pointer to THD handle
7804   @return false  as success and
7805           true   as an error
7806 */
7807 
do_commit(THD * thd)7808 bool XA_prepare_log_event::do_commit(THD *thd)
7809 {
7810   bool error= false;
7811   xid_t xid;
7812 
7813   enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
7814   if (state == GTID_STATEMENT_EXECUTE)
7815   {
7816     if (gtid_pre_statement_post_implicit_commit_checks(thd))
7817       state= GTID_STATEMENT_CANCEL;
7818   }
7819   if (state == GTID_STATEMENT_CANCEL)
7820   {
7821     uint error= thd->get_stmt_da()->mysql_errno();
7822     assert(error != 0);
7823     thd->rli_slave->report(ERROR_LEVEL, error,
7824                            "Error executing XA PREPARE event: '%s'",
7825                            thd->get_stmt_da()->message_text());
7826     thd->is_slave_error= 1;
7827     return true;
7828   }
7829   else if (state == GTID_STATEMENT_SKIP)
7830     return false;
7831 
7832   xid.set(my_xid.formatID,
7833           my_xid.data, my_xid.gtrid_length,
7834           my_xid.data + my_xid.gtrid_length, my_xid.bqual_length);
7835   if (!one_phase)
7836   {
7837     /*
7838       This is XA-prepare branch.
7839     */
7840     thd->lex->sql_command= SQLCOM_XA_PREPARE;
7841     thd->lex->m_sql_cmd= new Sql_cmd_xa_prepare(&xid);
7842     error= thd->lex->m_sql_cmd->execute(thd);
7843   }
7844   else
7845   {
7846     thd->lex->sql_command= SQLCOM_XA_COMMIT;
7847     thd->lex->m_sql_cmd= new Sql_cmd_xa_commit(&xid, XA_ONE_PHASE);
7848     error= thd->lex->m_sql_cmd->execute(thd);
7849   }
7850 
7851   if (!error)
7852     error = mysql_bin_log.gtid_end_transaction(thd);
7853 
7854   return error;
7855 }
7856 #endif
7857 
7858 
7859 /**************************************************************************
7860   User_var_log_event methods
7861 **************************************************************************/
7862 
7863 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7864 int User_var_log_event::pack_info(Protocol* protocol)
7865 {
7866   char *buf= 0;
7867   char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
7868   size_t id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len);
7869   quoted_id[id_len]= '\0';
7870   size_t val_offset= 2 + id_len;
7871   size_t event_len= val_offset;
7872 
7873   if (is_null)
7874   {
7875     if (!(buf= (char*) my_malloc(key_memory_log_event,
7876                                  val_offset + 5, MYF(MY_WME))))
7877       return 1;
7878     my_stpcpy(buf + val_offset, "NULL");
7879     event_len= val_offset + 4;
7880   }
7881   else
7882   {
7883     switch (type) {
7884     case REAL_TYPE:
7885       double real_val;
7886       float8get(&real_val, val);
7887       if (!(buf= (char*) my_malloc(key_memory_log_event,
7888                                    val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
7889                                    MYF(MY_WME))))
7890         return 1;
7891       event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
7892                           buf + val_offset, NULL);
7893       break;
7894     case INT_TYPE:
7895       if (!(buf= (char*) my_malloc(key_memory_log_event,
7896                                    val_offset + 22, MYF(MY_WME))))
7897         return 1;
7898       event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
7899                                    ((flags & User_var_log_event::UNSIGNED_F) ?
7900                                     10 : -10))-buf;
7901       break;
7902     case DECIMAL_TYPE:
7903     {
7904       if (!(buf= (char*) my_malloc(key_memory_log_event,
7905                                    val_offset + DECIMAL_MAX_STR_LENGTH + 1,
7906                                    MYF(MY_WME))))
7907         return 1;
7908       String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin);
7909       my_decimal dec;
7910       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
7911                         val[1]);
7912       my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
7913       event_len= str.length() + val_offset;
7914       break;
7915     }
7916     case STRING_TYPE:
7917       /* 15 is for 'COLLATE' and other chars */
7918       buf= (char*) my_malloc(key_memory_log_event,
7919                              event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
7920                              MYF(MY_WME));
7921       CHARSET_INFO *cs;
7922       if (!buf)
7923         return 1;
7924       if (!(cs= get_charset(charset_number, MYF(0))))
7925       {
7926         my_stpcpy(buf+val_offset, "???");
7927         event_len+= 3;
7928       }
7929       else
7930       {
7931         char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
7932         p= str_to_hex(p, val, val_len);
7933         p= strxmov(p, " COLLATE ", cs->name, NullS);
7934         event_len= p-buf;
7935       }
7936       break;
7937     case ROW_TYPE:
7938     default:
7939       assert(1);
7940       return 1;
7941     }
7942   }
7943   buf[0]= '@';
7944   memcpy(buf + 1, quoted_id, id_len);
7945   buf[1 + id_len]= '=';
7946   protocol->store(buf, event_len, &my_charset_bin);
7947   my_free(buf);
7948   return 0;
7949 }
7950 #endif /* !MYSQL_CLIENT */
7951 
7952 
7953 User_var_log_event::
User_var_log_event(const char * buf,uint event_len,const Format_description_event * description_event)7954 	User_var_log_event(const char* buf, uint event_len,
7955 			   const Format_description_event* description_event)
7956   : binary_log::User_var_event(buf, event_len, description_event),
7957     Log_event(header(), footer())
7958 #ifndef MYSQL_CLIENT
7959     ,deferred(false), query_id(0)
7960 #endif
7961 {
7962   if (name != 0)
7963     is_valid_param= true;
7964 }
7965 
7966 
7967 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7968 bool User_var_log_event::write(IO_CACHE* file)
7969 {
7970   char buf[UV_NAME_LEN_SIZE];
7971   char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7972 	    UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
7973   uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
7974   uint unsigned_len= 0;
7975   uint buf1_length;
7976   ulong event_length;
7977 
7978   int4store(buf, name_len);
7979 
7980   if ((buf1[0]= is_null))
7981   {
7982     buf1_length= 1;
7983     val_len= 0;                                 // Length of 'pos'
7984   }
7985   else
7986   {
7987     buf1[1]= type;
7988     int4store(buf1 + 2, charset_number);
7989 
7990     switch (type) {
7991     case REAL_TYPE:
7992       float8store(buf2, *(double*) val);
7993       break;
7994     case INT_TYPE:
7995       int8store(buf2, *(longlong*) val);
7996       unsigned_len= 1;
7997       break;
7998     case DECIMAL_TYPE:
7999     {
8000       my_decimal *dec= (my_decimal *)val;
8001       dec->sanity_check();
8002       buf2[0]= (char)(dec->intg + dec->frac);
8003       buf2[1]= (char)dec->frac;
8004       decimal2bin(dec, buf2+2, buf2[0], buf2[1]);
8005       val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
8006       break;
8007     }
8008     case STRING_TYPE:
8009       pos= (uchar*) val;
8010       break;
8011     case ROW_TYPE:
8012     default:
8013       assert(1);
8014       return 0;
8015     }
8016     int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
8017     buf1_length= 10;
8018   }
8019 
8020   /* Length of the whole event */
8021   event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
8022 
8023   return (write_header(file, event_length) ||
8024           wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
8025 	  wrapper_my_b_safe_write(file, (uchar*) name, name_len)     ||
8026 	  wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
8027 	  wrapper_my_b_safe_write(file, pos, val_len) ||
8028           wrapper_my_b_safe_write(file, &flags, unsigned_len) ||
8029 	  write_footer(file));
8030 }
8031 #endif
8032 
8033 
8034 /*
8035   User_var_log_event::print()
8036 */
8037 
8038 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8039 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8040 {
8041   IO_CACHE *const head= &print_event_info->head_cache;
8042   char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
8043   char name_id[NAME_LEN];
8044   size_t quoted_len= 0;
8045 
8046   if (!print_event_info->short_form)
8047   {
8048     print_header(head, print_event_info, FALSE);
8049     my_b_printf(head, "\tUser_var\n");
8050   }
8051   my_stpcpy(name_id, name);
8052   name_id[name_len]= '\0';
8053   my_b_printf(head, "SET @");
8054   quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
8055                                           (const char *) name_id);
8056   quoted_id[quoted_len]= '\0';
8057   MY_ATTRIBUTE((unused)) int write_res=
8058     my_b_write(head, (uchar*) quoted_id, quoted_len);
8059   assert(write_res == 0);
8060 
8061   if (is_null)
8062   {
8063     my_b_printf(head, ":=NULL%s\n", print_event_info->delimiter);
8064   }
8065   else
8066   {
8067     switch (type) {
8068     case REAL_TYPE:
8069       double real_val;
8070       char real_buf[FMT_G_BUFSIZE(14)];
8071       float8get(&real_val, val);
8072       sprintf(real_buf, "%.14g", real_val);
8073       my_b_printf(head, ":=%s%s\n", real_buf, print_event_info->delimiter);
8074       break;
8075     case INT_TYPE:
8076       char int_buf[22];
8077       longlong10_to_str(uint8korr(val), int_buf,
8078                         ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
8079       my_b_printf(head, ":=%s%s\n", int_buf, print_event_info->delimiter);
8080       break;
8081     case DECIMAL_TYPE:
8082     {
8083       char str_buf[200];
8084       int str_len= sizeof(str_buf) - 1;
8085       int precision= (int)val[0];
8086       int scale= (int)val[1];
8087       decimal_digit_t dec_buf[10];
8088       decimal_t dec;
8089       dec.len= 10;
8090       dec.buf= dec_buf;
8091 
8092       bin2decimal((uchar*) val+2, &dec, precision, scale);
8093       decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
8094       str_buf[str_len]= 0;
8095       my_b_printf(head, ":=%s%s\n", str_buf, print_event_info->delimiter);
8096       break;
8097     }
8098     case STRING_TYPE:
8099     {
8100       /*
8101         Let's express the string in hex. That's the most robust way. If we
8102         print it in character form instead, we need to escape it with
8103         character_set_client which we don't know (we will know it in 5.0, but
8104         in 4.1 we don't know it easily when we are printing
8105         User_var_log_event). Explanation why we would need to bother with
8106         character_set_client (quoting Bar):
8107         > Note, the parser doesn't switch to another unescaping mode after
8108         > it has met a character set introducer.
8109         > For example, if an SJIS client says something like:
8110         > SET @a= _ucs2 \0a\0b'
8111         > the string constant is still unescaped according to SJIS, not
8112         > according to UCS2.
8113       */
8114       char *hex_str;
8115       CHARSET_INFO *cs;
8116 
8117       hex_str= (char *)my_malloc(key_memory_log_event,
8118                                  2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
8119       if (!hex_str)
8120         return;
8121       str_to_hex(hex_str, val, val_len);
8122       /*
8123         For proper behaviour when mysqlbinlog|mysql, we need to explicitely
8124         specify the variable's collation. It will however cause problems when
8125         people want to mysqlbinlog|mysql into another server not supporting the
8126         character set. But there's not much to do about this and it's unlikely.
8127       */
8128       if (!(cs= get_charset(charset_number, MYF(0))))
8129         /*
8130           Generate an unusable command (=> syntax error) is probably the best
8131           thing we can do here.
8132         */
8133         my_b_printf(head, ":=???%s\n", print_event_info->delimiter);
8134       else
8135         my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n",
8136                     cs->csname, hex_str, cs->name,
8137                     print_event_info->delimiter);
8138       my_free(hex_str);
8139     }
8140       break;
8141     case ROW_TYPE:
8142     default:
8143       assert(1);
8144       return;
8145     }
8146   }
8147 }
8148 #endif
8149 
8150 
8151 /*
8152   User_var_log_event::do_apply_event()
8153 */
8154 
8155 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8156 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
8157 {
8158   DBUG_ENTER("User_var_log_event::do_apply_event");
8159   Item *it= 0;
8160   CHARSET_INFO *charset;
8161   query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
8162 
8163   if (rli->deferred_events_collecting)
8164   {
8165     set_deferred(current_thd->query_id);
8166     int ret= rli->deferred_events->add(this);
8167     DBUG_RETURN(ret);
8168   }
8169   else if (is_deferred())
8170   {
8171     sav_query_id= current_thd->query_id;
8172     current_thd->query_id= query_id; /* recreating original time context */
8173   }
8174 
8175   if (!(charset= get_charset(charset_number, MYF(MY_WME))))
8176   {
8177     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8178                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8179                 "Invalid character set for User var event");
8180     DBUG_RETURN(1);
8181   }
8182   double real_val;
8183   longlong int_val;
8184 
8185   /*
8186     We are now in a statement until the associated query log event has
8187     been processed.
8188    */
8189   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
8190 
8191   if (is_null)
8192   {
8193     it= new Item_null();
8194   }
8195   else
8196   {
8197     switch (type) {
8198     case REAL_TYPE:
8199       if (val_len != 8)
8200       {
8201         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8202                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8203                     "Invalid variable length at User var event");
8204         DBUG_RETURN(1);
8205       }
8206       float8get(&real_val, val);
8207       it= new Item_float(real_val, 0);
8208       val= (char*) &real_val;		// Pointer to value in native format
8209       val_len= 8;
8210       break;
8211     case INT_TYPE:
8212       if (val_len != 8)
8213       {
8214         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8215                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8216                     "Invalid variable length at User var event");
8217         DBUG_RETURN(1);
8218       }
8219       int_val= (longlong) uint8korr(val);
8220       it= new Item_int(int_val);
8221       val= (char*) &int_val;		// Pointer to value in native format
8222       val_len= 8;
8223       break;
8224     case DECIMAL_TYPE:
8225     {
8226       if (val_len < 3)
8227       {
8228         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8229                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8230                     "Invalid variable length at User var event");
8231         DBUG_RETURN(1);
8232       }
8233       Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
8234       it= dec;
8235       val= (char *)dec->val_decimal(NULL);
8236       val_len= sizeof(my_decimal);
8237       break;
8238     }
8239     case STRING_TYPE:
8240       it= new Item_string(val, val_len, charset);
8241       break;
8242     case ROW_TYPE:
8243     default:
8244       assert(1);
8245       DBUG_RETURN(0);
8246     }
8247   }
8248   Item_func_set_user_var *e=
8249     new Item_func_set_user_var(Name_string(name, name_len, false), it, false);
8250   /*
8251     Item_func_set_user_var can't substitute something else on its place =>
8252     0 can be passed as last argument (reference on item)
8253 
8254     Fix_fields() can fail, in which case a call of update_hash() might
8255     crash the server, so if fix fields fails, we just return with an
8256     error.
8257   */
8258   if (e->fix_fields(thd, 0))
8259     DBUG_RETURN(1);
8260 
8261   /*
8262     A variable can just be considered as a table with
8263     a single record and with a single column. Thus, like
8264     a column value, it could always have IMPLICIT derivation.
8265    */
8266   e->update_hash(val, val_len, (Item_result)type, charset, DERIVATION_IMPLICIT,
8267                  (flags & binary_log::User_var_event::UNSIGNED_F));
8268   if (!is_deferred())
8269     free_root(thd->mem_root, 0);
8270   else
8271     current_thd->query_id= sav_query_id; /* restore current query's context */
8272 
8273   DBUG_RETURN(0);
8274 }
8275 
do_update_pos(Relay_log_info * rli)8276 int User_var_log_event::do_update_pos(Relay_log_info *rli)
8277 {
8278   rli->inc_event_relay_log_pos();
8279   return 0;
8280 }
8281 
8282 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)8283 User_var_log_event::do_shall_skip(Relay_log_info *rli)
8284 {
8285   /*
8286     It is a common error to set the slave skip counter to 1 instead
8287     of 2 when recovering from an insert which used a auto increment,
8288     rand, or user var.  Therefore, if the slave skip counter is 1, we
8289     just say that this event should be skipped by ignoring it, meaning
8290     that we do not change the value of the slave skip counter since it
8291     will be decreased by the following insert event.
8292   */
8293   return continue_group(rli);
8294 }
8295 #endif /* !MYSQL_CLIENT */
8296 
8297 
8298 /**************************************************************************
8299   Unknown_log_event methods
8300 **************************************************************************/
8301 
8302 #ifdef HAVE_REPLICATION
8303 #ifdef MYSQL_CLIENT
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info)8304 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
8305 {
8306   if (print_event_info->short_form)
8307     return;
8308 
8309   if (what != ENCRYPTED)
8310   {
8311     print_header(&print_event_info->head_cache, print_event_info, FALSE);
8312     my_b_printf(&print_event_info->head_cache, "\n# %s", "Unknown event\n");
8313   }
8314   else
8315     my_b_printf(&print_event_info->head_cache, "\n# %s", "Encrypted event\n");
8316 }
8317 #endif
8318 
8319 /**************************************************************************
8320 	Stop_log_event methods
8321 **************************************************************************/
8322 
8323 /*
8324   Stop_log_event::print()
8325 */
8326 
8327 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8328 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8329 {
8330   if (print_event_info->short_form)
8331     return;
8332 
8333   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8334   my_b_printf(&print_event_info->head_cache, "\tStop\n");
8335 }
8336 #endif /* MYSQL_CLIENT */
8337 
8338 
8339 #ifndef MYSQL_CLIENT
8340 /*
8341   The master stopped.  We used to clean up all temporary tables but
8342   this is useless as, as the master has shut down properly, it has
8343   written all DROP TEMPORARY TABLE (prepared statements' deletion is
8344   TODO only when we binlog prep stmts).  We used to clean up
8345   slave_load_tmpdir, but this is useless as it has been cleared at the
8346   end of LOAD DATA INFILE.  So we have nothing to do here.  The place
8347   were we must do this cleaning is in
8348   Start_log_event_v3::do_apply_event(), not here. Because if we come
8349   here, the master was sane.
8350 
8351   This must only be called from the Slave SQL thread, since it calls
8352   flush_relay_log_info().
8353 */
do_update_pos(Relay_log_info * rli)8354 int Stop_log_event::do_update_pos(Relay_log_info *rli)
8355 {
8356   int error_inc= 0;
8357   int error_flush= 0;
8358   /*
8359     We do not want to update master_log pos because we get a rotate event
8360     before stop, so by now group_master_log_name is set to the next log.
8361     If we updated it, we will have incorrect master coordinates and this
8362     could give false triggers in MASTER_POS_WAIT() that we have reached
8363     the target position when in fact we have not.
8364     The group position is always unchanged in MTS mode because the event
8365     is never executed so can't be scheduled to a Worker.
8366   */
8367   if ((thd->variables.option_bits & OPTION_BEGIN) || rli->is_parallel_exec())
8368     rli->inc_event_relay_log_pos();
8369   else
8370   {
8371     error_inc= rli->inc_group_relay_log_pos(0, true/*need_data_lock=true*/);
8372     error_flush= rli->flush_info(TRUE);
8373   }
8374   return (error_inc || error_flush);
8375 }
8376 
8377 #endif /* !MYSQL_CLIENT */
8378 #endif /* HAVE_REPLICATION */
8379 
8380 
8381 /**************************************************************************
8382 	Create_file_log_event methods
8383 **************************************************************************/
8384 
8385 #ifndef MYSQL_CLIENT
8386 /*
8387   Create_file_log_event::write_data_body()
8388 */
8389 
write_data_body(IO_CACHE * file)8390 bool Create_file_log_event::write_data_body(IO_CACHE* file)
8391 {
8392   bool res;
8393   if ((res= Load_log_event::write_data_body(file)) || fake_base)
8394     return res;
8395   return (event_encrypter.encrypt_and_write(file, (uchar*) "", 1) ||
8396           event_encrypter.encrypt_and_write(file, block, block_len));
8397 }
8398 
8399 
8400 /*
8401   Create_file_log_event::write_data_header()
8402 */
8403 
write_data_header(IO_CACHE * file)8404 bool Create_file_log_event::write_data_header(IO_CACHE* file)
8405 {
8406   bool res;
8407   uchar buf[Binary_log_event::CREATE_FILE_HEADER_LEN];
8408   if ((res= Load_log_event::write_data_header(file)) || fake_base)
8409     return res;
8410   int4store(buf + CF_FILE_ID_OFFSET, file_id);
8411   return event_encrypter.encrypt_and_write(file, buf, Binary_log_event::CREATE_FILE_HEADER_LEN) != 0;
8412 }
8413 
8414 
8415 /*
8416   Create_file_log_event::write_base()
8417 */
8418 
write_base(IO_CACHE * file)8419 bool Create_file_log_event::write_base(IO_CACHE* file)
8420 {
8421   bool res;
8422   fake_base= 1;                                 // pretend we are Load event
8423   common_header->type_code= Load_log_event::get_type_code();
8424   DBUG_EXECUTE_IF("simulate_cache_write_failure",
8425                   {
8426                   res= TRUE;
8427                   my_error(ER_UNKNOWN_ERROR, MYF(0));
8428                   return res;
8429                   });
8430   res= write(file);
8431   fake_base= 0;
8432   common_header->type_code= binary_log::CREATE_FILE_EVENT;
8433   return res;
8434 }
8435 
8436 #endif /* !MYSQL_CLIENT */
8437 
8438 /*
8439   Create_file_log_event ctor
8440 */
8441 
8442 Create_file_log_event::
Create_file_log_event(const char * buf,uint len,const Format_description_event * description_event)8443 Create_file_log_event(const char* buf, uint len,
8444                       const Format_description_event* description_event)
8445  : binary_log::Load_event(buf, 0, description_event),
8446   Load_log_event(buf,0,description_event),
8447   binary_log::Create_file_event(buf, len, description_event)
8448 {
8449   DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
8450   /**
8451     We need to set exec_time here, which is ued to calcutate seconds behind
8452     master on the slave.
8453   */
8454   exec_time= load_exec_time;
8455   sql_ex.data_info= sql_ex_data;
8456   if (inited_from_old || block != 0)
8457     is_valid_param= true;
8458   if (fake_base)
8459     common_header->type_code= Load_log_event::get_type_code();
8460   else
8461     common_header->type_code= binary_log::CREATE_FILE_EVENT;
8462   DBUG_VOID_RETURN;
8463 }
8464 
8465 
8466 /*
8467   Create_file_log_event::print()
8468 */
8469 
8470 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info,bool enable_local)8471 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
8472 				  bool enable_local)
8473 {
8474   if (print_event_info->short_form)
8475   {
8476     if (enable_local && check_fname_outside_temp_buf())
8477       Load_log_event::print(file, print_event_info);
8478     return;
8479   }
8480 
8481   if (enable_local)
8482   {
8483     Load_log_event::print(file, print_event_info,
8484 			  !check_fname_outside_temp_buf());
8485     /**
8486       reduce the size of io cache so that the write function is called
8487       for every call to my_b_printf().
8488      */
8489     DBUG_EXECUTE_IF ("simulate_create_event_write_error",
8490                      {(&print_event_info->head_cache)->write_pos=
8491                      (&print_event_info->head_cache)->write_end;
8492                      DBUG_SET("+d,simulate_file_write_error");});
8493     /*
8494        That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
8495        SHOW BINLOG EVENTS we don't.
8496     */
8497     my_b_printf(&print_event_info->head_cache, "#");
8498   }
8499 
8500   my_b_printf(&print_event_info->head_cache,
8501               " file_id: %d  block_len: %d\n", file_id, block_len);
8502 }
8503 
8504 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8505 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8506 {
8507   print(file, print_event_info, 0);
8508 }
8509 #endif /* MYSQL_CLIENT */
8510 
8511 
8512 /*
8513   Create_file_log_event::pack_info()
8514 */
8515 
8516 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8517 int Create_file_log_event::pack_info(Protocol *protocol)
8518 {
8519   char buf[NAME_LEN*2 + 30 + 21*2], *pos;
8520   pos= my_stpcpy(buf, "db=");
8521   memcpy(pos, db, db_len);
8522   pos= my_stpcpy(pos + db_len, ";table=");
8523   memcpy(pos, table_name, table_name_len);
8524   pos= my_stpcpy(pos + table_name_len, ";file_id=");
8525   pos= int10_to_str((long) file_id, pos, 10);
8526   pos= my_stpcpy(pos, ";block_len=");
8527   pos= int10_to_str((long) block_len, pos, 10);
8528   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8529   return 0;
8530 }
8531 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8532 
8533 
8534 /**
8535   Create_file_log_event::do_apply_event()
8536   Constructor for Create_file_log_event to intantiate an event
8537   from the relay log on the slave.
8538 
8539   @retval
8540     0           Success
8541   @retval
8542     1           Failure
8543 */
8544 
8545 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8546 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
8547 {
8548   char fname_buf[FN_REFLEN+TEMP_FILE_MAX_LEN];
8549   char *ext;
8550   int fd = -1;
8551   IO_CACHE file;
8552   int error = 1;
8553 
8554   lex_start(thd);
8555   mysql_reset_thd_for_next_command(thd);
8556   THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
8557   memset(&file, 0, sizeof(file));
8558   ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
8559   /* old copy may exist already */
8560   mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8561   /**
8562     To simulate file creation failure, convert the file name to a
8563     directory by appending a "/" to the file name.
8564    */
8565   DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event",
8566                   {
8567                   strcat(fname_buf,"/");
8568                   });
8569   if ((fd= mysql_file_create(key_file_log_event_info,
8570                              fname_buf, CREATE_MODE,
8571                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8572                              MYF(MY_WME))) < 0 ||
8573       init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
8574 		    MYF(MY_WME|MY_NABP)))
8575   {
8576     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8577                 "Error in Create_file event: could not open file '%s', '%s'",
8578                 fname_buf, thd->get_stmt_da()->message_text());
8579     goto err;
8580   }
8581 
8582   // a trick to avoid allocating another buffer
8583   fname= fname_buf;
8584   fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
8585   if (write_base(&file))
8586   {
8587     my_stpcpy(ext, ".info"); // to have it right in the error message
8588     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8589                 "Error in Create_file event: could not write to file '%s', '%s'",
8590                 fname_buf, thd->get_stmt_da()->message_text());
8591     goto err;
8592   }
8593   end_io_cache(&file);
8594   mysql_file_close(fd, MYF(0));
8595 
8596   // fname_buf now already has .data, not .info, because we did our trick
8597   /* old copy may exist already */
8598   mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8599   DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event_2",
8600                   {
8601                   strcat(fname_buf, "/");
8602                   });
8603   if ((fd= mysql_file_create(key_file_log_event_data,
8604                              fname_buf, CREATE_MODE,
8605                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8606                              MYF(MY_WME))) < 0)
8607   {
8608     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8609                 "Error in Create_file event: could not open file '%s', '%s'",
8610                 fname_buf, thd->get_stmt_da()->message_text());
8611     goto err;
8612   }
8613   /**
8614     To simulate file write failure,close the file before the write operation.
8615     Write will fail with an error reporting file is UNOPENED.
8616    */
8617   DBUG_EXECUTE_IF("simulate_file_write_error_create_log_event",
8618                   {
8619                   mysql_file_close(fd, MYF(0));
8620                   });
8621   if (mysql_file_write(fd, block, block_len, MYF(MY_WME+MY_NABP)))
8622   {
8623     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8624                 "Error in Create_file event: write to '%s' failed, '%s'",
8625                 fname_buf, thd->get_stmt_da()->message_text());
8626     goto err;
8627   }
8628   error=0;					// Everything is ok
8629 
8630 err:
8631   if (error)
8632   {
8633     end_io_cache(&file);
8634     /*
8635       Error occured. Delete .info and .data files if they are created.
8636     */
8637     my_stpcpy(ext,".info");
8638     mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8639     my_stpcpy(ext,".data");
8640     mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8641   }
8642   if (fd >= 0)
8643     mysql_file_close(fd, MYF(0));
8644   return error != 0;
8645 }
8646 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8647 
8648 
8649 /**************************************************************************
8650 	Append_block_log_event methods
8651 **************************************************************************/
8652 
8653 /*
8654   Append_block_log_event ctor
8655 */
8656 
8657 #ifndef MYSQL_CLIENT
Append_block_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)8658 Append_block_log_event::Append_block_log_event(THD *thd_arg,
8659                                                const char *db_arg,
8660 					       uchar *block_arg,
8661 					       uint block_len_arg,
8662 					       bool using_trans)
8663   : binary_log::Append_block_event(db_arg, block_arg, block_len_arg, thd_arg->file_id),
8664     Log_event(thd_arg, 0,
8665               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8666                             Log_event::EVENT_STMT_CACHE,
8667               Log_event::EVENT_NORMAL_LOGGING,
8668               header(), footer())
8669 {
8670   if (block != 0)
8671     is_valid_param= true;
8672 }
8673 #endif
8674 
8675 
8676 /*
8677   Append_block_log_event ctor
8678 */
8679 
Append_block_log_event(const char * buf,uint len,const Format_description_event * description_event)8680 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
8681                                                const Format_description_event*
8682                                                description_event)
8683   : binary_log::Append_block_event(buf, len, description_event),
8684     Log_event(header(), footer())
8685 {
8686 
8687   DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
8688   if (block != 0)
8689     is_valid_param= true;
8690   DBUG_VOID_RETURN;
8691 }
8692 
8693 
8694 /*
8695   Append_block_log_event::write()
8696 */
8697 
8698 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8699 bool Append_block_log_event::write(IO_CACHE* file)
8700 {
8701   uchar buf[Binary_log_event::APPEND_BLOCK_HEADER_LEN];
8702   int4store(buf + AB_FILE_ID_OFFSET, file_id);
8703   return (write_header(file, Binary_log_event::APPEND_BLOCK_HEADER_LEN +
8704                        block_len) ||
8705           wrapper_my_b_safe_write(file, buf,
8706                                   Binary_log_event::APPEND_BLOCK_HEADER_LEN) ||
8707 	  wrapper_my_b_safe_write(file, block, block_len) ||
8708 	  write_footer(file));
8709 }
8710 #endif
8711 
8712 
8713 /*
8714   Append_block_log_event::print()
8715 */
8716 
8717 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8718 void Append_block_log_event::print(FILE* file,
8719 				   PRINT_EVENT_INFO* print_event_info)
8720 {
8721   if (print_event_info->short_form)
8722     return;
8723   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8724   my_b_printf(&print_event_info->head_cache,
8725               "\n#%s: file_id: %d  block_len: %d\n",
8726               get_type_str(), file_id, block_len);
8727 }
8728 #endif /* MYSQL_CLIENT */
8729 
8730 
8731 /*
8732   Append_block_log_event::pack_info()
8733 */
8734 
8735 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8736 int Append_block_log_event::pack_info(Protocol *protocol)
8737 {
8738   char buf[256];
8739   size_t length;
8740   length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
8741                       file_id, block_len);
8742   protocol->store(buf, length, &my_charset_bin);
8743   return 0;
8744 }
8745 
8746 
8747 /*
8748   Append_block_log_event::get_create_or_append()
8749 */
8750 
get_create_or_append() const8751 int Append_block_log_event::get_create_or_append() const
8752 {
8753   return 0; /* append to the file, fail if not exists */
8754 }
8755 
8756 /*
8757   Append_block_log_event::do_apply_event()
8758 */
8759 
do_apply_event(Relay_log_info const * rli)8760 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
8761 {
8762   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8763   int fd;
8764   int error = 1;
8765   DBUG_ENTER("Append_block_log_event::do_apply_event");
8766 
8767   THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
8768   slave_load_file_stem(fname, file_id, server_id, ".data");
8769   if (get_create_or_append())
8770   {
8771     /*
8772       Usually lex_start() is called by mysql_parse(), but we need it here
8773       as the present method does not call mysql_parse().
8774     */
8775     lex_start(thd);
8776     mysql_reset_thd_for_next_command(thd);
8777     /* old copy may exist already */
8778     mysql_file_delete(key_file_log_event_data, fname, MYF(0));
8779     DBUG_EXECUTE_IF("simulate_file_create_error_Append_block_event",
8780                     {
8781                     strcat(fname, "/");
8782                     });
8783     if ((fd= mysql_file_create(key_file_log_event_data,
8784                                fname, CREATE_MODE,
8785                                O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8786                                MYF(MY_WME))) < 0)
8787     {
8788       rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8789                   "Error in %s event: could not create file '%s', '%s'",
8790                   get_type_str(), fname, thd->get_stmt_da()->message_text());
8791       goto err;
8792     }
8793   }
8794   else if ((fd= mysql_file_open(key_file_log_event_data,
8795                                 fname,
8796                                 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
8797                                 MYF(MY_WME))) < 0)
8798   {
8799     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8800                 "Error in %s event: could not open file '%s', '%s'",
8801                 get_type_str(), fname, thd->get_stmt_da()->message_text());
8802     goto err;
8803   }
8804   DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
8805                   {
8806                     my_delete_allow_opened(fname, MYF(0));
8807                   });
8808 
8809   DBUG_EXECUTE_IF("simulate_file_write_error_Append_block_event",
8810                   {
8811                     mysql_file_close(fd, MYF(0));
8812                   });
8813   if (mysql_file_write(fd, block, block_len, MYF(MY_WME+MY_NABP)))
8814   {
8815     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
8816                 "Error in %s event: write to '%s' failed, '%s'",
8817                 get_type_str(), fname, thd->get_stmt_da()->message_text());
8818     goto err;
8819   }
8820   error=0;
8821 
8822 err:
8823   if (fd >= 0)
8824     mysql_file_close(fd, MYF(0));
8825   DBUG_RETURN(error);
8826 }
8827 #endif
8828 
8829 
8830 /**************************************************************************
8831 	Delete_file_log_event methods
8832 **************************************************************************/
8833 
8834 /*
8835   Delete_file_log_event ctor
8836 */
8837 
8838 #ifndef MYSQL_CLIENT
Delete_file_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8839 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
8840 					     bool using_trans)
8841   : binary_log::Delete_file_event(thd_arg->file_id, db_arg),
8842     Log_event(thd_arg, 0,
8843               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8844                             Log_event::EVENT_STMT_CACHE,
8845               Log_event::EVENT_NORMAL_LOGGING,
8846               header(), footer())
8847 {
8848   if (file_id != 0)
8849     is_valid_param= true;
8850 }
8851 #endif
8852 
8853 /*
8854   Delete_file_log_event ctor
8855 */
8856 
Delete_file_log_event(const char * buf,uint len,const Format_description_event * description_event)8857 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
8858                                              const Format_description_event*
8859                                              description_event)
8860   : binary_log::Delete_file_event(buf, len, description_event),
8861     Log_event(header(), footer())
8862 {
8863   if (file_id != 0)
8864     is_valid_param= true;
8865 }
8866 
8867 
8868 /*
8869   Delete_file_log_event::write()
8870 */
8871 
8872 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8873 bool Delete_file_log_event::write(IO_CACHE* file)
8874 {
8875  uchar buf[Binary_log_event::DELETE_FILE_HEADER_LEN];
8876  int4store(buf + DF_FILE_ID_OFFSET, file_id);
8877  return (write_header(file, sizeof(buf)) ||
8878          wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8879 	 write_footer(file));
8880 }
8881 #endif
8882 
8883 
8884 /*
8885   Delete_file_log_event::print()
8886 */
8887 
8888 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8889 void Delete_file_log_event::print(FILE* file,
8890 				  PRINT_EVENT_INFO* print_event_info)
8891 {
8892   if (print_event_info->short_form)
8893     return;
8894   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8895   my_b_printf(&print_event_info->head_cache,
8896               "\n#Delete_file: file_id=%u\n", file_id);
8897 }
8898 #endif /* MYSQL_CLIENT */
8899 
8900 /*
8901   Delete_file_log_event::pack_info()
8902 */
8903 
8904 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8905 int Delete_file_log_event::pack_info(Protocol *protocol)
8906 {
8907   char buf[64];
8908   size_t length;
8909   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8910   protocol->store(buf, length, &my_charset_bin);
8911   return 0;
8912 }
8913 #endif
8914 
8915 /*
8916   Delete_file_log_event::do_apply_event()
8917 */
8918 
8919 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8920 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
8921 {
8922   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8923   lex_start(thd);
8924   mysql_reset_thd_for_next_command(thd);
8925   char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
8926   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8927   my_stpcpy(ext, ".info");
8928   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8929   return 0;
8930 }
8931 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8932 
8933 
8934 /**************************************************************************
8935 	Execute_load_log_event methods
8936 **************************************************************************/
8937 
8938 /*
8939   Execute_load_log_event ctor
8940 */
8941 
8942 #ifndef MYSQL_CLIENT
Execute_load_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8943 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
8944                                                const char* db_arg,
8945 					       bool using_trans)
8946 : binary_log::Execute_load_event(thd_arg->file_id, db_arg),
8947   Log_event(thd_arg, 0,
8948              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8949                            Log_event::EVENT_STMT_CACHE,
8950              Log_event::EVENT_NORMAL_LOGGING,
8951              header(), footer())
8952 {
8953   if (file_id != 0)
8954     is_valid_param= true;
8955 }
8956 #endif
8957 
8958 
8959 /*
8960   Execute_load_log_event ctor
8961 */
8962 
Execute_load_log_event(const char * buf,uint len,const Format_description_event * description_event)8963 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
8964                                                const Format_description_event*
8965                                                description_event)
8966 : binary_log::Execute_load_event(buf, len, description_event),
8967   Log_event(header(), footer())
8968 {
8969   if (file_id != 0)
8970     is_valid_param= true;
8971 }
8972 
8973 
8974 /*
8975   Execute_load_log_event::write()
8976 */
8977 
8978 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8979 bool Execute_load_log_event::write(IO_CACHE* file)
8980 {
8981   uchar buf[Binary_log_event::EXEC_LOAD_HEADER_LEN];
8982   int4store(buf + EL_FILE_ID_OFFSET, file_id);
8983   return (write_header(file, sizeof(buf)) ||
8984           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8985 	  write_footer(file));
8986 }
8987 #endif
8988 
8989 
8990 /*
8991   Execute_load_log_event::print()
8992 */
8993 
8994 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8995 void Execute_load_log_event::print(FILE* file,
8996 				   PRINT_EVENT_INFO* print_event_info)
8997 {
8998   if (print_event_info->short_form)
8999     return;
9000   print_header(&print_event_info->head_cache, print_event_info, FALSE);
9001   my_b_printf(&print_event_info->head_cache, "\n#Exec_load: file_id=%d\n",
9002               file_id);
9003 }
9004 #endif
9005 
9006 /*
9007   Execute_load_log_event::pack_info()
9008 */
9009 
9010 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9011 int Execute_load_log_event::pack_info(Protocol *protocol)
9012 {
9013   char buf[64];
9014   size_t length;
9015   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
9016   protocol->store(buf, length, &my_charset_bin);
9017   return 0;
9018 }
9019 
9020 
9021 /*
9022   Execute_load_log_event::do_apply_event()
9023 */
9024 
do_apply_event(Relay_log_info const * rli)9025 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
9026 {
9027   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
9028   char *ext;
9029   int fd;
9030   int error= 1;
9031   IO_CACHE file;
9032   Load_log_event *lev= 0;
9033 
9034   lex_start(thd);
9035   mysql_reset_thd_for_next_command(thd);
9036   ext= slave_load_file_stem(fname, file_id, server_id, ".info");
9037   /**
9038     To simulate file open failure, convert the file name to a
9039     directory by appending a "/" to the file name. File open
9040     will fail with an error reporting it is not a directory.
9041    */
9042   DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
9043                   {
9044                   strcat(fname,"/");
9045                   });
9046   if ((fd= mysql_file_open(key_file_log_event_info,
9047                            fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
9048                            MYF(MY_WME))) < 0 ||
9049       init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
9050 		    MYF(MY_WME|MY_NABP)))
9051   {
9052     rli->report(ERROR_LEVEL, thd->get_stmt_da()->mysql_errno(),
9053                 "Error in Exec_load event: could not open file, '%s'",
9054                 thd->get_stmt_da()->message_text());
9055     goto err;
9056   }
9057   if (!(lev= (Load_log_event*)
9058         Log_event::read_log_event(&file,
9059                                   (mysql_mutex_t*) 0,
9060                                   rli->get_rli_description_event(),
9061                                   opt_slave_sql_verify_checksum)) ||
9062       lev->get_type_code() != binary_log::NEW_LOAD_EVENT)
9063   {
9064     rli->report(ERROR_LEVEL, ER_FILE_CORRUPT, ER(ER_FILE_CORRUPT),
9065                 fname);
9066     goto err;
9067   }
9068   lev->thd = thd;
9069   /*
9070     lev->do_apply_event should use rli only for errors.
9071     lev->do_apply_event is the place where the table is loaded (it
9072     calls mysql_load()).
9073   */
9074   if (lev->do_apply_event(0,rli,1))
9075   {
9076     /*
9077       We want to indicate the name of the file that could not be loaded
9078       (SQL_LOADxxx).
9079       But as we are here we are sure the error is in rli->last_slave_error and
9080       rli->last_slave_errno (example of error: duplicate entry for key), so we
9081       don't want to overwrite it with the filename.
9082       What we want instead is add the filename to the current error message.
9083     */
9084     char *tmp= my_strdup(key_memory_log_event,
9085                          rli->last_error().message, MYF(MY_WME));
9086     if (tmp)
9087     {
9088       rli->report(ERROR_LEVEL, rli->last_error().number,
9089                   "%s. Failed executing load from '%s'", tmp, fname);
9090       my_free(tmp);
9091     }
9092     goto err;
9093   }
9094   /*
9095     We have an open file descriptor to the .info file; we need to close it
9096     or Windows will refuse to delete the file in mysql_file_delete().
9097   */
9098   if (fd >= 0)
9099   {
9100     mysql_file_close(fd, MYF(0));
9101     end_io_cache(&file);
9102     fd= -1;
9103   }
9104   error = 0;
9105 
9106 err:
9107   DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
9108                   {
9109                      my_stpcpy(ext, ".info");
9110                   });
9111   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
9112   my_stpcpy(ext, ".data");
9113   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9114   delete lev;
9115   if (fd >= 0)
9116   {
9117     mysql_file_close(fd, MYF(0));
9118     end_io_cache(&file);
9119   }
9120   return error;
9121 }
9122 
9123 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9124 
9125 
9126 /**************************************************************************
9127 	Begin_load_query_log_event methods
9128 **************************************************************************/
9129 
9130 #ifndef MYSQL_CLIENT
9131 Begin_load_query_log_event::
Begin_load_query_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)9132 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
9133                            uint block_len_arg, bool using_trans)
9134  : binary_log::Append_block_event(db_arg, block_arg, block_len_arg,
9135                                   thd_arg->file_id),
9136    Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
9137                           using_trans),
9138    binary_log::Begin_load_query_event()
9139 {
9140   common_header->type_code= binary_log::BEGIN_LOAD_QUERY_EVENT;
9141   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
9142 }
9143 #endif
9144 
9145 
9146 Begin_load_query_log_event::
Begin_load_query_log_event(const char * buf,uint len,const Format_description_event * desc_event)9147 Begin_load_query_log_event(const char* buf, uint len,
9148                            const Format_description_event* desc_event)
9149   : binary_log::Append_block_event(buf, len, desc_event),
9150     Append_block_log_event(buf, len, desc_event),
9151     binary_log::Begin_load_query_event(buf, len, desc_event)
9152 {
9153 }
9154 
9155 
9156 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_create_or_append() const9157 int Begin_load_query_log_event::get_create_or_append() const
9158 {
9159   return 1; /* create the file */
9160 }
9161 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9162 
9163 
9164 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9165 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)9166 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
9167 {
9168   /*
9169     If the slave skip counter is 1, then we should not start executing
9170     on the next event.
9171   */
9172   return continue_group(rli);
9173 }
9174 #endif
9175 
9176 
9177 /**************************************************************************
9178 	Execute_load_query_log_event methods
9179 **************************************************************************/
9180 
9181 
9182 #ifndef MYSQL_CLIENT
9183 Execute_load_query_log_event::
Execute_load_query_log_event(THD * thd_arg,const char * query_arg,ulong query_length_arg,uint fn_pos_start_arg,uint fn_pos_end_arg,binary_log::enum_load_dup_handling dup_handling_arg,bool using_trans,bool immediate,bool suppress_use,int errcode)9184 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
9185                              ulong query_length_arg, uint fn_pos_start_arg,
9186                              uint fn_pos_end_arg,
9187                              binary_log::enum_load_dup_handling dup_handling_arg,
9188                              bool using_trans, bool immediate, bool suppress_use,
9189                              int errcode)
9190 : binary_log::Query_event(query_arg, thd_arg->catalog().str, thd_arg->db().str,
9191                           query_length_arg,
9192                           thd_arg->thread_id(), thd_arg->variables.sql_mode,
9193                           thd_arg->variables.auto_increment_increment,
9194                           thd_arg->variables.auto_increment_offset,
9195                           thd_arg->variables.lc_time_names->number,
9196                           (ulonglong)thd_arg->table_map_for_update,
9197                           errcode,
9198                           thd_arg->db().str ? strlen(thd_arg->db().str) : 0,
9199                           thd_arg->catalog().str ? strlen(thd_arg->catalog().str) : 0),
9200   Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
9201                   suppress_use, errcode),
9202   binary_log::Execute_load_query_event(thd_arg->file_id, fn_pos_start_arg,
9203                            fn_pos_end_arg, dup_handling_arg)
9204 {
9205   if (Query_log_event::is_valid() && file_id != 0)
9206     is_valid_param= true;
9207   common_header->type_code= binary_log::EXECUTE_LOAD_QUERY_EVENT;
9208 }
9209 #endif /* !MYSQL_CLIENT */
9210 
9211 
9212 Execute_load_query_log_event::
Execute_load_query_log_event(const char * buf,uint event_len,const Format_description_event * desc_event)9213 Execute_load_query_log_event(const char* buf, uint event_len,
9214                              const Format_description_event* desc_event)
9215   : binary_log::Query_event(buf, event_len, desc_event,
9216                             binary_log::EXECUTE_LOAD_QUERY_EVENT),
9217     Query_log_event(buf, event_len, desc_event,
9218                     binary_log::EXECUTE_LOAD_QUERY_EVENT),
9219     binary_log::Execute_load_query_event(buf, event_len, desc_event)
9220 {
9221   if (!Query_log_event::is_valid())
9222   {
9223     //clear all the variables set in execute_load_query_event
9224     file_id= 0; fn_pos_start= 0; fn_pos_end= 0;
9225     dup_handling= binary_log::LOAD_DUP_ERROR;
9226   }
9227   if (Query_log_event::is_valid() && file_id != 0)
9228     is_valid_param= true;
9229 }
9230 
9231 
get_post_header_size_for_derived()9232 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
9233 {
9234   return Binary_log_event::EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
9235 }
9236 
9237 
9238 #ifndef MYSQL_CLIENT
9239 bool
write_post_header_for_derived(IO_CACHE * file)9240 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
9241 {
9242   uchar buf[Binary_log_event::EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
9243   int4store(buf, file_id);
9244   int4store(buf + 4, fn_pos_start);
9245   int4store(buf + 4 + 4, fn_pos_end);
9246   *(buf + 4 + 4 + 4)= (uchar) dup_handling;
9247   return wrapper_my_b_safe_write(file, buf, Binary_log_event::EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
9248 }
9249 #endif
9250 
9251 
9252 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)9253 void Execute_load_query_log_event::print(FILE* file,
9254                                          PRINT_EVENT_INFO* print_event_info)
9255 {
9256   print(file, print_event_info, 0);
9257 }
9258 
9259 /**
9260   Prints the query as LOAD DATA LOCAL and with rewritten filename.
9261 */
print(FILE * file,PRINT_EVENT_INFO * print_event_info,const char * local_fname)9262 void Execute_load_query_log_event::print(FILE* file,
9263                                          PRINT_EVENT_INFO* print_event_info,
9264                                          const char *local_fname)
9265 {
9266   MY_ATTRIBUTE((unused)) int write_res;
9267   IO_CACHE *const head= &print_event_info->head_cache;
9268 
9269   print_query_header(head, print_event_info);
9270   /**
9271     reduce the size of io cache so that the write function is called
9272     for every call to my_b_printf().
9273    */
9274   DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
9275                    {head->write_pos= head->write_end;
9276                    DBUG_SET("+d,simulate_file_write_error");});
9277 
9278   if (local_fname)
9279   {
9280     write_res= my_b_write(head, (uchar*) query, fn_pos_start);
9281     assert(write_res == 0);
9282     my_b_printf(head, " LOCAL INFILE ");
9283     pretty_print_str(head, local_fname, strlen(local_fname));
9284 
9285     if (dup_handling == binary_log::LOAD_DUP_REPLACE)
9286       my_b_printf(head, " REPLACE");
9287     my_b_printf(head, " INTO");
9288     write_res= my_b_write(head, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
9289     assert(write_res == 0);
9290     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9291   }
9292   else
9293   {
9294     write_res= my_b_write(head, (uchar*) query, q_len);
9295     assert(write_res == 0);
9296     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9297   }
9298 
9299   if (!print_event_info->short_form)
9300     my_b_printf(head, "# file_id: %d \n", file_id);
9301 }
9302 #endif
9303 
9304 
9305 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9306 int Execute_load_query_log_event::pack_info(Protocol *protocol)
9307 {
9308   char *buf, *pos;
9309   if (!(buf= (char*) my_malloc(key_memory_log_event,
9310                                9 + (db_len * 2) + 2 + q_len + 10 + 21,
9311                                MYF(MY_WME))))
9312     return 1;
9313   pos= buf;
9314   if (db && db_len)
9315   {
9316     /*
9317       Statically allocates room to store '\0' and an identifier
9318       that may have NAME_LEN * 2 due to quoting and there are
9319       two quoting characters that wrap them.
9320     */
9321     char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
9322     size_t size= 0;
9323     size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
9324     pos= my_stpcpy(buf, "use ");
9325     memcpy(pos, quoted_db, size);
9326     pos= my_stpcpy(pos + size, "; ");
9327   }
9328   if (query && q_len)
9329   {
9330     memcpy(pos, query, q_len);
9331     pos+= q_len;
9332   }
9333   pos= my_stpcpy(pos, " ;file_id=");
9334   pos= int10_to_str((long) file_id, pos, 10);
9335   protocol->store(buf, pos-buf, &my_charset_bin);
9336   my_free(buf);
9337   return 0;
9338 }
9339 
9340 
9341 int
do_apply_event(Relay_log_info const * rli)9342 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
9343 {
9344   char *p;
9345   char *buf;
9346   char *fname;
9347   char *fname_end;
9348   int error;
9349 
9350   buf= (char*) my_malloc(key_memory_log_event,
9351                          q_len + 1 - (fn_pos_end - fn_pos_start) +
9352                          (FN_REFLEN + TEMP_FILE_MAX_LEN) + 10 + 8 + 5, MYF(MY_WME));
9353 
9354   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
9355 
9356   /* Replace filename and LOCAL keyword in query before executing it */
9357   if (buf == NULL)
9358   {
9359     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9360                 ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
9361     return 1;
9362   }
9363 
9364   p= buf;
9365   memcpy(p, query, fn_pos_start);
9366   p+= fn_pos_start;
9367   fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
9368   p= slave_load_file_stem(p, file_id, server_id, ".data");
9369   fname_end= p= strend(p);                      // Safer than p=p+5
9370   *(p++)='\'';
9371   switch (dup_handling) {
9372   case binary_log::LOAD_DUP_IGNORE:
9373     p= strmake(p, STRING_WITH_LEN(" IGNORE"));
9374     break;
9375   case binary_log::LOAD_DUP_REPLACE:
9376     p= strmake(p, STRING_WITH_LEN(" REPLACE"));
9377     break;
9378   default:
9379     /* Ordinary load data */
9380     break;
9381   }
9382   p= strmake(p, STRING_WITH_LEN(" INTO "));
9383   p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
9384 
9385   error= Query_log_event::do_apply_event(rli, buf, p-buf);
9386 
9387   /* Forging file name for deletion in same buffer */
9388   *fname_end= 0;
9389 
9390   /*
9391     If there was an error the slave is going to stop, leave the
9392     file so that we can re-execute this event at START SLAVE.
9393   */
9394   if (!error)
9395     mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9396 
9397   my_free(buf);
9398   return error;
9399 }
9400 #endif
9401 
9402 
9403 /**************************************************************************
9404 	sql_ex_info methods
9405 **************************************************************************/
9406 
9407 /*
9408   sql_ex_info::write_data()
9409 */
9410 
write_data(IO_CACHE * file)9411 bool sql_ex_info::write_data(IO_CACHE* file)
9412 {
9413   if (data_info.new_format())
9414   {
9415     return (write_str_at_most_255_bytes(file, data_info.field_term,
9416                                         (uint) data_info.field_term_len, event_encrypter) ||
9417 	    write_str_at_most_255_bytes(file, data_info.enclosed,
9418                                         (uint) data_info.enclosed_len, event_encrypter) ||
9419 	    write_str_at_most_255_bytes(file, data_info.line_term,
9420                                         (uint) data_info.line_term_len, event_encrypter) ||
9421 	    write_str_at_most_255_bytes(file, data_info.line_start,
9422                                         (uint) data_info.line_start_len, event_encrypter) ||
9423 	    write_str_at_most_255_bytes(file, data_info.escaped,
9424                                         (uint) data_info.escaped_len, event_encrypter) ||
9425             event_encrypter->encrypt_and_write(file,(uchar*) &(data_info.opt_flags), 1));
9426   }
9427   else
9428   {
9429     /**
9430       @todo This is sensitive to field padding. We should write a
9431       char[7], not an old_sql_ex. /sven
9432     */
9433     binary_log::old_sql_ex old_ex;
9434     old_ex.field_term= *(data_info.field_term);
9435     old_ex.enclosed=   *(data_info.enclosed);
9436     old_ex.line_term=  *(data_info.line_term);
9437     old_ex.line_start= *(data_info.line_start);
9438     old_ex.escaped=    *(data_info.escaped);
9439     old_ex.opt_flags=  data_info.opt_flags;
9440     old_ex.empty_flags= data_info.empty_flags;
9441     return event_encrypter->encrypt_and_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
9442   }
9443 }
9444 
9445 
9446 /**
9447   sql_ex_info::init()
9448   This method initializes the members of strcuture variable sql_ex_info,
9449   defined in a Load_log_event. The structure, initializes the sub struct
9450   data_info, with the subclause characters in a LOAD_DATA_INFILE query.
9451 
9452 */
init(const char * buf,const char * buf_end,bool use_new_format)9453 const char *sql_ex_info::init(const char *buf, const char *buf_end,
9454                               bool use_new_format)
9455 {
9456   return data_info.init(buf, buf_end, use_new_format);
9457 }
9458 #ifndef NDEBUG
9459 #ifndef MYSQL_CLIENT
9460 static uchar dbug_extra_row_data_val= 0;
9461 
9462 /**
9463    set_extra_data
9464 
9465    Called during self-test to generate various
9466    self-consistent binlog row event extra
9467    thread data structures which can be checked
9468    when reading the binlog.
9469 
9470    @param arr  Buffer to use
9471 */
set_extra_data(uchar * arr)9472 const uchar* set_extra_data(uchar* arr)
9473 {
9474   uchar val= (dbug_extra_row_data_val++) %
9475     (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
9476   arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
9477   arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
9478   for (uchar i=0; i<val; i++)
9479     arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
9480 
9481   return arr;
9482 }
9483 
9484 #endif // #ifndef MYSQL_CLIENT
9485 
9486 /**
9487    check_extra_data
9488 
9489    Called during self-test to check that
9490    binlog row event extra data is self-
9491    consistent as defined by the set_extra_data
9492    function above.
9493 
9494    Will assert(false) if not.
9495 
9496    @param extra_row_data
9497 */
check_extra_data(uchar * extra_row_data)9498 void check_extra_data(uchar* extra_row_data)
9499 {
9500   assert(extra_row_data);
9501   uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
9502   uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
9503   assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
9504   for (uint16 i= 0; i < val; i++)
9505   {
9506     assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
9507   }
9508 }
9509 
9510 #endif  // #ifndef NDEBUG
9511 
9512 /**************************************************************************
9513 	Rows_log_event member functions
9514 **************************************************************************/
9515 
9516 #ifndef MYSQL_CLIENT
Rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,MY_BITMAP const * cols,bool using_trans,Log_event_type event_type,const uchar * extra_row_info)9517 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, const Table_id& tid,
9518                                MY_BITMAP const *cols, bool using_trans,
9519                                Log_event_type event_type,
9520                                const uchar* extra_row_info)
9521  : binary_log::Rows_event(event_type),
9522    Log_event(thd_arg, 0,
9523              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
9524                            Log_event::EVENT_STMT_CACHE,
9525              Log_event::EVENT_NORMAL_LOGGING,
9526              header(), footer())
9527 #ifdef HAVE_REPLICATION
9528     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9529     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9530 #endif
9531 {
9532   common_header->type_code= m_type;
9533   m_row_count= 0;
9534   m_table_id= tid;
9535   m_width= tbl_arg ? tbl_arg->s->fields : 1;
9536   m_rows_buf= 0; m_rows_cur= 0; m_rows_end= 0; m_flags= 0;
9537   m_type= event_type; m_extra_row_data=0;
9538 
9539   assert(tbl_arg && tbl_arg->s && tid.is_valid());
9540 
9541   if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
9542       set_flags(NO_FOREIGN_KEY_CHECKS_F);
9543   if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
9544       set_flags(RELAXED_UNIQUE_CHECKS_F);
9545 #ifndef NDEBUG
9546   uchar extra_data[255];
9547   DBUG_EXECUTE_IF("extra_row_data_set",
9548                   /* Set extra row data to a known value */
9549                   extra_row_info = set_extra_data(extra_data););
9550 #endif
9551   if (extra_row_info)
9552   {
9553     /* Copy Extra data from thd into new event */
9554     uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
9555     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
9556 
9557     m_extra_row_data= (uchar*) my_malloc(key_memory_log_event,
9558                                          extra_data_len, MYF(MY_WME));
9559 
9560     if (likely(m_extra_row_data != NULL))
9561     {
9562       memcpy(m_extra_row_data, extra_row_info,
9563              extra_data_len);
9564     }
9565   }
9566 
9567   /* if bitmap_init fails, caught in is_valid() */
9568   if (likely(!bitmap_init(&m_cols,
9569                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9570                           m_width,
9571                           false)))
9572   {
9573     /* Cols can be zero if this is a dummy binrows event */
9574     if (likely(cols != NULL))
9575     {
9576       memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
9577       create_last_word_mask(&m_cols);
9578     }
9579   }
9580   else
9581   {
9582     // Needed because bitmap_init() does not set it to null on failure
9583     m_cols.bitmap= 0;
9584   }
9585   /*
9586    -Check that malloc() succeeded in allocating memory for the rows
9587     buffer and the COLS vector.
9588    -Checking that an Update_rows_log_event
9589     is valid is done while setting the Update_rows_log_event::is_valid
9590   */
9591   if (m_rows_buf && m_cols.bitmap)
9592     is_valid_param= true;
9593 }
9594 #endif
9595 
Rows_log_event(const char * buf,uint event_len,const Format_description_event * description_event)9596 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
9597                                const Format_description_event
9598                                *description_event)
9599 : binary_log::Rows_event(buf, event_len, description_event),
9600   Log_event(header(), footer()),
9601   m_row_count(0),
9602 #ifndef MYSQL_CLIENT
9603   m_table(NULL),
9604 #endif
9605   m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
9606 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9607     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9608     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9609 #endif
9610 {
9611   DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
9612 
9613   assert(header()->type_code == m_type);
9614 
9615 
9616   if (m_extra_row_data)
9617     DBUG_EXECUTE_IF("extra_row_data_check",
9618                     /* Check extra data has expected value */
9619                     check_extra_data(m_extra_row_data););
9620 
9621 
9622   /*
9623      m_cols and m_cols_ai are of the type MY_BITMAP, which are members of
9624      class Rows_log_event, and are used while applying the row events on
9625      the slave.
9626      The bitmap integer is initialized by copying the contents of the
9627      vector column_before_image for m_cols.bitamp, and vector
9628      column_after_image for m_cols_ai.bitmap. m_cols_ai is only initialized
9629      for UPDATE_ROWS_EVENTS, else it is equal to the before image.
9630   */
9631   memset(&m_cols, 0, sizeof(m_cols));
9632   /* if bitmap_init fails, is_valid will be set to false */
9633   if (likely(!bitmap_init(&m_cols,
9634                           m_width <= sizeof(m_bitbuf) * 8 ? m_bitbuf : NULL,
9635                           m_width,
9636                           false)))
9637   {
9638     if (!columns_before_image.empty())
9639     {
9640       memcpy(m_cols.bitmap, &columns_before_image[0], (m_width + 7) / 8);
9641       create_last_word_mask(&m_cols);
9642       DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
9643     } //end if columns_before_image.empty()
9644     else
9645     m_cols.bitmap= NULL;
9646   }
9647   else
9648   {
9649     // Needed because bitmap_init() does not set it to null on failure
9650     m_cols.bitmap= NULL;
9651     DBUG_VOID_RETURN;
9652   }
9653   m_cols_ai.bitmap= m_cols.bitmap; //See explanation below while setting is_valid.
9654 
9655   if ((m_type == binary_log::UPDATE_ROWS_EVENT) ||
9656       (m_type == binary_log::UPDATE_ROWS_EVENT_V1))
9657   {
9658     /* if bitmap_init fails, is_valid will be set to false*/
9659     if (likely(!bitmap_init(&m_cols_ai,
9660                             m_width <= sizeof(m_bitbuf_ai) * 8 ?
9661                                         m_bitbuf_ai : NULL,
9662                             m_width,
9663                             false)))
9664     {
9665       if (!columns_after_image.empty())
9666       {
9667         memcpy(m_cols_ai.bitmap, &columns_after_image[0], (m_width + 7) / 8);
9668         create_last_word_mask(&m_cols_ai);
9669        DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
9670                   no_bytes_in_map(&m_cols_ai));
9671       }
9672       else
9673         m_cols_ai.bitmap= NULL;
9674     }
9675     else
9676     {
9677       // Needed because bitmap_init() does not set it to null on failure
9678       m_cols_ai.bitmap= 0;
9679       DBUG_VOID_RETURN;
9680     }
9681   }
9682 
9683 
9684   /*
9685     m_rows_buf, m_cur_row and m_rows_end are pointers to the vector rows.
9686     m_rows_buf is the pointer to the first byte of first row in the event.
9687     m_curr_row points to current row being applied on the slave. Initially,
9688     this points to the same element as m_rows_buf in the vector.
9689     m_rows_end points to the last byte in the last row in the event.
9690 
9691     These pointers are used while applying the events on to the slave, and
9692     are not required for decoding.
9693   */
9694   if (likely(!row.empty()))
9695   {
9696     m_rows_buf= &row[0];
9697 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9698     m_curr_row= m_rows_buf;
9699 #endif
9700     m_rows_end= m_rows_buf + row.size() - 1;
9701     m_rows_cur= m_rows_end;
9702   }
9703   /*
9704     -Check that malloc() succeeded in allocating memory for the row
9705      buffer and the COLS vector.
9706     -Checking that an Update_rows_log_event
9707      is valid is done while setting the Update_rows_log_event::is_valid
9708   */
9709   if (m_rows_buf && m_cols.bitmap)
9710     is_valid_param= true;
9711   DBUG_VOID_RETURN;
9712 }
9713 
~Rows_log_event()9714 Rows_log_event::~Rows_log_event()
9715 {
9716   if (m_cols.bitmap)
9717   {
9718     if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
9719       m_cols.bitmap= 0; // so no my_free in bitmap_free
9720     bitmap_free(&m_cols); // To pair with bitmap_init().
9721   }
9722 }
get_data_size()9723 size_t Rows_log_event::get_data_size()
9724 {
9725   int const general_type_code= get_general_type_code();
9726 
9727   uchar buf[sizeof(m_width) + 1];
9728   uchar *end= net_store_length(buf, m_width);
9729 
9730   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9731                   return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
9732                   (general_type_code == binary_log::UPDATE_ROWS_EVENT ?
9733                                         no_bytes_in_map(&m_cols_ai) : 0) +
9734                   (m_rows_cur - m_rows_buf););
9735 
9736   int data_size= 0;
9737   bool is_v2_event= common_header->type_code > binary_log::DELETE_ROWS_EVENT_V1;
9738   if (is_v2_event)
9739   {
9740     data_size= Binary_log_event::ROWS_HEADER_LEN_V2 +
9741       (m_extra_row_data ?
9742        ROWS_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
9743        0);
9744   }
9745   else
9746   {
9747     data_size= Binary_log_event::ROWS_HEADER_LEN_V1;
9748   }
9749   data_size+= no_bytes_in_map(&m_cols);
9750   data_size+= (uint) (end - buf);
9751 
9752   if (general_type_code == binary_log::UPDATE_ROWS_EVENT)
9753     data_size+= no_bytes_in_map(&m_cols_ai);
9754 
9755   data_size+= (uint) (m_rows_cur - m_rows_buf);
9756   return data_size;
9757 }
9758 
9759 
9760 #ifndef MYSQL_CLIENT
do_add_row_data(uchar * row_data,size_t length)9761 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
9762 {
9763   /*
9764     When the table has a primary key, we would probably want, by default, to
9765     log only the primary key value instead of the entire "before image". This
9766     would save binlog space. TODO
9767   */
9768   DBUG_ENTER("Rows_log_event::do_add_row_data");
9769   DBUG_PRINT("enter", ("row_data: 0x%lx  length: %lu", (ulong) row_data,
9770                        (ulong) length));
9771 
9772   /*
9773     If length is zero, there is nothing to write, so we just
9774     return. Note that this is not an optimization, since calling
9775     realloc() with size 0 means free().
9776    */
9777   if (length == 0)
9778   {
9779     m_row_count++;
9780     DBUG_RETURN(0);
9781   }
9782 
9783   DBUG_DUMP("row_data", row_data, min<size_t>(length, 32));
9784 
9785   assert(m_rows_buf <= m_rows_cur);
9786   assert(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
9787   assert(m_rows_cur <= m_rows_end);
9788 
9789   /* The cast will always work since m_rows_cur <= m_rows_end */
9790   if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
9791   {
9792     size_t const block_size= 1024;
9793     ulong cur_size= m_rows_cur - m_rows_buf;
9794     DBUG_EXECUTE_IF("simulate_too_big_row_case1",
9795                      cur_size= UINT_MAX32 - (block_size * 10);
9796                      length= UINT_MAX32 - (block_size * 10););
9797     DBUG_EXECUTE_IF("simulate_too_big_row_case2",
9798                      cur_size= UINT_MAX32 - (block_size * 10);
9799                      length= block_size * 10;);
9800     DBUG_EXECUTE_IF("simulate_too_big_row_case3",
9801                      cur_size= block_size * 10;
9802                      length= UINT_MAX32 - (block_size * 10););
9803     DBUG_EXECUTE_IF("simulate_too_big_row_case4",
9804                      cur_size= UINT_MAX32 - (block_size * 10);
9805                      length= (block_size * 10) - block_size + 1;);
9806     ulong remaining_space= UINT_MAX32 - cur_size;
9807     /* Check that the new data fits within remaining space and we can add
9808        block_size without wrapping.
9809      */
9810     if (length > remaining_space ||
9811         ((length + block_size) > remaining_space))
9812     {
9813       sql_print_error("The row data is greater than 4GB, which is too big to "
9814                       "write to the binary log.");
9815       DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
9816     }
9817     const size_t new_alloc=
9818         block_size * ((cur_size + length + block_size - 1) / block_size);
9819     if (new_alloc)
9820       row.resize(new_alloc);
9821 
9822     /* If the memory moved, we need to move the pointers */
9823     if (new_alloc && &row[0] != m_rows_buf)
9824     {
9825       m_rows_buf= &row[0];
9826       if (m_rows_buf && m_cols.bitmap)
9827         is_valid_param= true;
9828       m_rows_cur= m_rows_buf + cur_size;
9829     }
9830 
9831     /*
9832        The end pointer should always be changed to point to the end of
9833        the allocated memory.
9834     */
9835     m_rows_end= m_rows_buf + new_alloc;
9836   }
9837 
9838   assert(m_rows_cur + length <= m_rows_end);
9839   memcpy(m_rows_cur, row_data, length);
9840   m_rows_cur+= length;
9841   m_row_count++;
9842   DBUG_RETURN(0);
9843 }
9844 #endif
9845 
9846 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9847 
9848 /**
9849   Checks if any of the columns in the given table is
9850   signaled in the bitmap.
9851 
9852   For each column in the given table checks if it is
9853   signaled in the bitmap. This is most useful when deciding
9854   whether a before image (BI) can be used or not for
9855   searching a row. If no column is signaled, then the
9856   image cannot be used for searching a record (regardless
9857   of using position(), index scan or table scan). Here is
9858   an example:
9859 
9860   MASTER> SET @@binlog_row_image='MINIMAL';
9861   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9862   SLAVE>  CREATE TABLE t1 (a int, b int);
9863   MASTER> INSERT INTO t1 VALUES (1,2,3);
9864   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9865 
9866   For the update statement only the PK (column c) is
9867   logged in the before image (BI). As such, given that
9868   the slave has no column c, it will not be able to
9869   find the row, because BI has no values for the columns
9870   the slave knows about (column a and b).
9871 
9872   @param table   the table reference on the slave.
9873   @param cols the bitmap signaling columns available in
9874                  the BI.
9875 
9876   @return TRUE if BI contains usable colums for searching,
9877           FALSE otherwise.
9878 */
9879 static
is_any_column_signaled_for_table(TABLE * table,MY_BITMAP * cols)9880 my_bool is_any_column_signaled_for_table(TABLE *table, MY_BITMAP *cols)
9881 {
9882   DBUG_ENTER("is_any_column_signaled_for_table");
9883 
9884   for (Field **ptr= table->field ;
9885        *ptr && ((*ptr)->field_index < cols->n_bits);
9886        ptr++)
9887   {
9888     if (bitmap_is_set(cols, (*ptr)->field_index))
9889       DBUG_RETURN(TRUE);
9890   }
9891 
9892   DBUG_RETURN (FALSE);
9893 }
9894 
9895 /**
9896   Checks if the fields in the given key are signaled in
9897   the bitmap.
9898 
9899   Validates whether the before image is usable for the
9900   given key. It can be the case that the before image
9901   does not contain values for the key (eg, master was
9902   using 'minimal' option for image logging and slave has
9903   different index structure on the table). Here is an
9904   example:
9905 
9906   MASTER> SET @@binlog_row_image='MINIMAL';
9907   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9908   SLAVE> CREATE TABLE t1 (a int, b int, c int, key(a,c));
9909   MASTER> INSERT INTO t1 VALUES (1,2,3);
9910   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9911 
9912   When finding the row on the slave, one cannot use the
9913   index (a,c) to search for the row, because there is only
9914   data in the before image for column c. This function
9915   checks the fields needed for a given key and searches
9916   the bitmap to see if all the fields required are
9917   signaled.
9918 
9919   @param keyinfo  reference to key.
9920   @param cols     the bitmap signaling which columns
9921                   have available data.
9922 
9923   @return TRUE if all fields are signaled in the bitmap
9924           for the given key, FALSE otherwise.
9925 */
9926 static
are_all_columns_signaled_for_key(KEY * keyinfo,MY_BITMAP * cols)9927 my_bool are_all_columns_signaled_for_key(KEY *keyinfo, MY_BITMAP *cols)
9928 {
9929   DBUG_ENTER("are_all_columns_signaled_for_key");
9930 
9931   for (uint i=0 ; i < keyinfo->user_defined_key_parts ;i++)
9932   {
9933     uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
9934     if (fieldnr >= cols->n_bits ||
9935         !bitmap_is_set(cols, fieldnr))
9936       DBUG_RETURN(FALSE);
9937   }
9938 
9939   DBUG_RETURN(TRUE);
9940 }
9941 
9942 /**
9943   Searches the table for a given key that can be used
9944   according to the existing values, ie, columns set
9945   in the bitmap.
9946 
9947   The caller can specify which type of key to find by
9948   setting the following flags in the key_type parameter:
9949 
9950     - PRI_KEY_FLAG
9951       Returns the primary key.
9952 
9953     - UNIQUE_KEY_FLAG
9954       Returns a unique key (flagged with HA_NOSAME)
9955 
9956     - MULTIPLE_KEY_FLAG
9957       Returns a key that is not unique (flagged with HA_NOSAME
9958       and without HA_NULL_PART_KEY) nor PK.
9959 
9960   The above flags can be used together, in which case, the
9961   search is conducted in the above listed order. Eg, the
9962   following flag:
9963 
9964     (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG)
9965 
9966   means that a primary key is returned if it is suitable. If
9967   not then the unique keys are searched. If no unique key is
9968   suitable, then the keys are searched. Finally, if no key
9969   is suitable, MAX_KEY is returned.
9970 
9971   @param table    reference to the table.
9972   @param bi_cols  a bitmap that filters out columns that should
9973                   not be considered while searching the key.
9974                   Columns that should be considered are set.
9975   @param key_type the type of key to search for.
9976 
9977   @return MAX_KEY if no key, according to the key_type specified
9978           is suitable. Returns the key otherwise.
9979 
9980 */
9981 static
9982 uint
search_key_in_table(TABLE * table,MY_BITMAP * bi_cols,uint key_type)9983 search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type)
9984 {
9985   DBUG_ENTER("search_key_in_table");
9986 
9987   KEY *keyinfo;
9988   uint res= MAX_KEY;
9989   uint key;
9990 
9991   if (key_type & PRI_KEY_FLAG &&
9992       (table->s->primary_key < MAX_KEY))
9993   {
9994     DBUG_PRINT("debug", ("Searching for PK"));
9995     keyinfo= table->s->key_info + table->s->primary_key;
9996     if (are_all_columns_signaled_for_key(keyinfo, bi_cols))
9997       DBUG_RETURN(table->s->primary_key);
9998   }
9999 
10000   if (key_type & UNIQUE_KEY_FLAG)
10001   {
10002     DBUG_PRINT("debug", ("Searching for UK"));
10003     for (key=0,keyinfo= table->key_info ;
10004          (key < table->s->keys) && (res == MAX_KEY);
10005          key++,keyinfo++)
10006     {
10007       /*
10008         - Unique keys cannot be disabled, thence we skip the check.
10009         - Skip unique keys with nullable parts
10010         - Skip primary keys
10011       */
10012       if (!((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10013           (key == table->s->primary_key))
10014         continue;
10015       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10016            key : MAX_KEY;
10017 
10018       if (res < MAX_KEY)
10019         DBUG_RETURN(res);
10020     }
10021     DBUG_PRINT("debug", ("UK has NULLABLE parts or not all columns signaled."));
10022   }
10023 
10024   if (key_type & MULTIPLE_KEY_FLAG && table->s->keys)
10025   {
10026     DBUG_PRINT("debug", ("Searching for K."));
10027     for (key=0,keyinfo= table->key_info ;
10028          (key < table->s->keys) && (res == MAX_KEY);
10029          key++,keyinfo++)
10030     {
10031       /*
10032         - Skip innactive keys
10033         - Skip unique keys without nullable parts
10034         - Skip indices that do not support ha_index_next() e.g. full-text
10035         - Skip primary keys
10036       */
10037       if (!(table->s->keys_in_use.is_set(key)) ||
10038           ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10039           !(table->file->index_flags(key, 0, true) & HA_READ_NEXT) ||
10040           (key == table->s->primary_key))
10041         continue;
10042 
10043       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10044            key : MAX_KEY;
10045 
10046       if (res < MAX_KEY)
10047         DBUG_RETURN(res);
10048     }
10049     DBUG_PRINT("debug", ("Not all columns signaled for K."));
10050   }
10051 
10052   DBUG_RETURN(res);
10053 }
10054 
10055 void
decide_row_lookup_algorithm_and_key()10056 Rows_log_event::decide_row_lookup_algorithm_and_key()
10057 {
10058 
10059   DBUG_ENTER("decide_row_lookup_algorithm_and_key");
10060 
10061   /*
10062     Decision table:
10063     - I  --> Index scan / search
10064     - T  --> Table scan
10065     - Hi --> Hash over index
10066     - Ht --> Hash over the entire table
10067 
10068     |--------------+-----------+------+------+------|
10069     | Index\Option | I , T , H | I, T | I, H | T, H |
10070     |--------------+-----------+------+------+------|
10071     | PK / UK      | I         | I    | I    | Hi   |
10072     | K            | Hi        | I    | Hi   | Hi   |
10073     | No Index     | Ht        | T    | Ht   | Ht   |
10074     |--------------+-----------+------+------+------|
10075 
10076   */
10077 
10078   TABLE *table= this->m_table;
10079   uint event_type= this->get_general_type_code();
10080   MY_BITMAP *cols= &this->m_cols;
10081   bool delete_update_lookup_condition= false;
10082   this->m_rows_lookup_algorithm= ROW_LOOKUP_NOT_NEEDED;
10083   this->m_key_index= MAX_KEY;
10084   this->m_key_info= NULL;
10085 
10086   // row lookup not needed
10087   if (event_type == binary_log::WRITE_ROWS_EVENT ||
10088      (delete_update_lookup_condition= ((event_type == binary_log::DELETE_ROWS_EVENT ||
10089                                         event_type == binary_log::UPDATE_ROWS_EVENT) &&
10090                                       get_flags(COMPLETE_ROWS_F) &&
10091                                       !m_table->file->rpl_lookup_rows())))
10092   {
10093     if (delete_update_lookup_condition &&
10094         table->s->primary_key == MAX_KEY)
10095     {
10096         if (!table->s->rfr_lookup_warning)
10097         {
10098           sql_print_warning("Slave: read free replication is disabled "
10099                             "for TokuDB/RocksDB table `%s.%s` "
10100                             "as it does not have implicit primary key, "
10101                             "continue with rows lookup",
10102                             print_slave_db_safe(table->s->db.str),
10103                             m_table->s->table_name.str);
10104           table->s->rfr_lookup_warning= true;
10105         }
10106     }
10107     else
10108       DBUG_VOID_RETURN;
10109   }
10110 
10111   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN))
10112     goto TABLE_OR_INDEX_HASH_SCAN;
10113 
10114   /* PK or UK => use LOOKUP_INDEX_SCAN */
10115   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG));
10116   if (this->m_key_index != MAX_KEY)
10117   {
10118     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10119     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10120     goto end;
10121   }
10122 
10123 TABLE_OR_INDEX_HASH_SCAN:
10124 
10125   /*
10126      NOTE: Engines like Blackhole cannot use HASH_SCAN, because
10127            they do not syncronize reads .
10128    */
10129   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_HASH_SCAN) ||
10130       (table->file->ha_table_flags() & HA_READ_OUT_OF_SYNC))
10131     goto TABLE_OR_INDEX_FULL_SCAN;
10132 
10133   /* search for a key to see if we can narrow the lookup domain further. */
10134   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10135   this->m_rows_lookup_algorithm= ROW_LOOKUP_HASH_SCAN;
10136   if (m_key_index < MAX_KEY)
10137     m_distinct_key_spare_buf= (uchar*) thd->alloc(table->key_info[m_key_index].key_length);
10138   DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - HASH_SCAN"));
10139   goto end;
10140 
10141 TABLE_OR_INDEX_FULL_SCAN:
10142 
10143   this->m_key_index= MAX_KEY;
10144 
10145   /* If we can use an index, try to narrow the scan a bit further. */
10146   if (slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN)
10147     this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10148 
10149   if (this->m_key_index != MAX_KEY)
10150   {
10151     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10152     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10153   }
10154   else
10155   {
10156     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - TABLE_SCAN"));
10157     this->m_rows_lookup_algorithm= ROW_LOOKUP_TABLE_SCAN;
10158   }
10159 
10160 end:
10161 
10162   /* m_key_index is ready, set m_key_info now. */
10163   m_key_info= m_table->key_info + m_key_index;
10164   /*
10165     m_key_info will influence key comparison code in HASH_SCAN mode,
10166     so the m_distinct_keys set should still be empty.
10167   */
10168   assert(m_distinct_keys.empty());
10169 
10170 #ifndef NDEBUG
10171   const char* s= ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
10172                   ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
10173                    "INDEX_SCAN"));
10174 
10175   // only for testing purposes
10176   slave_rows_last_search_algorithm_used= m_rows_lookup_algorithm;
10177   DBUG_PRINT("debug", ("Row lookup method: %s", s));
10178 #endif
10179 
10180   DBUG_VOID_RETURN;
10181 }
10182 
10183 /*
10184   Encapsulates the  operations to be done before applying
10185   row events for update and delete.
10186 
10187   @ret value error code
10188              0 success
10189 */
10190 int
row_operations_scan_and_key_setup()10191 Rows_log_event::row_operations_scan_and_key_setup()
10192 {
10193   int error= 0;
10194   DBUG_ENTER("Row_log_event::row_operations_scan_and_key_setup");
10195 
10196   /*
10197      Prepare memory structures for search operations. If
10198      search is performed:
10199 
10200      1. using hash search => initialize the hash
10201      2. using key => decide on key to use and allocate mem structures
10202      3. using table scan => do nothing
10203    */
10204   decide_row_lookup_algorithm_and_key();
10205 
10206   switch (m_rows_lookup_algorithm)
10207   {
10208   case ROW_LOOKUP_HASH_SCAN:
10209     {
10210       if (m_hash.init())
10211         error= HA_ERR_OUT_OF_MEM;
10212       goto err;
10213     }
10214   case ROW_LOOKUP_INDEX_SCAN:
10215     {
10216       assert (m_key_index < MAX_KEY);
10217       // Allocate buffer for key searches
10218       m_key= (uchar*)my_malloc(key_memory_log_event,
10219                                m_key_info->key_length, MYF(MY_WME));
10220       if (!m_key)
10221         error= HA_ERR_OUT_OF_MEM;
10222       goto err;
10223     }
10224   case ROW_LOOKUP_TABLE_SCAN:
10225   default: break;
10226   }
10227 err:
10228   DBUG_RETURN(error);
10229 }
10230 
10231 /*
10232   Encapsulates the  operations to be done after applying
10233   row events for update and delete.
10234 
10235   @ret value error code
10236              0 success
10237 */
10238 
10239 int
row_operations_scan_and_key_teardown(int error)10240 Rows_log_event::row_operations_scan_and_key_teardown(int error)
10241 {
10242   DBUG_ENTER("Rows_log_event::row_operations_scan_and_key_teardown");
10243 
10244   assert(!m_table->file->inited);
10245   switch (m_rows_lookup_algorithm)
10246   {
10247   case ROW_LOOKUP_HASH_SCAN:
10248     {
10249       m_hash.deinit(); // we don't need the hash anymore.
10250       goto err;
10251     }
10252 
10253   case ROW_LOOKUP_INDEX_SCAN:
10254     {
10255       if (m_table->s->keys > 0)
10256       {
10257         my_free(m_key); // Free for multi_malloc
10258         m_key= NULL;
10259         m_key_index= MAX_KEY;
10260         m_key_info= NULL;
10261       }
10262      goto err;
10263     }
10264 
10265   case ROW_LOOKUP_TABLE_SCAN:
10266   default: break;
10267   }
10268 
10269 err:
10270   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
10271   DBUG_RETURN(error);
10272 }
10273 
10274 /*
10275   Compares table->record[0] and table->record[1]
10276 
10277   Returns TRUE if different.
10278 */
record_compare(TABLE * table,MY_BITMAP * cols)10279 static bool record_compare(TABLE *table, MY_BITMAP *cols)
10280 {
10281   DBUG_ENTER("record_compare");
10282 
10283   /*
10284     Need to set the X bit and the filler bits in both records since
10285     there are engines that do not set it correctly.
10286 
10287     In addition, since MyISAM checks that one hasn't tampered with the
10288     record, it is necessary to restore the old bytes into the record
10289     after doing the comparison.
10290 
10291     TODO[record format ndb]: Remove it once NDB returns correct
10292     records. Check that the other engines also return correct records.
10293    */
10294 
10295   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10296   DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
10297 
10298   bool result= false;
10299   uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
10300 
10301   if (table->s->null_bytes > 0)
10302   {
10303     for (int i = 0 ; i < 2 ; ++i)
10304     {
10305       /*
10306         If we have an X bit then we need to take care of it.
10307       */
10308       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10309       {
10310         saved_x[i]= table->record[i][0];
10311         table->record[i][0]|= 1U;
10312       }
10313 
10314       /*
10315          If (last_null_bit_pos == 0 && null_bytes > 1), then:
10316 
10317          X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
10318 
10319          Ie, the entire byte is used.
10320       */
10321       if (table->s->last_null_bit_pos > 0)
10322       {
10323         saved_filler[i]= table->record[i][table->s->null_bytes - 1];
10324         table->record[i][table->s->null_bytes - 1]|=
10325           256U - (1U << table->s->last_null_bit_pos);
10326       }
10327     }
10328   }
10329 
10330   /**
10331     Compare full record only if:
10332     - there are no blob fields (otherwise we would also need
10333       to compare blobs contents as well);
10334     - there are no varchar fields (otherwise we would also need
10335       to compare varchar contents as well);
10336     - there are no null fields, otherwise NULLed fields
10337       contents (i.e., the don't care bytes) may show arbitrary
10338       values, depending on how each engine handles internally.
10339     - if all the bitmap is set (both are full rows)
10340     */
10341   if ((table->s->blob_fields +
10342        table->s->varchar_fields +
10343        table->s->null_fields) == 0 &&
10344       bitmap_is_set_all(cols))
10345   {
10346     result= cmp_record(table,record[1]);
10347   }
10348 
10349   /*
10350     Fallback to field-by-field comparison:
10351     1. start by checking if the field is signaled:
10352     2. if it is, first compare the null bit if the field is nullable
10353     3. then compare the contents of the field, if it is not
10354        set to null
10355    */
10356   else
10357   {
10358     for (Field **ptr=table->field ;
10359          *ptr && ((*ptr)->field_index < cols->n_bits) && !result;
10360          ptr++)
10361     {
10362       Field *field= *ptr;
10363       if (bitmap_is_set(cols, field->field_index) && !field->is_virtual_gcol())
10364       {
10365         /* compare null bit */
10366         if (field->is_null() != field->is_null_in_record(table->record[1]))
10367           result= true;
10368 
10369         /* compare content, only if fields are not set to NULL */
10370         else if (!field->is_null())
10371           result= field->cmp_binary_offset(table->s->rec_buff_length);
10372       }
10373     }
10374   }
10375 
10376   /*
10377     Restore the saved bytes.
10378 
10379     TODO[record format ndb]: Remove this code once NDB returns the
10380     correct record format.
10381   */
10382   if (table->s->null_bytes > 0)
10383   {
10384     for (int i = 0 ; i < 2 ; ++i)
10385     {
10386       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10387         table->record[i][0]= saved_x[i];
10388 
10389       if (table->s->last_null_bit_pos)
10390         table->record[i][table->s->null_bytes - 1]= saved_filler[i];
10391     }
10392   }
10393 
10394   DBUG_RETURN(result);
10395 }
10396 
do_post_row_operations(Relay_log_info const * rli,int error)10397 void Rows_log_event::do_post_row_operations(Relay_log_info const *rli, int error)
10398 {
10399 
10400   /*
10401     If m_curr_row_end  was not set during event execution (e.g., because
10402     of errors) we can't proceed to the next row. If the error is transient
10403     (i.e., error==0 at this point) we must call unpack_current_row() to set
10404     m_curr_row_end.
10405   */
10406 
10407   DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
10408                       (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
10409 
10410   if (!m_curr_row_end && !error)
10411   {
10412     const uchar *previous_m_curr_row= m_curr_row;
10413     error= unpack_current_row(rli, &m_cols);
10414 
10415     if (!error && previous_m_curr_row == m_curr_row)
10416     {
10417       error= 1;
10418     }
10419   }
10420 
10421   // at this moment m_curr_row_end should be set
10422   assert(error || m_curr_row_end != NULL);
10423   assert(error || m_curr_row <= m_curr_row_end);
10424   assert(error || m_curr_row_end <= m_rows_end);
10425 
10426   m_curr_row= m_curr_row_end;
10427 
10428   if (error == 0 && !m_table->file->has_transactions())
10429   {
10430     thd->get_transaction()->set_unsafe_rollback_flags(Transaction_ctx::SESSION,
10431                                                       TRUE);
10432     thd->get_transaction()->set_unsafe_rollback_flags(Transaction_ctx::STMT,
10433                                                       TRUE);
10434   }
10435 }
10436 
handle_idempotent_and_ignored_errors(Relay_log_info const * rli,int * err)10437 int Rows_log_event::handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err)
10438 {
10439   int error= *err;
10440   if (error)
10441   {
10442     int actual_error= convert_handler_error(error, thd, m_table);
10443     bool idempotent_error= (idempotent_error_code(error) &&
10444                            (rbr_exec_mode == RBR_EXEC_MODE_IDEMPOTENT));
10445     bool ignored_error= (idempotent_error == 0 ?
10446                          ignored_error_code(actual_error) : 0);
10447 
10448     if (idempotent_error || ignored_error)
10449     {
10450       loglevel ll;
10451       if (idempotent_error)
10452         ll= WARNING_LEVEL;
10453       else
10454         ll= INFORMATION_LEVEL;
10455       slave_rows_error_report(ll, error, rli, thd, m_table,
10456                               get_type_str(),
10457                               const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
10458                               (ulong) common_header->log_pos);
10459       thd->get_stmt_da()->reset_condition_info(thd);
10460       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
10461       *err= 0;
10462       if (idempotent_error == 0)
10463         return ignored_error;
10464     }
10465   }
10466 
10467   return *err;
10468 }
10469 
do_apply_row(Relay_log_info const * rli)10470 int Rows_log_event::do_apply_row(Relay_log_info const *rli)
10471 {
10472   DBUG_ENTER("Rows_log_event::do_apply_row");
10473 
10474   int error= 0;
10475 
10476   /* in_use can have been set to NULL in close_tables_for_reopen */
10477   THD* old_thd= m_table->in_use;
10478   if (!m_table->in_use)
10479     m_table->in_use= thd;
10480 
10481   error= do_exec_row(rli);
10482 
10483   if(error)
10484   {
10485     DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10486     assert(error != HA_ERR_RECORD_DELETED);
10487   }
10488 
10489   m_table->in_use = old_thd;
10490 
10491   DBUG_RETURN(error);
10492 }
10493 
10494 /**
10495    Does the cleanup
10496      -  closes the index if opened by open_record_scan
10497      -  closes the table if opened for scanning.
10498 */
10499 int
close_record_scan()10500 Rows_log_event::close_record_scan()
10501 {
10502   DBUG_ENTER("Rows_log_event::close_record_scan");
10503   int error= 0;
10504 
10505   // if there is something to actually close
10506   if (m_key_index < MAX_KEY)
10507   {
10508     if (m_table->file->inited)
10509       error= m_table->file->ha_index_end();
10510   }
10511   else if (m_table->file->inited)
10512     error= m_table->file->ha_rnd_end();
10513 
10514   DBUG_RETURN(error);
10515 }
10516 
10517 /**
10518   Fetches next row. If it is a HASH_SCAN over an index, it populates
10519   table->record[0] with the next row corresponding to the index. If
10520   the indexes are in non-contigous ranges it fetches record corresponding
10521   to the key value in the next range.
10522 
10523   @parms: bool first_read : signifying if this is the first time we are reading a row
10524           over an index.
10525   @return_value: -  error code when there are no more reeords to be fetched or some other
10526                     error occured,
10527                  -  0 otherwise.
10528 */
10529 int
next_record_scan(bool first_read)10530 Rows_log_event::next_record_scan(bool first_read)
10531 {
10532   DBUG_ENTER("Rows_log_event::next_record_scan");
10533   assert(m_table->file->inited);
10534   TABLE *table= m_table;
10535   int error= 0;
10536 
10537   if (m_key_index >= MAX_KEY)
10538     error= table->file->ha_rnd_next(table->record[0]);
10539   else
10540   {
10541     /*
10542       We need to set the null bytes to ensure that the filler bit are
10543       all set when returning.  There are storage engines that just set
10544       the necessary bits on the bytes and don't set the filler bits
10545       correctly.
10546     */
10547     if (table->s->null_bytes > 0)
10548       table->record[0][table->s->null_bytes - 1]|=
10549         256U - (1U << table->s->last_null_bit_pos);
10550 
10551     if (!first_read)
10552     {
10553       /*
10554         if we fail to fetch next record corresponding to a key value, we
10555         move to the next key value. If we are out of key values as well an error
10556         will be returned.
10557        */
10558       error= table->file->ha_index_next_same(table->record[0], m_key,
10559                                              m_key_info->key_length);
10560       if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10561       {
10562         /*
10563           if we are out of rows for this particular key value, we reposition the
10564           marker according to the next key value that we have in the list.
10565          */
10566         if (error)
10567         {
10568           if (m_itr != m_distinct_keys.end())
10569           {
10570             m_key= *m_itr;
10571             m_itr++;
10572             first_read= true;
10573           }
10574           else
10575             error= HA_ERR_KEY_NOT_FOUND;
10576         }
10577       }
10578     }
10579 
10580     if (first_read)
10581       if ((error= table->file->ha_index_read_map(table->record[0], m_key,
10582                                                  HA_WHOLE_KEY,
10583                                                  HA_READ_KEY_EXACT)))
10584       {
10585         DBUG_PRINT("info",("no record matching the key found in the table"));
10586         if (error == HA_ERR_RECORD_DELETED)
10587           error= HA_ERR_KEY_NOT_FOUND;
10588       }
10589   }
10590 
10591   DBUG_RETURN(error);
10592 }
10593 
10594 /**
10595   Initializes scanning of rows. Opens an index and initializes an iterator
10596   over a list of distinct keys (m_distinct_keys) if it is a HASH_SCAN
10597   over an index or the table if its a HASH_SCAN over the table.
10598 */
10599 int
open_record_scan()10600 Rows_log_event::open_record_scan()
10601 {
10602   int error= 0;
10603   TABLE *table= m_table;
10604   DBUG_ENTER("Rows_log_event::open_record_scan");
10605 
10606   if (m_key_index < MAX_KEY )
10607   {
10608     if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10609     {
10610       /* initialize the iterator over the list of distinct keys that we have */
10611       m_itr= m_distinct_keys.begin();
10612 
10613       /* get the first element from the list of keys and increment the
10614          iterator
10615        */
10616       m_key= *m_itr;
10617       m_itr++;
10618     }
10619     else {
10620       /* this is an INDEX_SCAN we need to store the key in m_key */
10621       assert((m_rows_lookup_algorithm == ROW_LOOKUP_INDEX_SCAN) && m_key);
10622       key_copy(m_key, m_table->record[0], m_key_info, 0);
10623     }
10624 
10625     /*
10626       Save copy of the record in table->record[1]. It might be needed
10627       later if linear search is used to find exact match.
10628      */
10629     store_record(table,record[1]);
10630 
10631     DBUG_PRINT("info",("locating record using a key (index_read)"));
10632 
10633     /* The m_key_index'th key is active and usable: search the table using the index */
10634     if (!table->file->inited && (error= table->file->ha_index_init(m_key_index, FALSE)))
10635     {
10636       DBUG_PRINT("info",("ha_index_init returns error %d",error));
10637       goto end;
10638     }
10639 
10640     DBUG_DUMP("key data", m_key, m_key_info->key_length);
10641   }
10642   else
10643   {
10644     if ((error= table->file->ha_rnd_init(1)))
10645     {
10646       DBUG_PRINT("info",("error initializing table scan"
10647           " (ha_rnd_init returns %d)",error));
10648       table->file->print_error(error, MYF(0));
10649     }
10650   }
10651 
10652 end:
10653   DBUG_RETURN(error);
10654 }
10655 
10656 /**
10657   Populates the m_distinct_keys with unique keys to be modified
10658   during HASH_SCAN over keys.
10659   @return_value -0 success
10660                 -Err_code
10661 */
10662 int
add_key_to_distinct_keyset()10663 Rows_log_event::add_key_to_distinct_keyset()
10664 {
10665   int error= 0;
10666   DBUG_ENTER("Rows_log_event::add_key_to_distinct_keyset");
10667   assert(m_key_index < MAX_KEY);
10668   key_copy(m_distinct_key_spare_buf, m_table->record[0], m_key_info, 0);
10669   std::pair<std::set<uchar *, Key_compare>::iterator,bool> ret=
10670     m_distinct_keys.insert(m_distinct_key_spare_buf);
10671   if (ret.second)
10672   {
10673     /* Insert is successful, so allocate a new buffer for next key */
10674     m_distinct_key_spare_buf= (uchar*) thd->alloc(m_key_info->key_length);
10675     if (!m_distinct_key_spare_buf)
10676     {
10677       error= HA_ERR_OUT_OF_MEM;
10678       goto err;
10679     }
10680   }
10681 
10682 err:
10683   DBUG_RETURN(error);
10684 }
10685 
10686 
do_index_scan_and_update(Relay_log_info const * rli)10687 int Rows_log_event::do_index_scan_and_update(Relay_log_info const *rli)
10688 {
10689   DBUG_ENTER("Rows_log_event::do_index_scan_and_update");
10690   assert(m_table && m_table->in_use != NULL);
10691 
10692   int error= 0;
10693   const uchar *saved_m_curr_row= m_curr_row;
10694 
10695   /*
10696     rpl_row_tabledefs.test specifies that
10697     if the extra field on the slave does not have a default value
10698     and this is okay with Delete or Update events.
10699     Todo: fix wl3228 hld that requires defaults for all types of events
10700   */
10701 
10702   prepare_record(m_table, &m_cols, FALSE);
10703   if ((error= unpack_current_row(rli, &m_cols)))
10704     goto end;
10705 
10706   /*
10707     Trying to do an index scan without a usable key
10708     This is a valid state because we allow the user
10709     to set Slave_rows_search_algorithm= 'INDEX_SCAN'.
10710 
10711     Therefore on tables with no indexes we will end
10712     up here.
10713    */
10714   if (m_key_index >= MAX_KEY)
10715   {
10716     error= HA_ERR_END_OF_FILE;
10717     goto end;
10718   }
10719 
10720 #ifndef NDEBUG
10721   DBUG_PRINT("info",("looking for the following record"));
10722   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10723 #endif
10724 
10725   if (m_key_index != m_table->s->primary_key)
10726     /* we dont have a PK, or PK is not usable */
10727     goto INDEX_SCAN;
10728 
10729   if ((m_table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL))
10730   {
10731     /*
10732       Read removal is possible since the engine supports write without
10733       previous read using full primary key
10734     */
10735     DBUG_PRINT("info", ("using read before write removal"));
10736     assert(m_key_index == m_table->s->primary_key);
10737 
10738     /*
10739       Tell the handler to ignore if key exists or not, since it's
10740       not yet known if the key does exist(when using rbwr)
10741     */
10742     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
10743 
10744     goto end;
10745   }
10746 
10747   if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION))
10748   {
10749     /*
10750       Use a more efficient method to fetch the record given by
10751       table->record[0] if the engine allows it.  We first compute a
10752       row reference using the position() member function (it will be
10753       stored in table->file->ref) and then use rnd_pos() to position
10754       the "cursor" (i.e., record[0] in this case) at the correct row.
10755 
10756       TODO: Check that the correct record has been fetched by
10757       comparing it with the original record. Take into account that the
10758       record on the master and slave can be of different
10759       length. Something along these lines should work:
10760 
10761       ADD>>>  store_record(table,record[1]);
10762               int error= table->file->rnd_pos(table->record[0], table->file->ref);
10763               ADD>>>  assert(memcmp(table->record[1], table->record[0],
10764               table->s->reclength) == 0);
10765 
10766     */
10767 
10768     DBUG_PRINT("info",("locating record using primary key (position)"));
10769     if (m_table->file->inited && (error= m_table->file->ha_index_end()))
10770       goto end;
10771 
10772     error= m_table->file->rnd_pos_by_record(m_table->record[0]);
10773     if (error)
10774     {
10775       DBUG_PRINT("info",("rnd_pos returns error %d",error));
10776       if (error == HA_ERR_RECORD_DELETED)
10777         error= HA_ERR_KEY_NOT_FOUND;
10778     }
10779 
10780     goto end;
10781   }
10782 
10783   // We can't use position() - try other methods.
10784 
10785 INDEX_SCAN:
10786 
10787   /* Use the m_key_index'th key */
10788 
10789   if ((error= open_record_scan()))
10790     goto end;
10791 
10792   error= next_record_scan(true);
10793   if (error)
10794   {
10795     DBUG_PRINT("info",("no record matching the key found in the table"));
10796     if (error == HA_ERR_RECORD_DELETED)
10797       error= HA_ERR_KEY_NOT_FOUND;
10798     goto end;
10799   }
10800 
10801 
10802   DBUG_PRINT("info",("found first matching record"));
10803   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10804   /*
10805     Below is a minor "optimization".  If the key (i.e., key number
10806     0) has the HA_NOSAME flag set, we know that we have found the
10807     correct record (since there can be no duplicates); otherwise, we
10808     have to compare the record with the one found to see if it is
10809     the correct one.
10810 
10811     CAVEAT! This behaviour is essential for the replication of,
10812     e.g., the mysql.proc table since the correct record *shall* be
10813     found using the primary key *only*.  There shall be no
10814     comparison of non-PK columns to decide if the correct record is
10815     found.  I can see no scenario where it would be incorrect to
10816     chose the row to change only using a PK or an UNNI.
10817   */
10818   if (m_key_info->flags & HA_NOSAME || m_key_index == m_table->s->primary_key)
10819   {
10820     /* Unique does not have non nullable part */
10821     if (!(m_key_info->flags & (HA_NULL_PART_KEY)))
10822       goto end;  // record found
10823     else
10824     {
10825       /*
10826         Unique has nullable part. We need to check if there is any field in the
10827         BI image that is null and part of UNNI.
10828       */
10829       bool null_found= FALSE;
10830       for (uint i=0; i < m_key_info->user_defined_key_parts && !null_found; i++)
10831       {
10832         uint fieldnr= m_key_info->key_part[i].fieldnr - 1;
10833         Field **f= m_table->field+fieldnr;
10834         null_found= (*f)->is_null();
10835       }
10836 
10837       if (!null_found)
10838         goto end;           // record found
10839 
10840       /* else fall through to index scan */
10841     }
10842   }
10843 
10844   /*
10845     In case key is not unique, we still have to iterate over records found
10846     and find the one which is identical to the row given. A copy of the
10847     record we are looking for is stored in record[1].
10848    */
10849   DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10850 
10851   while (record_compare(m_table, &m_cols))
10852   {
10853     while((error= next_record_scan(false)))
10854     {
10855       /* We just skip records that has already been deleted */
10856       if (error == HA_ERR_RECORD_DELETED)
10857         continue;
10858       DBUG_PRINT("info",("no record matching the given row found"));
10859       goto end;
10860     }
10861   }
10862 
10863 end:
10864 
10865   assert(error != HA_ERR_RECORD_DELETED);
10866 
10867   if (error && error != HA_ERR_RECORD_DELETED)
10868     m_table->file->print_error(error, MYF(0));
10869   else
10870     error= do_apply_row(rli);
10871 
10872   if (!error)
10873     error= close_record_scan();
10874   else
10875     /*
10876       we are already with errors. Keep the error code and
10877       try to close the scan anyway.
10878     */
10879     (void) close_record_scan();
10880 
10881   if ((get_general_type_code() == binary_log::UPDATE_ROWS_EVENT) &&
10882       (saved_m_curr_row == m_curr_row))
10883   {
10884     /* we need to unpack the AI so that positions get updated */
10885     m_curr_row= m_curr_row_end;
10886     unpack_current_row(rli, &m_cols_ai);
10887   }
10888   m_table->default_column_bitmaps();
10889   DBUG_RETURN(error);
10890 
10891 }
10892 
do_hash_row(Relay_log_info const * rli)10893 int Rows_log_event::do_hash_row(Relay_log_info const *rli)
10894 {
10895   DBUG_ENTER("Rows_log_event::do_hash_row");
10896   assert(m_table && m_table->in_use != NULL);
10897   int error= 0;
10898 
10899   /* create an empty entry to add to the hash table */
10900   HASH_ROW_ENTRY* entry= m_hash.make_entry();
10901   if (entry == NULL)
10902   {
10903     error= 1;
10904     goto end;
10905   }
10906   /* Prepare the record, unpack and save positions. */
10907   entry->positions->bi_start= m_curr_row;        // save the bi start pos
10908   prepare_record(m_table, &m_cols, false);
10909   if ((error= unpack_current_row(rli, &m_cols)))
10910     goto end;
10911   entry->positions->bi_ends= m_curr_row_end;    // save the bi end pos
10912 
10913   /*
10914     Now that m_table->record[0] is filled in, we can add the entry
10915     to the hash table. Note that the put operation calculates the
10916     key based on record[0] contents (including BLOB fields).
10917    */
10918   m_hash.put(m_table, &m_cols, entry);
10919 
10920   if (m_key_index < MAX_KEY)
10921     add_key_to_distinct_keyset();
10922 
10923   /*
10924     We need to unpack the AI to advance the positions, so we
10925     know when we have reached m_rows_end and that we do not
10926     unpack the AI in the next iteration as if it was a BI.
10927   */
10928   if (get_general_type_code() == binary_log::UPDATE_ROWS_EVENT)
10929   {
10930     /* Save a copy of the BI. */
10931     store_record(m_table, record[1]);
10932 
10933      /*
10934       This is the situation after hashing the BI:
10935 
10936       ===|=== before image ====|=== after image ===|===
10937          ^                     ^
10938          m_curr_row            m_curr_row_end
10939     */
10940 
10941     /* Set the position to the start of the record to be unpacked. */
10942     m_curr_row= m_curr_row_end;
10943 
10944     /* We shouldn't need this, but lets not leave loose ends */
10945     prepare_record(m_table, &m_cols, false);
10946     error= unpack_current_row(rli, &m_cols_ai);
10947 
10948     /*
10949       This is the situation after unpacking the AI:
10950 
10951       ===|=== before image ====|=== after image ===|===
10952                                ^                   ^
10953                                m_curr_row          m_curr_row_end
10954     */
10955 
10956     /* Restore back the copy of the BI. */
10957     restore_record(m_table, record[1]);
10958   }
10959 
10960 end:
10961   DBUG_RETURN(error);
10962 }
10963 
do_scan_and_update(Relay_log_info const * rli)10964 int Rows_log_event::do_scan_and_update(Relay_log_info const *rli)
10965 {
10966   DBUG_ENTER("Rows_log_event::do_scan_and_update");
10967   assert(m_table && m_table->in_use != NULL);
10968   assert(m_hash.is_empty() == false);
10969   TABLE *table= m_table;
10970   int error= 0;
10971   const uchar *saved_last_m_curr_row= NULL;
10972   const uchar *saved_last_m_curr_row_end= NULL;
10973   /* create an empty entry to add to the hash table */
10974   HASH_ROW_ENTRY* entry= NULL;
10975   int idempotent_errors= 0;
10976   int i= 0;
10977 
10978   saved_last_m_curr_row=m_curr_row;
10979   saved_last_m_curr_row_end=m_curr_row_end;
10980 
10981   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
10982 
10983   /* open table or index depending on whether we have set m_key_index or not. */
10984   if ((error= open_record_scan()))
10985     goto err;
10986 
10987   /*
10988      Scan the table only once and compare against entries in hash.
10989      When a match is found, apply the changes.
10990    */
10991   do
10992   {
10993     /* get the next record from the table */
10994     error= next_record_scan(i == 0);
10995     i++;
10996 
10997     if(error)
10998       DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10999     switch (error) {
11000       case 0:
11001       {
11002         entry= m_hash.get(table, &m_cols);
11003         store_record(table, record[1]);
11004 
11005         /**
11006            If there are collisions we need to be sure that this is
11007            indeed the record we want.  Loop through all records for
11008            the given key and explicitly compare them against the
11009            record we got from the storage engine.
11010          */
11011         while(entry)
11012         {
11013           m_curr_row= entry->positions->bi_start;
11014           m_curr_row_end= entry->positions->bi_ends;
11015 
11016           prepare_record(table, &m_cols, false);
11017           if ((error= unpack_current_row(rli, &m_cols)))
11018             goto close_table;
11019 
11020           if (record_compare(table, &m_cols))
11021             m_hash.next(&entry);
11022           else
11023             break;   // we found a match
11024         }
11025 
11026         /**
11027            We found the entry we needed, just apply the changes.
11028          */
11029         if (entry)
11030         {
11031           // just to be safe, copy the record from the SE to table->record[0]
11032           restore_record(table, record[1]);
11033 
11034           /**
11035              At this point, both table->record[0] and
11036              table->record[1] have the SE row that matched the one
11037              in the hash table.
11038 
11039              Thence if this is a DELETE we wouldn't need to mess
11040              around with positions anymore, but since this can be an
11041              update, we need to provide positions so that AI is
11042              unpacked correctly to table->record[0] in UPDATE
11043              implementation of do_exec_row().
11044           */
11045           m_curr_row= entry->positions->bi_start;
11046           m_curr_row_end= entry->positions->bi_ends;
11047 
11048           /* we don't need this entry anymore, just delete it */
11049           if ((error= m_hash.del(entry)))
11050             goto err;
11051 
11052           if ((error= do_apply_row(rli)))
11053           {
11054             if (handle_idempotent_and_ignored_errors(rli, &error))
11055               goto close_table;
11056 
11057             do_post_row_operations(rli, error);
11058           }
11059         }
11060       }
11061       break;
11062 
11063       case HA_ERR_RECORD_DELETED:
11064         // get next
11065         continue;
11066 
11067       case HA_ERR_KEY_NOT_FOUND:
11068         /* If the slave exec mode is idempotent or the error is
11069             skipped error, then don't break */
11070         if (handle_idempotent_and_ignored_errors(rli, &error))
11071           goto close_table;
11072         idempotent_errors++;
11073         continue;
11074 
11075       case HA_ERR_END_OF_FILE:
11076       default:
11077         // exception (hash is not empty and we have reached EOF or
11078         // other error happened)
11079         goto close_table;
11080     }
11081   }
11082   /**
11083     if the rbr_exec_mode is set to Idempotent, we cannot expect the hash to
11084     be empty. In such cases we count the number of idempotent errors and check
11085     if it is equal to or greater than the number of rows left in the hash.
11086    */
11087   while (((idempotent_errors < m_hash.size()) && !m_hash.is_empty()) &&
11088          (!error || (error == HA_ERR_RECORD_DELETED)));
11089 
11090 close_table:
11091   if (error == HA_ERR_RECORD_DELETED)
11092     error= 0;
11093 
11094   if (error)
11095   {
11096     table->file->print_error(error, MYF(0));
11097     DBUG_PRINT("info", ("Failed to get next record"
11098                         " (ha_rnd_next returns %d)",error));
11099     /*
11100       we are already with errors. Keep the error code and
11101       try to close the scan anyway.
11102     */
11103     (void) close_record_scan();
11104   }
11105   else
11106     error= close_record_scan();
11107 
11108   assert((m_hash.is_empty() && !error) ||
11109          (!m_hash.is_empty() &&
11110           ((error) || (idempotent_errors >= m_hash.size()))));
11111 
11112 err:
11113 
11114   if ((m_hash.is_empty() && !error) || (idempotent_errors >= m_hash.size()))
11115   {
11116     /**
11117        Reset the last positions, because the positions are lost while
11118        handling entries in the hash.
11119      */
11120     m_curr_row= saved_last_m_curr_row;
11121     m_curr_row_end= saved_last_m_curr_row_end;
11122   }
11123 
11124   DBUG_RETURN(error);
11125 }
11126 
do_hash_scan_and_update(Relay_log_info const * rli)11127 int Rows_log_event::do_hash_scan_and_update(Relay_log_info const *rli)
11128 {
11129   DBUG_ENTER("Rows_log_event::do_hash_scan_and_update");
11130   assert(m_table && m_table->in_use != NULL);
11131 
11132   // HASHING PART
11133 
11134   /* unpack the BI (and AI, if it exists) and add it to the hash map. */
11135   if (int error= this->do_hash_row(rli))
11136     DBUG_RETURN(error);
11137 
11138   /* We have not yet hashed all rows in the buffer. Do not proceed to the SCAN part. */
11139   if (m_curr_row_end < m_rows_end)
11140     DBUG_RETURN (0);
11141 
11142   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11143   assert(m_curr_row_end == m_rows_end);
11144 
11145   // SCANNING & UPDATE PART
11146 
11147   DBUG_RETURN(this->do_scan_and_update(rli));
11148 }
11149 
do_table_scan_and_update(Relay_log_info const * rli)11150 int Rows_log_event::do_table_scan_and_update(Relay_log_info const *rli)
11151 {
11152   int error= 0;
11153   const uchar* saved_m_curr_row= m_curr_row;
11154   TABLE* table= m_table;
11155 
11156   DBUG_ENTER("Rows_log_event::do_table_scan_and_update");
11157   assert(m_curr_row != m_rows_end);
11158   DBUG_PRINT("info",("locating record using table scan (ha_rnd_next)"));
11159 
11160   saved_m_curr_row= m_curr_row;
11161 
11162   /** unpack the before image */
11163   prepare_record(table, &m_cols, FALSE);
11164   if (!(error= unpack_current_row(rli, &m_cols)))
11165   {
11166     /** save a copy so that we can compare against it later */
11167     store_record(m_table, record[1]);
11168 
11169     int restart_count= 0; // Number of times scanning has restarted from top
11170 
11171     if ((error= m_table->file->ha_rnd_init(1)))
11172     {
11173       DBUG_PRINT("info",("error initializing table scan"
11174                          " (ha_rnd_init returns %d)",error));
11175       goto end;
11176     }
11177 
11178     /* Continue until we find the right record or have made a full loop */
11179     do
11180     {
11181   restart_ha_rnd_next:
11182       error= m_table->file->ha_rnd_next(m_table->record[0]);
11183       if (error)
11184         DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11185       switch (error) {
11186       case HA_ERR_END_OF_FILE:
11187         // restart scan from top
11188         if (++restart_count < 2)
11189         {
11190           if ((error= m_table->file->ha_rnd_init(1)))
11191             goto end;
11192           goto restart_ha_rnd_next;
11193         }
11194         break;
11195 
11196       case HA_ERR_RECORD_DELETED:
11197         // fetch next
11198         goto restart_ha_rnd_next;
11199       case 0:
11200         // we're good, check if record matches
11201         break;
11202 
11203       default:
11204         // exception
11205         goto end;
11206       }
11207     }
11208     while (restart_count < 2 && record_compare(m_table, &m_cols));
11209   }
11210 
11211 end:
11212 
11213   assert(error != HA_ERR_RECORD_DELETED);
11214 
11215   /* either we report error or apply the changes */
11216   if (error && error != HA_ERR_RECORD_DELETED)
11217   {
11218     DBUG_PRINT("info", ("Failed to get next record"
11219                         " (ha_rnd_next returns %d)",error));
11220     m_table->file->print_error(error, MYF(0));
11221   }
11222   else
11223     error= do_apply_row(rli);
11224 
11225 
11226   if (!error)
11227     error= close_record_scan();
11228   else
11229     /*
11230       we are already with errors. Keep the error code and
11231       try to close the scan anyway.
11232     */
11233     (void) close_record_scan();
11234 
11235   if ((get_general_type_code() == binary_log::UPDATE_ROWS_EVENT) &&
11236       (saved_m_curr_row == m_curr_row)) // we need to unpack the AI
11237   {
11238     m_curr_row= m_curr_row_end;
11239     unpack_current_row(rli, &m_cols);
11240   }
11241 
11242   table->default_column_bitmaps();
11243   DBUG_RETURN(error);
11244 }
11245 
do_apply_event(Relay_log_info const * rli)11246 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
11247 {
11248   DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
11249   TABLE *table= NULL;
11250   int error= 0;
11251 
11252   /*
11253     'thd' has been set by exec_relay_log_event(), just before calling
11254     do_apply_event(). We still check here to prevent future coding
11255     errors.
11256   */
11257   assert(rli->info_thd == thd);
11258 
11259   /*
11260     If there is no locks taken, this is the first binrow event seen
11261     after the table map events.  We should then lock all the tables
11262     used in the transaction and proceed with execution of the actual
11263     event.
11264   */
11265   if (!thd->lock)
11266   {
11267     /*
11268       Lock_tables() reads the contents of thd->lex, so they must be
11269       initialized.
11270 
11271       We also call the mysql_reset_thd_for_next_command(), since this
11272       is the logical start of the next "statement". Note that this
11273       call might reset the value of current_stmt_binlog_format, so
11274       we need to do any changes to that value after this function.
11275     */
11276     lex_start(thd);
11277     mysql_reset_thd_for_next_command(thd);
11278 
11279     enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
11280     if (state == GTID_STATEMENT_EXECUTE)
11281     {
11282       if (gtid_pre_statement_post_implicit_commit_checks(thd))
11283         state= GTID_STATEMENT_CANCEL;
11284     }
11285 
11286     if (state == GTID_STATEMENT_CANCEL)
11287     {
11288       uint error= thd->get_stmt_da()->mysql_errno();
11289       assert(error != 0);
11290       rli->report(ERROR_LEVEL, error,
11291                   "Error executing row event: '%s'",
11292                   thd->get_stmt_da()->message_text());
11293       thd->is_slave_error= 1;
11294       DBUG_RETURN(-1);
11295     }
11296     else if (state == GTID_STATEMENT_SKIP)
11297       goto end;
11298 
11299     /*
11300       The current statement is just about to begin and
11301       has not yet modified anything. Note, all.modified is reset
11302       by mysql_reset_thd_for_next_command.
11303     */
11304     thd->get_transaction()->reset_unsafe_rollback_flags(Transaction_ctx::STMT);
11305     /*
11306       This is a row injection, so we flag the "statement" as
11307       such. Note that this code is called both when the slave does row
11308       injections and when the BINLOG statement is used to do row
11309       injections.
11310     */
11311     thd->lex->set_stmt_row_injection();
11312 
11313     /*
11314       There are a few flags that are replicated with each row event.
11315       Make sure to set/clear them before executing the main body of
11316       the event.
11317     */
11318     if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
11319       thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
11320     else
11321       thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
11322 
11323     if (get_flags(RELAXED_UNIQUE_CHECKS_F))
11324       thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
11325     else
11326       thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
11327 
11328     thd->binlog_row_event_extra_data = m_extra_row_data;
11329 
11330     /* A small test to verify that objects have consistent types */
11331     assert(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
11332     DBUG_EXECUTE_IF("rows_log_event_before_open_table",
11333                     {
11334                       const char action[] = "now SIGNAL before_open_table WAIT_FOR go_ahead_sql";
11335                       assert(!debug_sync_set_action(thd, STRING_WITH_LEN(action)));
11336                     };);
11337     if (open_and_lock_tables(thd, rli->tables_to_lock, 0))
11338     {
11339       if (thd->is_error())
11340       {
11341         uint actual_error= thd->get_stmt_da()->mysql_errno();
11342         if (ignored_error_code(actual_error))
11343         {
11344           if (log_warnings > 1)
11345             rli->report(WARNING_LEVEL, actual_error,
11346                         "Error executing row event: '%s'",
11347                         thd->get_stmt_da()->message_text());
11348           thd->get_stmt_da()->reset_condition_info(thd);
11349           clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11350           error= 0;
11351           goto end;
11352         }
11353         else
11354         {
11355           rli->report(ERROR_LEVEL, actual_error,
11356                       "Error executing row event: '%s'",
11357                       thd->get_stmt_da()->message_text());
11358           thd->is_slave_error= 1;
11359         }
11360       }
11361       DBUG_RETURN(1);
11362     }
11363 
11364     /*
11365       When the open and locking succeeded, we check all tables to
11366       ensure that they still have the correct type.
11367     */
11368 
11369     {
11370       DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
11371                            rli->tables_to_lock));
11372 
11373       /**
11374         When using RBR and MyISAM MERGE tables the base tables that make
11375         up the MERGE table can be appended to the list of tables to lock.
11376 
11377         Thus, we just check compatibility for those that tables that have
11378         a correspondent table map event (ie, those that are actually going
11379         to be accessed while applying the event). That's why the loop stops
11380         at rli->tables_to_lock_count .
11381 
11382         NOTE: The base tables are added here are removed when
11383               close_thread_tables is called.
11384        */
11385       TABLE_LIST *table_list_ptr= rli->tables_to_lock;
11386       for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count);
11387            table_list_ptr= table_list_ptr->next_global, i++)
11388       {
11389         /*
11390           Below if condition takes care of skipping base tables that
11391           make up the MERGE table (which are added by open_tables()
11392           call). They are added next to the merge table in the list.
11393           For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
11394           are base tables for merge table 't3'), open_tables will modify
11395           the list by adding t1 and t2 again immediately after t3 in the
11396           list (*not at the end of the list*). New table_to_lock list will
11397           look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
11398           objects added by open_tables() call). There is no flag(or logic) in
11399           open_tables() that can skip adding these base tables to the list.
11400           So the logic here should take care of skipping them.
11401 
11402           tables_to_lock_count logic will take care of skipping base tables
11403           that are added at the end of the list.
11404           For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
11405           the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
11406           because tables_to_lock_count logic in this for loop.
11407         */
11408         if (table_list_ptr->parent_l)
11409           continue;
11410         /*
11411           We can use a down cast here since we know that every table added
11412           to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
11413           skipped above).
11414         */
11415         RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
11416         assert(ptr->m_tabledef_valid);
11417         TABLE *conv_table;
11418         if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
11419                                              ptr->table, &conv_table))
11420         {
11421           DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
11422                                ptr->table->s->db.str,
11423                                ptr->table->s->table_name.str));
11424           if (thd->is_slave_error)
11425           {
11426             const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
11427             DBUG_RETURN(ERR_BAD_TABLE_DEF);
11428           }
11429           else
11430           {
11431             thd->get_stmt_da()->reset_condition_info(thd);
11432             clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11433             error= 0;
11434             goto end;
11435           }
11436         }
11437         DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
11438                              " - conv_table: %p",
11439                              ptr->table->s->db.str,
11440                              ptr->table->s->table_name.str, conv_table));
11441         ptr->m_conv_table= conv_table;
11442       }
11443     }
11444 
11445     /*
11446       ... and then we add all the tables to the table map and but keep
11447       them in the tables to lock list.
11448 
11449       We also invalidate the query cache for all the tables, since
11450       they will now be changed.
11451 
11452       TODO [/Matz]: Maybe the query cache should not be invalidated
11453       here? It might be that a table is not changed, even though it
11454       was locked for the statement.  We do know that each
11455       Rows_log_event contain at least one row, so after processing one
11456       Rows_log_event, we can invalidate the query cache for the
11457       associated table.
11458      */
11459     TABLE_LIST *ptr= rli->tables_to_lock;
11460     for (uint i=0 ;  ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
11461     {
11462       /*
11463         Please see comment in above 'for' loop to know the reason
11464         for this if condition
11465       */
11466       if (ptr->parent_l)
11467         continue;
11468       const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
11469     }
11470 
11471     query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11472   }
11473 
11474   table=
11475     m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
11476 
11477   DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %llu", (ulong) m_table,
11478                        m_table_id.id()));
11479 
11480   /*
11481     A row event comprising of a P_S table
11482     - should not be replicated (i.e executed) by the slave SQL thread.
11483     - should not be executed by the client in the  form BINLOG '...' stmts.
11484   */
11485   if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
11486     table= NULL;
11487 
11488   if (table)
11489   {
11490     /*
11491       table == NULL means that this table should not be replicated
11492       (this was set up by Table_map_log_event::do_apply_event()
11493       which tested replicate-* rules).
11494     */
11495 
11496     /*
11497       It's not needed to set_time() but
11498       1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11499       much slave is behind
11500       2) it will be needed when we allow replication from a table with no
11501       TIMESTAMP column to a table with one.
11502       So we call set_time(), like in SBR. Presently it changes nothing.
11503     */
11504     thd->set_time(&(common_header->when));
11505 
11506     /*
11507       We don't consider index extensions in RBR, as doing so would cause
11508       replication failure with UPDATE/DELETE when replica server has a PK on
11509       extra columns and source does not.
11510     */
11511     Disable_index_extensions_switch_guard guard(thd);
11512 
11513     thd->binlog_row_event_extra_data = m_extra_row_data;
11514 
11515     /*
11516       Now we are in a statement and will stay in a statement until we
11517       see a STMT_END_F.
11518 
11519       We set this flag here, before actually applying any rows, in
11520       case the SQL thread is stopped and we need to detect that we're
11521       inside a statement and halting abruptly might cause problems
11522       when restarting.
11523      */
11524     const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
11525 
11526      if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11527       set_flags(COMPLETE_ROWS_F);
11528 
11529     /*
11530       Set tables write and read sets.
11531 
11532       Read_set contains all slave columns (in case we are going to fetch
11533       a complete record from slave)
11534 
11535       Write_set equals the m_cols bitmap sent from master but it can be
11536       longer if slave has extra columns.
11537      */
11538 
11539     DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11540 
11541     /*
11542       Call mark_generated_columns() to set read_set/write_set bits of the
11543       virtual generated columns as required in order to get these computed.
11544       This is needed since all columns need to have a value in the before
11545       image for the record when doing the update (some storage engines will
11546       use this for maintaining of secondary indexes). This call is required
11547       even for DELETE events to set write_set bit in order to satisfy
11548       ASSERTs in Field_*::store functions.
11549 
11550       binlog_prepare_row_image() function, which will be called from
11551       binlogging functions (binlog_update_row() and binlog_delete_row())
11552       will take care of removing these spurious fields required during
11553       execution but not needed for binlogging. In case of inserts, there
11554       are no spurious fields (all generated columns are required to be written
11555       into the binlog).
11556     */
11557 
11558     bitmap_set_all(table->read_set);
11559     bitmap_set_all(table->write_set);
11560 
11561     switch (get_general_type_code()) {
11562       case binary_log::DELETE_ROWS_EVENT:
11563         bitmap_intersect(table->read_set, &m_cols);
11564         bitmap_intersect(table->write_set, &m_cols);
11565         if (m_table->vfield)
11566           m_table->mark_generated_columns(false);
11567         break;
11568       case binary_log::UPDATE_ROWS_EVENT:
11569         bitmap_intersect(table->read_set, &m_cols);
11570         bitmap_intersect(table->write_set, &m_cols_ai);
11571         if (m_table->vfield)
11572           m_table->mark_generated_columns(true);
11573         break;
11574       case binary_log::WRITE_ROWS_EVENT:
11575         /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11576         bitmap_intersect(table->write_set, &m_cols);
11577         if (m_table->vfield)
11578           m_table->mark_generated_columns(false);
11579         break;
11580       default:
11581         assert(false);
11582     }
11583 
11584     if (thd->slave_thread) // set the mode for slave
11585       this->rbr_exec_mode= slave_exec_mode_options;
11586     else //set the mode for user thread
11587       this->rbr_exec_mode= thd->variables.rbr_exec_mode_options;
11588 
11589     // Do event specific preparations
11590     error= do_before_row_operations(rli);
11591 
11592     /*
11593       Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11594       Don't allow generation of auto_increment value when processing
11595       rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
11596       to this rule happens when the auto_inc column exists on some
11597       extra columns on the slave. In that case, do not force
11598       MODE_NO_AUTO_VALUE_ON_ZERO.
11599     */
11600     sql_mode_t saved_sql_mode= thd->variables.sql_mode;
11601     if (!is_auto_inc_in_extra_columns())
11602       thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11603 
11604     // row processing loop
11605 
11606     /*
11607       set the initial time of this ROWS statement if it was not done
11608       before in some other ROWS event.
11609      */
11610     const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
11611 
11612     const uchar *saved_m_curr_row= m_curr_row;
11613 
11614     int (Rows_log_event::*do_apply_row_ptr)(Relay_log_info const *)= NULL;
11615 
11616     /**
11617        Skip update rows events that don't have data for this slave's
11618        table.
11619      */
11620     if ((get_general_type_code() == binary_log::UPDATE_ROWS_EVENT) &&
11621         !is_any_column_signaled_for_table(table, &m_cols_ai))
11622       goto AFTER_MAIN_EXEC_ROW_LOOP;
11623 
11624     /**
11625        If there are no columns marked in the read_set for this table,
11626        that means that we cannot lookup any row using the available BI
11627        in the binarr log. Thence, we immediatly raise an error:
11628        HA_ERR_END_OF_FILE.
11629      */
11630 
11631     if ((m_rows_lookup_algorithm != ROW_LOOKUP_NOT_NEEDED) &&
11632         !is_any_column_signaled_for_table(table, &m_cols))
11633     {
11634       error= HA_ERR_END_OF_FILE;
11635       goto AFTER_MAIN_EXEC_ROW_LOOP;
11636     }
11637     switch (m_rows_lookup_algorithm)
11638     {
11639       case ROW_LOOKUP_HASH_SCAN:
11640         do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11641         break;
11642 
11643       case ROW_LOOKUP_INDEX_SCAN:
11644         do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11645         break;
11646 
11647       case ROW_LOOKUP_TABLE_SCAN:
11648         do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11649         break;
11650 
11651       case ROW_LOOKUP_NOT_NEEDED:
11652         assert(get_general_type_code() == binary_log::WRITE_ROWS_EVENT ||
11653                get_general_type_code() == binary_log::DELETE_ROWS_EVENT ||
11654                get_general_type_code() == binary_log::UPDATE_ROWS_EVENT);
11655 
11656         /* No need to scan for rows, just apply it */
11657         do_apply_row_ptr= &Rows_log_event::do_apply_row;
11658         break;
11659 
11660       default:
11661         assert(0);
11662         error= 1;
11663         goto AFTER_MAIN_EXEC_ROW_LOOP;
11664         break;
11665     }
11666 
11667     do {
11668 
11669       error= (this->*do_apply_row_ptr)(rli);
11670 
11671       if (!error)
11672         thd->updated_row_count++;
11673 
11674       if (handle_idempotent_and_ignored_errors(rli, &error))
11675         break;
11676 
11677       /* this advances m_curr_row */
11678       do_post_row_operations(rli, error);
11679 
11680     } while (!error && (m_curr_row != m_rows_end));
11681 
11682     if (unlikely(opt_userstat))
11683     {
11684       thd->update_stats(false);
11685 #ifndef EMBEDDED_LIBRARY
11686       update_global_user_stats(thd, true, time(NULL));
11687 #endif
11688     }
11689 
11690 AFTER_MAIN_EXEC_ROW_LOOP:
11691 
11692     if (saved_m_curr_row != m_curr_row && !table->file->has_transactions())
11693     {
11694       /*
11695         Usually, the trans_commit_stmt() propagates unsafe_rollback_flags
11696         from statement to transaction level. However, we cannot rely on
11697         this when row format is in use as several events can be processed
11698         before calling this function. This happens because it is called
11699         only when the latest event generated by a statement is processed.
11700 
11701         There are however upper level functions that execute per event
11702         and check transaction's status. So if the unsafe_rollback_flags
11703         are not propagated here, this can lead to errors.
11704 
11705         For example, a transaction that updates non-transactional tables
11706         may be stopped in the middle thus leading to inconsistencies
11707         after a restart.
11708       */
11709       thd->get_transaction()->mark_modified_non_trans_table(
11710         Transaction_ctx::STMT);
11711       thd->get_transaction()->merge_unsafe_rollback_flags();
11712     }
11713 
11714     /*
11715       Restore the sql_mode after the rows event is processed.
11716     */
11717     thd->variables.sql_mode= saved_sql_mode;
11718 
11719     {/*
11720          The following failure injecion works in cooperation with tests
11721          setting @@global.debug= 'd,stop_slave_middle_group'.
11722          The sql thread receives the killed status and will proceed
11723          to shutdown trying to finish incomplete events group.
11724      */
11725       DBUG_EXECUTE_IF("stop_slave_middle_group",
11726                       if (thd->get_transaction()->cannot_safely_rollback(
11727                           Transaction_ctx::SESSION))
11728                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11729     }
11730 
11731     if ((error= do_after_row_operations(rli, error)) &&
11732         ignored_error_code(convert_handler_error(error, thd, table)))
11733     {
11734       slave_rows_error_report(INFORMATION_LEVEL, error, rli, thd, table,
11735                               get_type_str(),
11736                               const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11737                               (ulong) common_header->log_pos);
11738       thd->get_stmt_da()->reset_condition_info(thd);
11739       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11740       error= 0;
11741     }
11742   } // if (table)
11743 
11744   if (error)
11745   {
11746     slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
11747                             get_type_str(),
11748                             const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11749                             (ulong) common_header->log_pos);
11750     /*
11751       @todo We should probably not call
11752       reset_current_stmt_binlog_format_row() from here.
11753 
11754       Note: this applies to log_event_old.cc too.
11755       /Sven
11756     */
11757     thd->reset_current_stmt_binlog_format_row();
11758     thd->is_slave_error= 1;
11759     DBUG_RETURN(error);
11760   }
11761 
11762 end:
11763   if (get_flags(STMT_END_F))
11764   {
11765     if((error= rows_event_stmt_cleanup(rli, thd)))
11766     {
11767       if (table)
11768         slave_rows_error_report(ERROR_LEVEL,
11769                                 thd->is_error() ? 0 : error,
11770                                 rli, thd, table,
11771                                 get_type_str(),
11772                                 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11773                                 (ulong) common_header->log_pos);
11774       else
11775       {
11776         rli->report(ERROR_LEVEL,
11777                     thd->is_error() ? thd->get_stmt_da()->mysql_errno() : error,
11778                     "Error in cleaning up after an event of type:%s; %s; the group"
11779                     " log file/position: %s %lu", get_type_str(),
11780                     thd->is_error() ? thd->get_stmt_da()->message_text() :
11781                     "unexpected error",
11782                     const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11783                     (ulong) common_header->log_pos);
11784       }
11785     }
11786    /* We are at end of the statement (STMT_END_F flag), lets clean
11787      the memory which was used from thd's mem_root now.
11788      This needs to be done only if we are here in SQL thread context.
11789      In other flow ( in case of a regular thread which can happen
11790      when the thread is applying BINLOG'...' row event) we should
11791      *not* try to free the memory here. It will be done latter
11792      in dispatch_command() after command execution is completed.
11793     */
11794    if (thd->slave_thread)
11795      free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
11796   }
11797   DBUG_RETURN(error);
11798 }
11799 
11800 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)11801 Rows_log_event::do_shall_skip(Relay_log_info *rli)
11802 {
11803   /*
11804     If the slave skip counter is 1 and this event does not end a
11805     statement, then we should not start executing on the next event.
11806     Otherwise, we defer the decision to the normal skipping logic.
11807   */
11808   if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11809     return Log_event::EVENT_SKIP_IGNORE;
11810   else
11811     return Log_event::do_shall_skip(rli);
11812 }
11813 
11814 /**
11815    The function is called at Rows_log_event statement commit time,
11816    normally from Rows_log_event::do_update_pos() and possibly from
11817    Query_log_event::do_apply_event() of the COMMIT.
11818    The function commits the last statement for engines, binlog and
11819    releases resources have been allocated for the statement.
11820 
11821    @retval  0         Ok.
11822    @retval  non-zero  Error at the commit.
11823  */
11824 
rows_event_stmt_cleanup(Relay_log_info const * rli,THD * thd)11825 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
11826 {
11827   DBUG_EXECUTE_IF("simulate_rows_event_cleanup_failure",
11828                   {
11829                   my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
11830                   return (1);
11831                   });
11832   int error;
11833   {
11834     /*
11835       This is the end of a statement or transaction, so close (and
11836       unlock) the tables we opened when processing the
11837       Table_map_log_event starting the statement.
11838 
11839       OBSERVER.  This will clear *all* mappings, not only those that
11840       are open for the table. There is not good handle for on-close
11841       actions for tables.
11842 
11843       NOTE. Even if we have no table ('table' == 0) we still need to be
11844       here, so that we increase the group relay log position. If we didn't, we
11845       could have a group relay log position which lags behind "forever"
11846       (assume the last master's transaction is ignored by the slave because of
11847       replicate-ignore rules).
11848     */
11849     error= thd->binlog_flush_pending_rows_event(TRUE);
11850 
11851     /*
11852       If this event is not in a transaction, the call below will, if some
11853       transactional storage engines are involved, commit the statement into
11854       them and flush the pending event to binlog.
11855       If this event is in a transaction, the call will do nothing, but a
11856       Xid_log_event will come next which will, if some transactional engines
11857       are involved, commit the transaction and flush the pending event to the
11858       binlog.
11859       If there was a deadlock the transaction should have been rolled back
11860       already. So there should be no need to rollback the transaction.
11861     */
11862     assert(! thd->transaction_rollback_request);
11863     error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11864 
11865     /*
11866       Now what if this is not a transactional engine? we still need to
11867       flush the pending event to the binlog; we did it with
11868       thd->binlog_flush_pending_rows_event(). Note that we imitate
11869       what is done for real queries: a call to
11870       ha_autocommit_or_rollback() (sometimes only if involves a
11871       transactional engine), and a call to be sure to have the pending
11872       event flushed.
11873     */
11874 
11875     /*
11876       @todo We should probably not call
11877       reset_current_stmt_binlog_format_row() from here.
11878 
11879       Note: this applies to log_event_old.cc too
11880 
11881       Btw, the previous comment about transactional engines does not
11882       seem related to anything that happens here.
11883       /Sven
11884     */
11885     thd->reset_current_stmt_binlog_format_row();
11886 
11887     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
11888 
11889     /*
11890       Clean sql_command value
11891     */
11892     thd->lex->sql_command= SQLCOM_END;
11893 
11894   }
11895   return error;
11896 }
11897 
11898 /**
11899    The method either increments the relay log position or
11900    commits the current statement and increments the master group
11901    possition if the event is STMT_END_F flagged and
11902    the statement corresponds to the autocommit query (i.e replicated
11903    without wrapping in BEGIN/COMMIT)
11904 
11905    @retval 0         Success
11906    @retval non-zero  Error in the statement commit
11907  */
11908 int
do_update_pos(Relay_log_info * rli)11909 Rows_log_event::do_update_pos(Relay_log_info *rli)
11910 {
11911   DBUG_ENTER("Rows_log_event::do_update_pos");
11912   int error= 0;
11913 
11914   DBUG_PRINT("info", ("flags: %s",
11915                       get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11916 
11917   /* Worker does not execute binlog update position logics */
11918   assert(!is_mts_worker(rli->info_thd));
11919 
11920   if (get_flags(STMT_END_F))
11921   {
11922     /*
11923       Indicate that a statement is finished.
11924       Step the group log position if we are not in a transaction,
11925       otherwise increase the event log position.
11926     */
11927     error= rli->stmt_done(common_header->log_pos);
11928   }
11929   else
11930   {
11931     rli->inc_event_relay_log_pos();
11932   }
11933 
11934   DBUG_RETURN(error);
11935 }
11936 
11937 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11938 
11939 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)11940 bool Rows_log_event::write_data_header(IO_CACHE *file)
11941 {
11942   uchar buf[Binary_log_event::ROWS_HEADER_LEN_V2];	// No need to init the buffer
11943   assert(m_table_id.is_valid());
11944   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11945                   {
11946                     int4store(buf + 0, (ulong) m_table_id.id());
11947                     int2store(buf + 4, m_flags);
11948                     return (wrapper_my_b_safe_write(file, buf, 6));
11949                   });
11950   int6store(buf + ROWS_MAPID_OFFSET, m_table_id.id());
11951   int2store(buf + ROWS_FLAGS_OFFSET, m_flags);
11952   int rc = 0;
11953   if (likely(!log_bin_use_v1_row_events))
11954   {
11955     /*
11956        v2 event, with variable header portion.
11957        Determine length of variable header payload
11958     */
11959     uint16 vhlen= 2;
11960     uint16 vhpayloadlen= 0;
11961     uint16 extra_data_len= 0;
11962     if (m_extra_row_data)
11963     {
11964       extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
11965       vhpayloadlen= ROWS_V_TAG_LEN + extra_data_len;
11966     }
11967 
11968     /* Var-size header len includes len itself */
11969     int2store(buf + ROWS_VHLEN_OFFSET, vhlen + vhpayloadlen);
11970     rc= wrapper_my_b_safe_write(file, buf, Binary_log_event::ROWS_HEADER_LEN_V2);
11971 
11972     /* Write var-sized payload, if any */
11973     if ((vhpayloadlen > 0) &&
11974         (rc == 0))
11975     {
11976       /* Add tag and extra row info */
11977       uchar type_code= ROWS_V_EXTRAINFO_TAG;
11978       rc= wrapper_my_b_safe_write(file, &type_code, ROWS_V_TAG_LEN);
11979       if (rc==0)
11980         rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
11981     }
11982   }
11983   else
11984   {
11985     rc= wrapper_my_b_safe_write(file, buf, Binary_log_event::ROWS_HEADER_LEN_V1);
11986   }
11987 
11988   return (rc != 0);
11989 }
11990 
write_data_body(IO_CACHE * file)11991 bool Rows_log_event::write_data_body(IO_CACHE*file)
11992 {
11993   /*
11994      Note that this should be the number of *bits*, not the number of
11995      bytes.
11996   */
11997   uchar sbuf[sizeof(m_width) + 1];
11998   my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
11999   bool res= false;
12000   uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
12001   assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
12002 
12003   DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
12004   res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
12005 
12006   DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
12007   res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
12008                               no_bytes_in_map(&m_cols));
12009   /*
12010     TODO[refactor write]: Remove the "down cast" here (and elsewhere).
12011    */
12012   if (get_general_type_code() == binary_log::UPDATE_ROWS_EVENT)
12013   {
12014     DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
12015               no_bytes_in_map(&m_cols_ai));
12016     res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
12017                                 no_bytes_in_map(&m_cols_ai));
12018   }
12019   DBUG_DUMP("rows", m_rows_buf, data_size);
12020   res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
12021 
12022   return res;
12023 
12024 }
12025 #endif
12026 
12027 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12028 int Rows_log_event::pack_info(Protocol *protocol)
12029 {
12030   char buf[256];
12031   char const *const flagstr=
12032     get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
12033   size_t bytes= my_snprintf(buf, sizeof(buf),
12034                             "table_id: %llu%s", m_table_id.id(), flagstr);
12035   protocol->store(buf, bytes, &my_charset_bin);
12036   return 0;
12037 }
12038 #endif
12039 
12040 #ifdef MYSQL_CLIENT
print_helper(FILE * file,PRINT_EVENT_INFO * print_event_info,char const * const name)12041 void Rows_log_event::print_helper(FILE *file,
12042                                   PRINT_EVENT_INFO *print_event_info,
12043                                   char const *const name)
12044 {
12045   IO_CACHE *const head= &print_event_info->head_cache;
12046   IO_CACHE *const body= &print_event_info->body_cache;
12047   if (!print_event_info->short_form)
12048   {
12049     bool const last_stmt_event= get_flags(STMT_END_F);
12050     print_header(head, print_event_info, !last_stmt_event);
12051     my_b_printf(head, "\t%s: table id %llu%s\n",
12052                 name, m_table_id.id(),
12053                 last_stmt_event ? " flags: STMT_END_F" : "");
12054     print_base64(body, print_event_info, !last_stmt_event);
12055   }
12056 }
12057 #endif
12058 
12059 /**************************************************************************
12060 	Table_map_log_event member functions and support functions
12061 **************************************************************************/
12062 
12063 /**
12064   @page How replication of field metadata works.
12065 
12066   When a table map is created, the master first calls
12067   Table_map_log_event::save_field_metadata() which calculates how many
12068   values will be in the field metadata. Only those fields that require the
12069   extra data are added. The method also loops through all of the fields in
12070   the table calling the method Field::save_field_metadata() which returns the
12071   values for the field that will be saved in the metadata and replicated to
12072   the slave. Once all fields have been processed, the table map is written to
12073   the binlog adding the size of the field metadata and the field metadata to
12074   the end of the body of the table map.
12075 
12076   When a table map is read on the slave, the field metadata is read from the
12077   table map and passed to the table_def class constructor which saves the
12078   field metadata from the table map into an array based on the type of the
12079   field. Field metadata values not present (those fields that do not use extra
12080   data) in the table map are initialized as zero (0). The array size is the
12081   same as the columns for the table on the slave.
12082 
12083   Additionally, values saved for field metadata on the master are saved as a
12084   string of bytes (uchar) in the binlog. A field may require 1 or more bytes
12085   to store the information. In cases where values require multiple bytes
12086   (e.g. values > 255), the endian-safe methods are used to properly encode
12087   the values on the master and decode them on the slave. When the field
12088   metadata values are captured on the slave, they are stored in an array of
12089   type uint16. This allows the least number of casts to prevent casting bugs
12090   when the field metadata is used in comparisons of field attributes. When
12091   the field metadata is used for calculating addresses in pointer math, the
12092   type used is uint32.
12093 */
12094 
12095 #if !defined(MYSQL_CLIENT)
12096 /**
12097   Save the field metadata based on the real_type of the field.
12098   The metadata saved depends on the type of the field. Some fields
12099   store a single byte for pack_length() while others store two bytes
12100   for field_length (max length).
12101 
12102   @retval  0  Ok.
12103 
12104   @todo
12105   We may want to consider changing the encoding of the information.
12106   Currently, the code attempts to minimize the number of bytes written to
12107   the tablemap. There are at least two other alternatives; 1) using
12108   net_store_length() to store the data allowing it to choose the number of
12109   bytes that are appropriate thereby making the code much easier to
12110   maintain (only 1 place to change the encoding), or 2) use a fixed number
12111   of bytes for each field. The problem with option 1 is that net_store_length()
12112   will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
12113   for fields like CHAR which can be no larger than 255 characters, the method
12114   will use 3 bytes when the value is > 250. Further, every value that is
12115   encoded using 2 parts (e.g., pack_length, field_length) will be numerically
12116   > 250 therefore will use 3 bytes for eah value. The problem with option 2
12117   is less wasteful for space but does waste 1 byte for every field that does
12118   not encode 2 parts.
12119 */
save_field_metadata()12120 int Table_map_log_event::save_field_metadata()
12121 {
12122   DBUG_ENTER("Table_map_log_event::save_field_metadata");
12123   int index= 0;
12124   for (unsigned int i= 0; i < m_table->s->fields ; i++)
12125   {
12126     DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
12127     index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
12128   }
12129   DBUG_RETURN(index);
12130 }
12131 #endif /* !defined(MYSQL_CLIENT) */
12132 
12133 /*
12134   Constructor used to build an event for writing to the binary log.
12135   Mats says tbl->s lives longer than this event so it's ok to copy pointers
12136   (tbl->s->db etc) and not pointer content.
12137  */
12138 #if !defined(MYSQL_CLIENT)
Table_map_log_event(THD * thd_arg,TABLE * tbl,const Table_id & tid,bool using_trans)12139 Table_map_log_event::Table_map_log_event(THD *thd_arg, TABLE *tbl,
12140                                          const Table_id& tid,
12141                                          bool using_trans)
12142   : binary_log::Table_map_event(tid, tbl->s->fields, (tbl->s->db.str),
12143                                 ((tbl->s->db.str) ? tbl->s->db.length : 0),
12144                                 (tbl->s->table_name.str),
12145                                 (tbl->s->table_name.length)),
12146     Log_event(thd_arg, 0,
12147               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
12148                             Log_event::EVENT_STMT_CACHE,
12149               Log_event::EVENT_NORMAL_LOGGING,
12150               header(), footer())
12151 {
12152   common_header->type_code= binary_log::TABLE_MAP_EVENT;
12153   m_table= tbl;
12154   m_flags= TM_BIT_LEN_EXACT_F;
12155 
12156   uchar cbuf[sizeof(m_colcnt) + 1];
12157   uchar *cbuf_end;
12158   assert(m_table_id.is_valid());
12159   /*
12160     In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
12161     table.cc / alloc_table_share():
12162       Use the fact the key is db/0/table_name/0
12163     As we rely on this let's assert it.
12164   */
12165   assert((tbl->s->db.str == 0) ||
12166          (tbl->s->db.str[tbl->s->db.length] == 0));
12167   assert(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
12168 
12169 
12170   m_data_size=  Binary_log_event::TABLE_MAP_HEADER_LEN;
12171   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
12172   m_data_size+= m_dblen + 2;	// Include length and terminating \0
12173   m_data_size+= m_tbllen + 2;	// Include length and terminating \0
12174   cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12175   assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12176   m_data_size+= (cbuf_end - cbuf) + m_colcnt;	// COLCNT and column types
12177 
12178   m_coltype= (uchar *)my_malloc(key_memory_log_event,
12179                                 m_colcnt, MYF(MY_WME));
12180 
12181   assert(m_colcnt == m_table->s->fields);
12182   for (unsigned int i= 0; i < m_table->s->fields; ++i)
12183     m_coltype[i]= m_table->field[i]->binlog_type();
12184 
12185 
12186   /*
12187     Calculate a bitmap for the results of maybe_null() for all columns.
12188     The bitmap is used to determine when there is a column from the master
12189     that is not on the slave and is null and thus not in the row data during
12190     replication.
12191   */
12192   uint num_null_bytes= (m_table->s->fields + 7) / 8;
12193   m_data_size+= num_null_bytes;
12194   /*
12195     m_null_bits is a pointer indicating which columns can have a null value
12196     in a particular table.
12197   */
12198   m_null_bits= (uchar *)my_malloc(key_memory_log_event,
12199                                   num_null_bytes, MYF(MY_WME));
12200 
12201   m_field_metadata= (uchar*)my_malloc(key_memory_log_event,
12202                                       (m_colcnt * 2), MYF(MY_WME));
12203   memset(m_field_metadata, 0, (m_colcnt * 2));
12204 
12205   if (m_null_bits != NULL && m_field_metadata != NULL && m_coltype != NULL)
12206     is_valid_param= true;
12207   /*
12208     Create an array for the field metadata and store it.
12209   */
12210   m_field_metadata_size= save_field_metadata();
12211   assert(m_field_metadata_size <= (m_colcnt * 2));
12212 
12213   /*
12214     Now set the size of the data to the size of the field metadata array
12215     plus one or three bytes (see pack.c:net_store_length) for number of
12216     elements in the field metadata array.
12217   */
12218   if (m_field_metadata_size < 251)
12219     m_data_size+= m_field_metadata_size + 1;
12220   else
12221     m_data_size+= m_field_metadata_size + 3;
12222 
12223   memset(m_null_bits, 0, num_null_bytes);
12224   for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12225     if (m_table->field[i]->maybe_null())
12226       m_null_bits[(i / 8)]+= 1 << (i % 8);
12227   /*
12228     Marking event to require sequential execution in MTS
12229     if the query might have updated FK-referenced db.
12230     Unlike Query_log_event where this fact is encoded through
12231     the accessed db list in the Table_map case m_flags is exploited.
12232   */
12233   uchar dbs= thd_arg->get_binlog_accessed_db_names() ?
12234     thd_arg->get_binlog_accessed_db_names()->elements : 0;
12235   if (dbs == 1)
12236   {
12237     char *db_name= thd_arg->get_binlog_accessed_db_names()->head();
12238     if (!strcmp(db_name, ""))
12239       m_flags |= TM_REFERRED_FK_DB_F;
12240   }
12241 }
12242 #endif /* !defined(MYSQL_CLIENT) */
12243 
12244 /*
12245   Constructor used by slave to read the event from the binary log.
12246  */
12247 #if defined(HAVE_REPLICATION)
Table_map_log_event(const char * buf,uint event_len,const Format_description_event * description_event)12248 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
12249                                          const Format_description_event
12250                                          *description_event)
12251 
12252    : binary_log::Table_map_event(buf, event_len, description_event),
12253      Log_event(header(), footer())
12254 #ifndef MYSQL_CLIENT
12255     ,m_table(NULL)
12256 #endif
12257 {
12258   DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
12259   if (m_null_bits != NULL && m_field_metadata != NULL && m_coltype != NULL)
12260     is_valid_param= true;
12261   assert(header()->type_code == binary_log::TABLE_MAP_EVENT);
12262   DBUG_VOID_RETURN;
12263 }
12264 #endif
12265 
~Table_map_log_event()12266 Table_map_log_event::~Table_map_log_event()
12267 {
12268   if(m_null_bits)
12269   {
12270     my_free(m_null_bits);
12271     m_null_bits= NULL;
12272   }
12273   if(m_field_metadata)
12274   {
12275     my_free(m_field_metadata);
12276     m_field_metadata= NULL;
12277   }
12278 }
12279 
12280 /*
12281   Return value is an error code, one of:
12282 
12283       -1     Failure to open table   [from open_tables()]
12284        0     Success
12285        1     No room for more tables [from set_table()]
12286        2     Out of memory           [from set_table()]
12287        3     Wrong table definition
12288        4     Daisy-chaining RBR with SBR not possible
12289  */
12290 
12291 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12292 
12293 enum enum_tbl_map_status
12294 {
12295   /* no duplicate identifier found */
12296   OK_TO_PROCESS= 0,
12297 
12298   /* this table map must be filtered out */
12299   FILTERED_OUT= 1,
12300 
12301   /* identifier mapping table with different properties */
12302   SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
12303 
12304   /* a duplicate identifier was found mapping the same table */
12305   SAME_ID_MAPPING_SAME_TABLE= 3,
12306 
12307   /*
12308     this table must be filtered out but found an active XA transaction. XA
12309     transactions shouldn't be used with replication filters, until disabling
12310     the XA read only optimization is a supported feature.
12311   */
12312   FILTERED_WITH_XA_ACTIVE = 4
12313 };
12314 
12315 /*
12316   Checks if this table map event should be processed or not. First
12317   it checks the filtering rules, and then looks for duplicate identifiers
12318   in the existing list of rli->tables_to_lock.
12319 
12320   It checks that there hasn't been any corruption by verifying that there
12321   are no duplicate entries with different properties.
12322 
12323   In some cases, some binary logs could get corrupted, showing several
12324   tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
12325   early sanity check for such cases and avoid that the server crashes
12326   later.
12327 
12328   In some corner cases, the master logs duplicate table map events, i.e.,
12329   same id, same database name, same table name (see: BUG#37137). This is
12330   different from the above as it's the same table that is mapped again
12331   to the same identifier. Thus we cannot just check for same ids and
12332   assume that the event is corrupted we need to check every property.
12333 
12334   NOTE: in the event that BUG#37137 ever gets fixed, this extra check
12335         will still be valid because we would need to support old binary
12336         logs anyway.
12337 
12338   @param rli The relay log info reference.
12339   @param table_list A list element containing the table to check against.
12340   @return OK_TO_PROCESS
12341             if there was no identifier already in rli->tables_to_lock
12342 
12343           FILTERED_OUT
12344             if the event is filtered according to the filtering rules
12345 
12346           SAME_ID_MAPPING_DIFFERENT_TABLE
12347             if the same identifier already maps a different table in
12348             rli->tables_to_lock
12349 
12350           SAME_ID_MAPPING_SAME_TABLE
12351             if the same identifier already maps the same table in
12352             rli->tables_to_lock.
12353 */
12354 static enum_tbl_map_status
check_table_map(Relay_log_info const * rli,RPL_TABLE_LIST * table_list)12355 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
12356 {
12357   DBUG_ENTER("check_table_map");
12358   enum_tbl_map_status res= OK_TO_PROCESS;
12359 
12360   if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
12361       (!rpl_filter->db_ok(table_list->db) ||
12362        (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
12363     if (rli->info_thd->get_transaction()->xid_state()->has_state(
12364             XID_STATE::XA_ACTIVE))
12365       res = FILTERED_WITH_XA_ACTIVE;
12366     else
12367       res = FILTERED_OUT;
12368   else
12369   {
12370     RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
12371     for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
12372         ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
12373     {
12374       if (ptr->table_id == table_list->table_id)
12375       {
12376 
12377         if (strcmp(ptr->db, table_list->db) ||
12378             strcmp(ptr->alias, table_list->table_name) ||
12379             ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
12380           res= SAME_ID_MAPPING_DIFFERENT_TABLE;
12381         else
12382           res= SAME_ID_MAPPING_SAME_TABLE;
12383 
12384         break;
12385       }
12386     }
12387   }
12388 
12389   DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
12390 
12391   DBUG_RETURN(res);
12392 }
12393 
do_apply_event(Relay_log_info const * rli)12394 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
12395 {
12396   RPL_TABLE_LIST *table_list;
12397   char *db_mem, *tname_mem, *ptr;
12398   size_t dummy_len;
12399   void *memory;
12400   DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
12401   assert(rli->info_thd == thd);
12402 
12403   /* Step the query id to mark what columns that are actually used. */
12404   thd->set_query_id(next_query_id());
12405 
12406   if (!(memory= my_multi_malloc(key_memory_log_event,
12407                                 MYF(MY_WME),
12408                                 &table_list, sizeof(RPL_TABLE_LIST),
12409                                 &db_mem, (uint) NAME_LEN + 1,
12410                                 &tname_mem, (uint) NAME_LEN + 1,
12411                                 NullS)))
12412     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
12413 
12414   my_stpcpy(db_mem, m_dbnam.c_str());
12415   my_stpcpy(tname_mem, m_tblnam.c_str());
12416 
12417   if (lower_case_table_names)
12418   {
12419     my_casedn_str(system_charset_info, db_mem);
12420     my_casedn_str(system_charset_info, tname_mem);
12421   }
12422 
12423   /* rewrite rules changed the database */
12424   if (((ptr= (char*) rpl_filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem))
12425     my_stpcpy(db_mem, ptr);
12426 
12427   table_list->init_one_table(db_mem, strlen(db_mem),
12428                              tname_mem, strlen(tname_mem),
12429                              tname_mem, TL_WRITE);
12430 
12431   table_list->table_id=
12432     DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id.id());
12433   table_list->updating= 1;
12434   table_list->required_type= FRMTYPE_TABLE;
12435   DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name,
12436                        table_list->table_id.id()));
12437 
12438   enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
12439   if (tblmap_status == OK_TO_PROCESS)
12440   {
12441     assert(thd->lex->query_tables != table_list);
12442 
12443     /*
12444       Use placement new to construct the table_def instance in the
12445       memory allocated for it inside table_list.
12446 
12447       The memory allocated by the table_def structure (i.e., not the
12448       memory allocated *for* the table_def structure) is released
12449       inside Relay_log_info::clear_tables_to_lock() by calling the
12450       table_def destructor explicitly.
12451     */
12452     new (&table_list->m_tabledef)
12453         table_def(m_coltype, m_colcnt,
12454                   m_field_metadata, m_field_metadata_size,
12455                   m_null_bits, m_flags);
12456 
12457     table_list->m_tabledef_valid= TRUE;
12458     table_list->m_conv_table= NULL;
12459     table_list->open_type= OT_BASE_ONLY;
12460 
12461     /*
12462       We record in the slave's information that the table should be
12463       locked by linking the table into the list of tables to lock.
12464     */
12465     table_list->next_global= table_list->next_local= rli->tables_to_lock;
12466     const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
12467     const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
12468     /* 'memory' is freed in clear_tables_to_lock */
12469   }
12470   else  // FILTERED_OUT, SAME_ID_MAPPING_*
12471   {
12472     if (tblmap_status == FILTERED_WITH_XA_ACTIVE)
12473     {
12474       if (thd->slave_thread)
12475         rli->report(ERROR_LEVEL, ER_XA_REPLICATION_FILTERS,
12476                     "%s", ER_THD(thd, ER_XA_REPLICATION_FILTERS));
12477       else
12478         /*
12479           For the cases in which a 'BINLOG' statement is set to
12480           execute in a user session
12481          */
12482         my_printf_error(ER_XA_REPLICATION_FILTERS,
12483                         "%s", MYF(0), ER_THD(thd, ER_XA_REPLICATION_FILTERS));
12484     }
12485     /*
12486       If mapped already but with different properties, we raise an
12487       error.
12488       If mapped already but with same properties we skip the event.
12489       If filtered out we skip the event.
12490 
12491       In all three cases, we need to free the memory previously
12492       allocated.
12493      */
12494     else if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
12495     {
12496       /*
12497         Something bad has happened. We need to stop the slave as strange things
12498         could happen if we proceed: slave crash, wrong table being updated, ...
12499         As a consequence we push an error in this case.
12500        */
12501 
12502       char buf[256];
12503 
12504       my_snprintf(buf, sizeof(buf),
12505                   "Found table map event mapping table id %llu which "
12506                   "was already mapped but with different settings.",
12507                   table_list->table_id.id());
12508 
12509       if (thd->slave_thread)
12510         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
12511                     ER(ER_SLAVE_FATAL_ERROR), buf);
12512       else
12513         /*
12514           For the cases in which a 'BINLOG' statement is set to
12515           execute in a user session
12516          */
12517         my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
12518                         MYF(0), buf);
12519     }
12520 
12521     my_free(memory);
12522   }
12523 
12524   DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12525 }
12526 
12527 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)12528 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
12529 {
12530   /*
12531     If the slave skip counter is 1, then we should not start executing
12532     on the next event.
12533   */
12534   return continue_group(rli);
12535 }
12536 
do_update_pos(Relay_log_info * rli)12537 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
12538 {
12539   rli->inc_event_relay_log_pos();
12540   return 0;
12541 }
12542 
12543 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12544 
12545 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)12546 bool Table_map_log_event::write_data_header(IO_CACHE *file)
12547 {
12548   assert(m_table_id.is_valid());
12549   uchar buf[Binary_log_event::TABLE_MAP_HEADER_LEN];
12550   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12551                   {
12552                     int4store(buf + 0, static_cast<uint32>(m_table_id.id()));
12553                     int2store(buf + 4, m_flags);
12554                     return (wrapper_my_b_safe_write(file, buf, 6));
12555                   });
12556   int6store(buf + TM_MAPID_OFFSET, m_table_id.id());
12557   int2store(buf + TM_FLAGS_OFFSET, m_flags);
12558   return (wrapper_my_b_safe_write(file, buf, Binary_log_event::TABLE_MAP_HEADER_LEN));
12559 }
12560 
write_data_body(IO_CACHE * file)12561 bool Table_map_log_event::write_data_body(IO_CACHE *file)
12562 {
12563   assert(!m_dbnam.empty());
12564   assert(!m_tblnam.empty());
12565   /* We use only one byte per length for storage in event: */
12566   assert(m_dblen <= 128);
12567   assert(m_tbllen <= 128);
12568 
12569   uchar const dbuf[]= { (uchar) m_dblen };
12570   uchar const tbuf[]= { (uchar) m_tbllen };
12571 
12572   uchar cbuf[sizeof(m_colcnt) + 1];
12573   uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12574   assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12575 
12576   /*
12577     Store the size of the field metadata.
12578   */
12579   uchar mbuf[sizeof(m_field_metadata_size)];
12580   uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12581 
12582   return (wrapper_my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
12583           wrapper_my_b_safe_write(file,
12584                                   (const uchar*)m_dbnam.c_str(),
12585                                   m_dblen+1) ||
12586           wrapper_my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
12587           wrapper_my_b_safe_write(file,
12588                                  (const uchar*)m_tblnam.c_str(),
12589                                   m_tbllen+1) ||
12590           wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
12591           wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
12592           wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
12593           wrapper_my_b_safe_write(file,
12594                                   m_field_metadata, m_field_metadata_size),
12595           wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
12596  }
12597 #endif
12598 
12599 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12600 
12601 /*
12602   Print some useful information for the SHOW BINARY LOG information
12603   field.
12604  */
12605 
12606 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12607 int Table_map_log_event::pack_info(Protocol *protocol)
12608 {
12609   char buf[256];
12610   size_t bytes= my_snprintf(buf, sizeof(buf),
12611                             "table_id: %llu (%s.%s)",
12612                             m_table_id.id(), m_dbnam.c_str(), m_tblnam.c_str());
12613   protocol->store(buf, bytes, &my_charset_bin);
12614   return 0;
12615 }
12616 #endif
12617 
12618 
12619 #endif
12620 
12621 
12622 #ifdef MYSQL_CLIENT
print(FILE *,PRINT_EVENT_INFO * print_event_info)12623 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
12624 {
12625   if (!print_event_info->short_form)
12626   {
12627     print_header(&print_event_info->head_cache, print_event_info, TRUE);
12628     my_b_printf(&print_event_info->head_cache,
12629                 "\tTable_map: `%s`.`%s` mapped to number %llu\n",
12630                 m_dbnam.c_str(), m_tblnam.c_str(), m_table_id.id());
12631     print_base64(&print_event_info->body_cache, print_event_info, TRUE);
12632   }
12633 }
12634 #endif
12635 
12636 /**************************************************************************
12637 	Write_rows_log_event member functions
12638 **************************************************************************/
12639 
12640 /*
12641   Constructor used to build an event for writing to the binary log.
12642  */
12643 #if !defined(MYSQL_CLIENT)
Write_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid_arg,bool is_transactional,const uchar * extra_row_info)12644 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12645                                            const Table_id& tid_arg,
12646                                            bool is_transactional,
12647                                            const uchar* extra_row_info)
12648 : binary_log::Rows_event(m_type),
12649   Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
12650                    log_bin_use_v1_row_events?
12651                    binary_log::WRITE_ROWS_EVENT_V1:
12652                    binary_log::WRITE_ROWS_EVENT,
12653                    extra_row_info)
12654 {
12655   common_header->type_code= m_type;
12656 }
12657 #endif
12658 
12659 /*
12660   Constructor used by slave to read the event from the binary log.
12661  */
12662 #ifdef HAVE_REPLICATION
Write_rows_log_event(const char * buf,uint event_len,const Format_description_event * description_event)12663 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12664                                            const Format_description_event
12665                                            *description_event)
12666 : binary_log::Rows_event(buf, event_len, description_event),
12667   Rows_log_event(buf, event_len, description_event),
12668   binary_log::Write_rows_event(buf, event_len, description_event)
12669 {
12670   assert(header()->type_code == m_type);
12671 }
12672 #endif
12673 
12674 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12675 int
do_before_row_operations(const Slave_reporting_capability * const)12676 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12677 {
12678   int error= 0;
12679 
12680   m_table->file->rpl_before_write_rows();
12681 
12682   /*
12683     Increment the global status insert count variable
12684   */
12685   if (get_flags(STMT_END_F))
12686     thd->status_var.com_stat[SQLCOM_INSERT]++;
12687 
12688   /*
12689     Let storage engines treat this event as an INSERT command.
12690 
12691     Set 'sql_command' as SQLCOM_INSERT after the tables are locked.
12692     When locking the tables, it should be SQLCOM_END.
12693     THD::decide_logging_format which is called from "lock tables"
12694     assumes that row_events will have 'sql_command' as SQLCOM_END.
12695   */
12696   thd->lex->sql_command= SQLCOM_INSERT;
12697 
12698   /**
12699      todo: to introduce a property for the event (handler?) which forces
12700      applying the event in the replace (idempotent) fashion.
12701   */
12702   if ((rbr_exec_mode == RBR_EXEC_MODE_IDEMPOTENT) ||
12703       (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
12704   {
12705     /*
12706       We are using REPLACE semantics and not INSERT IGNORE semantics
12707       when writing rows, that is: new rows replace old rows.  We need to
12708       inform the storage engine that it should use this behaviour.
12709     */
12710 
12711     /* Tell the storage engine that we are using REPLACE semantics. */
12712     thd->lex->duplicates= DUP_REPLACE;
12713 
12714     /*
12715       Pretend we're executing a REPLACE command: this is needed for
12716       InnoDB and NDB Cluster since they are not (properly) checking the
12717       lex->duplicates flag.
12718     */
12719     thd->lex->sql_command= SQLCOM_REPLACE;
12720     /*
12721        Do not raise the error flag in case of hitting to an unique attribute
12722     */
12723     m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12724     /*
12725        NDB specific: update from ndb master wrapped as Write_rows
12726        so that the event should be applied to replace slave's row
12727     */
12728     m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12729     /*
12730        NDB specific: if update from ndb master wrapped as Write_rows
12731        does not find the row it's assumed idempotent binlog applying
12732        is taking place; don't raise the error.
12733     */
12734     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12735     /*
12736       TODO: the cluster team (Tomas?) says that it's better if the engine knows
12737       how many rows are going to be inserted, then it can allocate needed memory
12738       from the start.
12739     */
12740   }
12741 
12742 
12743   /* Honor next number column if present */
12744   m_table->next_number_field= m_table->found_next_number_field;
12745   /*
12746    * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12747    * sequence numbers for auto_increment fields if the values of them are 0.
12748    * If generateing a sequence number is decided by the values of
12749    * table->auto_increment_field_not_null and SQL_MODE(if includes
12750    * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12751    * SQL_MODE of slave sql thread is always consistency with master's.
12752    * In RBR, auto_increment fields never are NULL, except if the auto_inc
12753    * column exists only on the slave side (i.e., in an extra column
12754    * on the slave's table).
12755    */
12756   if (!is_auto_inc_in_extra_columns())
12757     m_table->auto_increment_field_not_null= TRUE;
12758   else
12759   {
12760     /*
12761       Here we have checked that there is an extra field
12762       on this server's table that has an auto_inc column.
12763 
12764       Mark that the auto_increment field is null and mark
12765       the read and write set bits.
12766 
12767       (There can only be one AUTO_INC column, it is always
12768        indexed and it cannot have a DEFAULT value).
12769     */
12770     m_table->auto_increment_field_not_null= FALSE;
12771     m_table->mark_auto_increment_column();
12772   }
12773 
12774   /**
12775      Sets it to ROW_LOOKUP_NOT_NEEDED.
12776    */
12777   decide_row_lookup_algorithm_and_key();
12778   assert(m_rows_lookup_algorithm==ROW_LOOKUP_NOT_NEEDED);
12779 
12780   return error;
12781 }
12782 
12783 int
do_after_row_operations(const Slave_reporting_capability * const,int error)12784 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12785                                               int error)
12786 {
12787   int local_error= 0;
12788 
12789   /**
12790     Clear the write_set bit for auto_inc field that only
12791     existed on the destination table as an extra column.
12792    */
12793   if (is_auto_inc_in_extra_columns())
12794   {
12795     bitmap_clear_bit(m_table->write_set, m_table->next_number_field->field_index);
12796     bitmap_clear_bit( m_table->read_set, m_table->next_number_field->field_index);
12797 
12798     if (get_flags(STMT_END_F))
12799       m_table->file->ha_release_auto_increment();
12800   }
12801   m_table->next_number_field=0;
12802   m_table->auto_increment_field_not_null= FALSE;
12803   if ((rbr_exec_mode == RBR_EXEC_MODE_IDEMPOTENT) ||
12804       m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
12805   {
12806     m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
12807     m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
12808     /*
12809       resetting the extra with
12810       table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
12811       fires bug#27077
12812       explanation: file->reset() performs this duty
12813       ultimately. Still todo: fix
12814     */
12815   }
12816   if ((local_error= m_table->file->ha_end_bulk_insert()))
12817   {
12818     m_table->file->print_error(local_error, MYF(0));
12819   }
12820 
12821   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
12822   m_table->file->rpl_after_write_rows();
12823 
12824   return error? error : local_error;
12825 }
12826 
12827 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12828 
12829 /*
12830   Check if there are more UNIQUE keys after the given key.
12831 */
12832 static int
last_uniq_key(TABLE * table,uint keyno)12833 last_uniq_key(TABLE *table, uint keyno)
12834 {
12835   while (++keyno < table->s->keys)
12836     if (table->key_info[keyno].flags & HA_NOSAME)
12837       return 0;
12838   return 1;
12839 }
12840 
12841 /**
12842    Check if an error is a duplicate key error.
12843 
12844    This function is used to check if an error code is one of the
12845    duplicate key error, i.e., and error code for which it is sensible
12846    to do a <code>get_dup_key()</code> to retrieve the duplicate key.
12847 
12848    @param errcode The error code to check.
12849 
12850    @return <code>true</code> if the error code is such that
12851    <code>get_dup_key()</code> will return true, <code>false</code>
12852    otherwise.
12853  */
12854 bool
is_duplicate_key_error(int errcode)12855 is_duplicate_key_error(int errcode)
12856 {
12857   switch (errcode)
12858   {
12859   case HA_ERR_FOUND_DUPP_KEY:
12860   case HA_ERR_FOUND_DUPP_UNIQUE:
12861     return true;
12862   }
12863   return false;
12864 }
12865 
12866 /**
12867   Write the current row into event's table.
12868 
12869   The row is located in the row buffer, pointed by @c m_curr_row member.
12870   Number of columns of the row is stored in @c m_width member (it can be
12871   different from the number of columns in the table to which we insert).
12872   Bitmap @c m_cols indicates which columns are present in the row. It is assumed
12873   that event's table is already open and pointed by @c m_table.
12874 
12875   If the same record already exists in the table it can be either overwritten
12876   or an error is reported depending on the value of @c overwrite flag
12877   (error reporting not yet implemented). Note that the matching record can be
12878   different from the row we insert if we use primary keys to identify records in
12879   the table.
12880 
12881   The row to be inserted can contain values only for selected columns. The
12882   missing columns are filled with default values using @c prepare_record()
12883   function. If a matching record is found in the table and @c overwritte is
12884   true, the missing columns are taken from it.
12885 
12886   @param  rli   Relay log info (needed for row unpacking).
12887   @param  overwrite
12888                 Shall we overwrite if the row already exists or signal
12889                 error (currently ignored).
12890 
12891   @returns Error code on failure, 0 on success.
12892 
12893   This method, if successful, sets @c m_curr_row_end pointer to point at the
12894   next row in the rows buffer. This is done when unpacking the row to be
12895   inserted.
12896 
12897   @note If a matching record is found, it is either updated using
12898   @c ha_update_row() or first deleted and then new record written.
12899 */
12900 
12901 int
write_row(const Relay_log_info * const rli,const bool overwrite)12902 Write_rows_log_event::write_row(const Relay_log_info *const rli,
12903                                 const bool overwrite)
12904 {
12905   DBUG_ENTER("write_row");
12906   assert(m_table != NULL && thd != NULL);
12907 
12908   TABLE *table= m_table;  // pointer to event's table
12909   int error;
12910   int keynum= 0;
12911   char* key= NULL;
12912 
12913   prepare_record(table, &m_cols,
12914                  table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
12915 
12916   /* unpack row into table->record[0] */
12917   if ((error= unpack_current_row(rli, &m_cols)))
12918     DBUG_RETURN(error);
12919 
12920   /*
12921     When m_curr_row == m_curr_row_end, it means a row that contains nothing,
12922     so all the pointers shall be pointing to the same address, or else
12923     we have corrupt data and shall throw the error.
12924   */
12925   DBUG_PRINT("debug",("m_rows_buf= %p, m_rows_cur= %p, m_rows_end= %p",
12926                       m_rows_buf, m_rows_cur, m_rows_end));
12927   DBUG_PRINT("debug",("m_curr_row= %p, m_curr_row_end= %p",
12928                       m_curr_row, m_curr_row_end));
12929   if (m_curr_row == m_curr_row_end &&
12930       !((m_rows_buf == m_rows_cur) && (m_rows_cur == m_rows_end)))
12931   {
12932     my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
12933     DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
12934   }
12935 
12936   if (m_curr_row == m_rows_buf)
12937   {
12938     /* this is the first row to be inserted, we estimate the rows with
12939        the size of the first row and use that value to initialize
12940        storage engine for bulk insertion */
12941     assert(!(m_curr_row > m_curr_row_end));
12942     ulong estimated_rows= 0;
12943     if (m_curr_row < m_curr_row_end)
12944       estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
12945     else if (m_curr_row == m_curr_row_end)
12946       estimated_rows= 1;
12947 
12948     m_table->file->ha_start_bulk_insert(estimated_rows);
12949   }
12950 
12951   /*
12952     Explicitly set the auto_inc to null to make sure that
12953     it gets an auto_generated value.
12954   */
12955   if (is_auto_inc_in_extra_columns())
12956     m_table->next_number_field->set_null();
12957 
12958 #ifndef NDEBUG
12959   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
12960   DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
12961   DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
12962 #endif
12963 
12964   /*
12965     Try to write record. If a corresponding record already exists in the table,
12966     we try to change it using ha_update_row() if possible. Otherwise we delete
12967     it and repeat the whole process again.
12968 
12969     TODO: Add safety measures against infinite looping.
12970    */
12971 
12972   m_table->mark_columns_per_binlog_row_image();
12973 
12974   while ((error= table->file->ha_write_row(table->record[0])))
12975   {
12976     if (error == HA_ERR_LOCK_DEADLOCK ||
12977         error == HA_ERR_LOCK_WAIT_TIMEOUT ||
12978         (keynum= table->file->get_dup_key(error)) < 0 ||
12979         !overwrite)
12980     {
12981       DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
12982       /*
12983         Deadlock, waiting for lock or just an error from the handler
12984         such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
12985         Retrieval of the duplicate key number may fail
12986         - either because the error was not "duplicate key" error
12987         - or because the information which key is not available
12988       */
12989       table->file->print_error(error, MYF(0));
12990       goto error;
12991     }
12992     /*
12993       key index value is either valid in the range [0-MAX_KEY) or
12994       has value MAX_KEY as a marker for the case when no information
12995       about key can be found. In the last case we have to require
12996       that storage engine has the flag HA_DUPLICATE_POS turned on.
12997       If this invariant is false then assert will crash
12998       the server built in debug mode. For the server that was built
12999       without DEBUG we have additional check for the value of key index
13000       in the code below in order to report about error in any case.
13001     */
13002     assert(keynum != MAX_KEY ||
13003            (keynum == MAX_KEY &&
13004             (table->file->ha_table_flags() & HA_DUPLICATE_POS)));
13005     /*
13006        We need to retrieve the old row into record[1] to be able to
13007        either update or delete the offending record.  We either:
13008 
13009        - use ha_rnd_pos() with a row-id (available as dupp_row) to the
13010          offending row, if that is possible (MyISAM and Blackhole), or else
13011 
13012        - use ha_index_read_idx_map() with the key that is duplicated, to
13013          retrieve the offending row.
13014      */
13015     if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
13016     {
13017       DBUG_PRINT("info",("Locating offending record using ha_rnd_pos()"));
13018 
13019       if (table->file->inited && (error= table->file->ha_index_end()))
13020       {
13021         table->file->print_error(error, MYF(0));
13022         goto error;
13023       }
13024       if ((error= table->file->ha_rnd_init(FALSE)))
13025       {
13026         table->file->print_error(error, MYF(0));
13027         goto error;
13028       }
13029 
13030       error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
13031 
13032       table->file->ha_rnd_end();
13033       if (error)
13034       {
13035         DBUG_PRINT("info",("ha_rnd_pos() returns error %d",error));
13036         if (error == HA_ERR_RECORD_DELETED)
13037           error= HA_ERR_KEY_NOT_FOUND;
13038         table->file->print_error(error, MYF(0));
13039         goto error;
13040       }
13041     }
13042     else
13043     {
13044       DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
13045 
13046       if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
13047       {
13048         DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
13049         error= my_errno();
13050         goto error;
13051       }
13052 
13053       if (key == NULL)
13054       {
13055         key= static_cast<char*>(my_alloca(table->s->max_unique_length));
13056         if (key == NULL)
13057         {
13058           DBUG_PRINT("info",("Can't allocate key buffer"));
13059           error= ENOMEM;
13060           goto error;
13061         }
13062       }
13063 
13064       if ((uint)keynum < MAX_KEY)
13065       {
13066         key_copy((uchar*)key, table->record[0], table->key_info + keynum,
13067                  0);
13068         error= table->file->ha_index_read_idx_map(table->record[1], keynum,
13069                                                   (const uchar*)key,
13070                                                   HA_WHOLE_KEY,
13071                                                   HA_READ_KEY_EXACT);
13072       }
13073       else
13074         /*
13075           For the server built in non-debug mode returns error if
13076           handler::get_dup_key() returned MAX_KEY as the value of key index.
13077         */
13078         error= HA_ERR_FOUND_DUPP_KEY;
13079 
13080       if (error)
13081       {
13082         DBUG_PRINT("info",("ha_index_read_idx_map() returns %s", HA_ERR(error)));
13083         if (error == HA_ERR_RECORD_DELETED)
13084           error= HA_ERR_KEY_NOT_FOUND;
13085         table->file->print_error(error, MYF(0));
13086         goto error;
13087       }
13088     }
13089 
13090     /*
13091        Now, record[1] should contain the offending row.  That
13092        will enable us to update it or, alternatively, delete it (so
13093        that we can insert the new row afterwards).
13094      */
13095 
13096     /*
13097       If row is incomplete we will use the record found to fill
13098       missing columns.
13099     */
13100     if (!get_flags(COMPLETE_ROWS_F))
13101     {
13102       restore_record(table,record[1]);
13103       error= unpack_current_row(rli, &m_cols);
13104     }
13105 
13106 #ifndef NDEBUG
13107     DBUG_PRINT("debug",("preparing for update: before and after image"));
13108     DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
13109     DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
13110 #endif
13111 
13112     /*
13113        REPLACE is defined as either INSERT or DELETE + INSERT.  If
13114        possible, we can replace it with an UPDATE, but that will not
13115        work on InnoDB if FOREIGN KEY checks are necessary.
13116 
13117        I (Matz) am not sure of the reason for the last_uniq_key()
13118        check as, but I'm guessing that it's something along the
13119        following lines.
13120 
13121        Suppose that we got the duplicate key to be a key that is not
13122        the last unique key for the table and we perform an update:
13123        then there might be another key for which the unique check will
13124        fail, so we're better off just deleting the row and inserting
13125        the correct row.
13126      */
13127     if (last_uniq_key(table, keynum) &&
13128         !table->file->referenced_by_foreign_key())
13129     {
13130       DBUG_PRINT("info",("Updating row using ha_update_row()"));
13131       error=table->file->ha_update_row(table->record[1],
13132                                        table->record[0]);
13133       switch (error) {
13134 
13135       case HA_ERR_RECORD_IS_THE_SAME:
13136         DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
13137                            " ha_update_row()"));
13138         error= 0;
13139 
13140       case 0:
13141         break;
13142 
13143       default:
13144         DBUG_PRINT("info",("ha_update_row() returns error %d",error));
13145         table->file->print_error(error, MYF(0));
13146       }
13147 
13148       goto error;
13149     }
13150     else
13151     {
13152       DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
13153       if ((error= table->file->ha_delete_row(table->record[1])))
13154       {
13155         DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
13156         table->file->print_error(error, MYF(0));
13157         goto error;
13158       }
13159       /* Will retry ha_write_row() with the offending row removed. */
13160     }
13161   }
13162 
13163 error:
13164   m_table->default_column_bitmaps();
13165   DBUG_RETURN(error);
13166 }
13167 
13168 #endif
13169 
13170 int
do_exec_row(const Relay_log_info * const rli)13171 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13172 {
13173   assert(m_table != NULL);
13174   int error= write_row(rli, rbr_exec_mode == RBR_EXEC_MODE_IDEMPOTENT);
13175 
13176   if (error && !thd->is_error())
13177   {
13178     assert(0);
13179     my_error(ER_UNKNOWN_ERROR, MYF(0));
13180   }
13181 
13182   return error;
13183 }
13184 
13185 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13186 
13187 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13188 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
13189 {
13190   DBUG_EXECUTE_IF("simulate_cache_read_error",
13191                   {DBUG_SET("+d,simulate_my_b_fill_error");});
13192   Rows_log_event::print_helper(file, print_event_info, "Write_rows");
13193 }
13194 #endif
13195 
13196 /**************************************************************************
13197 	Delete_rows_log_event member functions
13198 **************************************************************************/
13199 
13200 /*
13201   Constructor used to build an event for writing to the binary log.
13202  */
13203 
13204 #ifndef MYSQL_CLIENT
Delete_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13205 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13206                                              const Table_id& tid,
13207                                              bool is_transactional,
13208                                              const uchar* extra_row_info)
13209 : binary_log::Rows_event(m_type),
13210   Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13211                  log_bin_use_v1_row_events?
13212                  binary_log::DELETE_ROWS_EVENT_V1:
13213                  binary_log::DELETE_ROWS_EVENT,
13214                  extra_row_info),
13215     binary_log::Delete_rows_event()
13216 {
13217   common_header->type_code= m_type;
13218 }
13219 #endif /* #if !defined(MYSQL_CLIENT) */
13220 
13221 /*
13222   Constructor used by slave to read the event from the binary log.
13223  */
13224 #ifdef HAVE_REPLICATION
Delete_rows_log_event(const char * buf,uint event_len,const Format_description_event * description_event)13225 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
13226                                              const Format_description_event
13227                                              *description_event)
13228 : binary_log::Rows_event(buf, event_len, description_event),
13229   Rows_log_event(buf, event_len, description_event),
13230   binary_log::Delete_rows_event(buf, event_len, description_event)
13231 {
13232   assert(header()->type_code == m_type);
13233 }
13234 #endif
13235 
13236 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13237 
13238 int
do_before_row_operations(const Slave_reporting_capability * const)13239 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13240 {
13241   int error= 0;
13242   DBUG_ENTER("Delete_rows_log_event::do_before_row_operations");
13243   m_table->file->rpl_before_delete_rows();
13244   /*
13245     Increment the global status delete count variable
13246    */
13247   if (get_flags(STMT_END_F))
13248     thd->status_var.com_stat[SQLCOM_DELETE]++;
13249 
13250   /*
13251     Let storage engines treat this event as a DELETE command.
13252 
13253     Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13254     When locking the tables, it should be SQLCOM_END.
13255     THD::decide_logging_format which is called from "lock tables"
13256     assumes that row_events will have 'sql_command' as SQLCOM_END.
13257   */
13258   thd->lex->sql_command= SQLCOM_DELETE;
13259 
13260   error= row_operations_scan_and_key_setup();
13261   DBUG_RETURN(error);
13262 
13263 }
13264 
13265 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13266 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13267                                                int error)
13268 {
13269   DBUG_ENTER("Delete_rows_log_event::do_after_row_operations");
13270   error= row_operations_scan_and_key_teardown(error);
13271   m_table->file->rpl_after_delete_rows();
13272   DBUG_RETURN(error);
13273 }
13274 
do_exec_row(const Relay_log_info * const rli)13275 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13276 {
13277   int error;
13278   assert(m_table != NULL);
13279   if (m_rows_lookup_algorithm == ROW_LOOKUP_NOT_NEEDED) {
13280     error= unpack_current_row(rli, &m_cols);
13281     if (error)
13282       return error;
13283   }
13284   /* m_table->record[0] contains the BI */
13285   m_table->mark_columns_per_binlog_row_image();
13286   error= m_table->file->ha_delete_row(m_table->record[0]);
13287   m_table->default_column_bitmaps();
13288   return error;
13289 }
13290 
13291 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13292 
13293 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13294 void Delete_rows_log_event::print(FILE *file,
13295                                   PRINT_EVENT_INFO* print_event_info)
13296 {
13297   Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
13298 }
13299 #endif
13300 
13301 
13302 /**************************************************************************
13303 	Update_rows_log_event member functions
13304 **************************************************************************/
13305 
13306 /*
13307   Constructor used to build an event for writing to the binary log.
13308  */
13309 #if !defined(MYSQL_CLIENT)
Update_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13310 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13311                                              const Table_id& tid,
13312                                              bool is_transactional,
13313                                              const uchar* extra_row_info)
13314 : binary_log::Rows_event(m_type),
13315   Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13316                  log_bin_use_v1_row_events?
13317                  binary_log::UPDATE_ROWS_EVENT_V1:
13318                  binary_log::UPDATE_ROWS_EVENT,
13319                  extra_row_info)
13320 {
13321   common_header->type_code= m_type;
13322   init(tbl_arg->write_set);
13323   if (Rows_log_event::is_valid() && m_cols_ai.bitmap)
13324     is_valid_param= true;
13325 }
13326 
init(MY_BITMAP const * cols)13327 void Update_rows_log_event::init(MY_BITMAP const *cols)
13328 {
13329   /* if bitmap_init fails, caught in is_valid() */
13330   if (likely(!bitmap_init(&m_cols_ai,
13331                           m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
13332                           m_width,
13333                           false)))
13334   {
13335     /* Cols can be zero if this is a dummy binrows event */
13336     if (likely(cols != NULL))
13337     {
13338       memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
13339       create_last_word_mask(&m_cols_ai);
13340     }
13341   }
13342 }
13343 #endif /* !defined(MYSQL_CLIENT) */
13344 
13345 
~Update_rows_log_event()13346 Update_rows_log_event::~Update_rows_log_event()
13347 {
13348   if (m_cols_ai.bitmap) {
13349   if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
13350     m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
13351   bitmap_free(&m_cols_ai); // To pair with bitmap_init().
13352 }
13353 }
13354 
13355 
13356 /*
13357   Constructor used by slave to read the event from the binary log.
13358  */
13359 #ifdef HAVE_REPLICATION
Update_rows_log_event(const char * buf,uint event_len,const Format_description_event * description_event)13360 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
13361                                              const Format_description_event
13362                                              *description_event)
13363 : binary_log::Rows_event(buf, event_len, description_event),
13364   Rows_log_event(buf, event_len, description_event),
13365   binary_log::Update_rows_event(buf, event_len, description_event)
13366 {
13367   if (Rows_log_event::is_valid() && m_cols_ai.bitmap)
13368     is_valid_param= true;
13369   assert(header()->type_code== m_type);
13370 }
13371 #endif
13372 
13373 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13374 
13375 int
do_before_row_operations(const Slave_reporting_capability * const)13376 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13377 {
13378   int error= 0;
13379   DBUG_ENTER("Update_rows_log_event::do_before_row_operations");
13380   m_table->file->rpl_before_update_rows();
13381   /*
13382     Increment the global status update count variable
13383   */
13384   if (get_flags(STMT_END_F))
13385     thd->status_var.com_stat[SQLCOM_UPDATE]++;
13386 
13387   /*
13388     Let storage engines treat this event as an UPDATE command.
13389 
13390     Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13391     When locking the tables, it should be SQLCOM_END.
13392     THD::decide_logging_format which is called from "lock tables"
13393     assumes that row_events will have 'sql_command' as SQLCOM_END.
13394    */
13395   thd->lex->sql_command= SQLCOM_UPDATE;
13396 
13397   error= row_operations_scan_and_key_setup();
13398   DBUG_RETURN(error);
13399 
13400 }
13401 
13402 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13403 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13404                                                int error)
13405 {
13406   DBUG_ENTER("Update_rows_log_event::do_after_row_operations");
13407   error= row_operations_scan_and_key_teardown(error);
13408   m_table->file->rpl_after_update_rows();
13409   DBUG_RETURN(error);
13410 }
13411 
13412 int
do_exec_row(const Relay_log_info * const rli)13413 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13414 {
13415   assert(m_table != NULL);
13416   int error= 0;
13417 
13418   if (m_rows_lookup_algorithm == ROW_LOOKUP_NOT_NEEDED) {
13419     error= unpack_current_row(rli, &m_cols);
13420     if (error)
13421       return error;
13422   }
13423 
13424   /*
13425     This is the situation after locating BI:
13426 
13427     ===|=== before image ====|=== after image ===|===
13428        ^                     ^
13429        m_curr_row            m_curr_row_end
13430 
13431     BI found in the table is stored in record[0]. We copy it to record[1]
13432     and unpack AI to record[0].
13433    */
13434 
13435   store_record(m_table,record[1]);
13436 
13437   m_curr_row= m_curr_row_end;
13438   /* this also updates m_curr_row_end */
13439   if ((error= unpack_current_row(rli, &m_cols_ai)))
13440     return error;
13441 
13442   /*
13443     Now we have the right row to update.  The old row (the one we're
13444     looking for) is in record[1] and the new row is in record[0].
13445   */
13446   DBUG_PRINT("info",("Updating row in table"));
13447   DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
13448   DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
13449 
13450   m_table->mark_columns_per_binlog_row_image();
13451   error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
13452   if (error == HA_ERR_RECORD_IS_THE_SAME)
13453     error= 0;
13454   m_table->default_column_bitmaps();
13455 
13456   return error;
13457 }
13458 
13459 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13460 
13461 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13462 void Update_rows_log_event::print(FILE *file,
13463 				  PRINT_EVENT_INFO* print_event_info)
13464 {
13465   Rows_log_event::print_helper(file, print_event_info, "Update_rows");
13466 }
13467 #endif
13468 
13469 
13470 Incident_log_event::
Incident_log_event(const char * buf,uint event_len,const Format_description_event * description_event)13471 Incident_log_event(const char *buf, uint event_len,
13472                    const Format_description_event *description_event)
13473    : binary_log::Incident_event(buf, event_len, description_event),
13474      Log_event(header(), footer())
13475 {
13476   DBUG_ENTER("Incident_log_event::Incident_log_event");
13477   if (incident > INCIDENT_NONE && incident < INCIDENT_COUNT)
13478     is_valid_param= true;
13479   DBUG_VOID_RETURN;
13480 }
13481 
13482 
~Incident_log_event()13483 Incident_log_event::~Incident_log_event()
13484 {
13485   if (message)
13486     bapi_free(message);
13487 }
13488 
13489 
13490 const char *
description() const13491 Incident_log_event::description() const
13492 {
13493   static const char *const description[]= {
13494     "NOTHING",                                  // Not used
13495     "LOST_EVENTS"
13496   };
13497 
13498   DBUG_PRINT("info", ("incident: %d", incident));
13499 
13500   return description[incident];
13501 }
13502 
13503 
13504 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13505 int Incident_log_event::pack_info(Protocol *protocol)
13506 {
13507   char buf[256];
13508   size_t bytes;
13509   if (message_length > 0)
13510     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
13511                        incident, description());
13512   else
13513     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
13514                        incident, description(), message);
13515   protocol->store(buf, bytes, &my_charset_bin);
13516   return 0;
13517 }
13518 #endif
13519 
13520 
13521 #ifdef MYSQL_CLIENT
13522 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13523 Incident_log_event::print(FILE *file,
13524                           PRINT_EVENT_INFO *print_event_info)
13525 {
13526   if (print_event_info->short_form)
13527     return;
13528 
13529   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13530   my_b_printf(&print_event_info->head_cache,
13531               "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n",
13532               description());
13533 }
13534 #endif
13535 
13536 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
13537 int
do_apply_event(Relay_log_info const * rli)13538 Incident_log_event::do_apply_event(Relay_log_info const *rli)
13539 {
13540   DBUG_ENTER("Incident_log_event::do_apply_event");
13541 
13542   /*
13543     It is not necessary to do GTID related check if the error
13544     'ER_SLAVE_INCIDENT' is ignored.
13545   */
13546   if (ignored_error_code(ER_SLAVE_INCIDENT))
13547   {
13548     DBUG_PRINT("info", ("Ignoring Incident"));
13549     mysql_bin_log.gtid_end_transaction(thd);
13550     DBUG_RETURN(0);
13551   }
13552 
13553   enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
13554   if (state == GTID_STATEMENT_EXECUTE)
13555   {
13556     if (gtid_pre_statement_post_implicit_commit_checks(thd))
13557       state= GTID_STATEMENT_CANCEL;
13558   }
13559 
13560   if (state == GTID_STATEMENT_CANCEL)
13561   {
13562     uint error= thd->get_stmt_da()->mysql_errno();
13563     assert(error != 0);
13564     rli->report(ERROR_LEVEL, error,
13565                 "Error executing incident event: '%s'",
13566                 thd->get_stmt_da()->message_text());
13567     thd->is_slave_error= 1;
13568     DBUG_RETURN(-1);
13569   }
13570   else if (state == GTID_STATEMENT_SKIP)
13571   {
13572     /*
13573       Make slave skip the Incident event through general commands of GTID
13574       i.e. 'set gtid_next=<GTID>; begin; commit;'.
13575     */
13576     DBUG_RETURN(0);
13577   }
13578 
13579   rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
13580               ER(ER_SLAVE_INCIDENT),
13581               description(),
13582               message_length > 0 ? message : "<none>");
13583   DBUG_RETURN(1);
13584 }
13585 #endif
13586 
13587 bool
write_data_header(IO_CACHE * file)13588 Incident_log_event::write_data_header(IO_CACHE *file)
13589 {
13590   DBUG_ENTER("Incident_log_event::write_data_header");
13591   DBUG_PRINT("enter", ("incident: %d", incident));
13592   uchar buf[sizeof(int16)];
13593   int2store(buf, (int16) incident);
13594 #ifndef MYSQL_CLIENT
13595   DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
13596 #else
13597    DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
13598 #endif
13599 }
13600 
13601 bool
write_data_body(IO_CACHE * file)13602 Incident_log_event::write_data_body(IO_CACHE *file)
13603 {
13604   uchar tmp[1];
13605   DBUG_ENTER("Incident_log_event::write_data_body");
13606   tmp[0]= (uchar) message_length;
13607   crc= checksum_crc32(crc, (uchar*) tmp, 1);
13608   if (message_length > 0)
13609   {
13610     crc= checksum_crc32(crc, (uchar*) message, message_length);
13611     // todo: report a bug on write_str accepts uint but treats it as uchar
13612   }
13613   DBUG_RETURN(write_str_at_most_255_bytes(file, message, (uint) message_length, &event_encrypter));
13614 }
13615 
13616 
Ignorable_log_event(const char * buf,const Format_description_event * descr_event)13617 Ignorable_log_event::Ignorable_log_event(const char *buf,
13618                                          const Format_description_event *descr_event)
13619   : binary_log::Ignorable_event(buf, descr_event),
13620     Log_event(header(), footer())
13621 {
13622   DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
13623 
13624   is_valid_param= true;
13625   DBUG_VOID_RETURN;
13626 }
13627 
~Ignorable_log_event()13628 Ignorable_log_event::~Ignorable_log_event()
13629 {
13630 }
13631 
13632 #ifndef MYSQL_CLIENT
13633 /* Pack info for its unrecognized ignorable event */
pack_info(Protocol * protocol)13634 int Ignorable_log_event::pack_info(Protocol *protocol)
13635 {
13636   char buf[256];
13637   size_t bytes;
13638   bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized ignorable event");
13639   protocol->store(buf, bytes, &my_charset_bin);
13640   return 0;
13641 }
13642 #endif
13643 
13644 #ifdef MYSQL_CLIENT
13645 /* Print for its unrecognized ignorable event */
13646 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13647 Ignorable_log_event::print(FILE *file,
13648                            PRINT_EVENT_INFO *print_event_info)
13649 {
13650   if (print_event_info->short_form)
13651     return;
13652 
13653   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13654   my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
13655   my_b_printf(&print_event_info->head_cache,
13656               "# Unrecognized ignorable event\n");
13657 }
13658 #endif
13659 
13660 
Rows_query_log_event(const char * buf,uint event_len,const Format_description_event * descr_event)13661 Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
13662                                            const Format_description_event
13663                                            *descr_event)
13664   : binary_log::Ignorable_event(buf, descr_event),
13665     Ignorable_log_event(buf, descr_event),
13666     binary_log::Rows_query_event(buf, event_len, descr_event)
13667 {
13668   is_valid_param= (m_rows_query != NULL);
13669 }
13670 
13671 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13672 int Rows_query_log_event::pack_info(Protocol *protocol)
13673 {
13674   char *buf;
13675   size_t bytes;
13676   size_t len= sizeof("# ") + strlen(m_rows_query);
13677   if (!(buf= (char*) my_malloc(key_memory_log_event,
13678                                len, MYF(MY_WME))))
13679     return 1;
13680   bytes= my_snprintf(buf, len, "# %s", m_rows_query);
13681   protocol->store(buf, bytes, &my_charset_bin);
13682   my_free(buf);
13683   return 0;
13684 }
13685 #endif
13686 
13687 #ifdef MYSQL_CLIENT
13688 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13689 Rows_query_log_event::print(FILE *file,
13690                             PRINT_EVENT_INFO *print_event_info)
13691 {
13692   if (!print_event_info->short_form && print_event_info->verbose > 1)
13693   {
13694     IO_CACHE *const head= &print_event_info->head_cache;
13695     IO_CACHE *const body= &print_event_info->body_cache;
13696     char *token= NULL, *saveptr= NULL;
13697     char *rows_query_copy= NULL;
13698     if (!(rows_query_copy= my_strdup(key_memory_log_event,
13699                                      m_rows_query, MYF(MY_WME))))
13700       return;
13701 
13702     print_header(head, print_event_info, FALSE);
13703     my_b_printf(head, "\tRows_query\n");
13704     /*
13705       Prefix every line of a multi-line query with '#' to prevent the
13706       statement from being executed when binary log will be processed
13707       using 'mysqlbinlog --verbose --verbose'.
13708     */
13709     for (token= my_strtok_r(rows_query_copy, "\n", &saveptr); token;
13710          token= my_strtok_r(NULL, "\n", &saveptr))
13711       my_b_printf(head, "# %s\n", token);
13712     my_free(rows_query_copy);
13713     print_base64(body, print_event_info, true);
13714   }
13715 }
13716 #endif
13717 
13718 bool
write_data_body(IO_CACHE * file)13719 Rows_query_log_event::write_data_body(IO_CACHE *file)
13720 {
13721   DBUG_ENTER("Rows_query_log_event::write_data_body");
13722   /*
13723    m_rows_query length will be stored using only one byte, but on read
13724    that length will be ignored and the complete query will be read.
13725   */
13726   DBUG_RETURN(write_str_at_most_255_bytes(file, m_rows_query,
13727               strlen(m_rows_query), &event_encrypter));
13728 }
13729 
13730 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13731 int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
13732 {
13733   DBUG_ENTER("Rows_query_log_event::do_apply_event");
13734   assert(rli->info_thd == thd);
13735   /* Set query for writing Rows_query log event into binlog later.*/
13736   thd->set_query(m_rows_query, strlen(m_rows_query));
13737   thd->set_query_for_display(m_rows_query, strlen(m_rows_query));
13738 
13739   assert(rli->rows_query_ev == NULL);
13740 
13741   const_cast<Relay_log_info*>(rli)->rows_query_ev= this;
13742   /* Tell worker not to free the event */
13743   worker= NULL;
13744   DBUG_EXECUTE_IF("error_on_rows_query_event_apply", { DBUG_RETURN(1); };);
13745   DBUG_RETURN(0);
13746 }
13747 #endif
13748 
13749 
13750 const char *Gtid_log_event::SET_STRING_PREFIX= "SET @@SESSION.GTID_NEXT= '";
13751 
13752 
Gtid_log_event(const char * buffer,uint event_len,const Format_description_event * description_event)13753 Gtid_log_event::Gtid_log_event(const char *buffer, uint event_len,
13754                                const Format_description_event *description_event)
13755    : binary_log::Gtid_event(buffer, event_len, description_event),
13756      Log_event(header(), footer())
13757 {
13758   DBUG_ENTER("Gtid_log_event::Gtid_log_event(const char *,"
13759              " uint, const Format_description_log_event *");
13760 
13761 #ifndef NDEBUG
13762   uint8_t const common_header_len= description_event->common_header_len;
13763   uint8 const post_header_len=
13764     buffer[EVENT_TYPE_OFFSET] == binary_log::ANONYMOUS_GTID_LOG_EVENT ?
13765     description_event->post_header_len[binary_log::ANONYMOUS_GTID_LOG_EVENT - 1] :
13766     description_event->post_header_len[binary_log::GTID_LOG_EVENT - 1];
13767   DBUG_PRINT("info",
13768              ("event_len: %u; common_header_len: %d; post_header_len: %d",
13769               event_len, common_header_len, post_header_len));
13770 #endif
13771 
13772   is_valid_param= true;
13773   spec.type= get_type_code() == binary_log::ANONYMOUS_GTID_LOG_EVENT ?
13774              ANONYMOUS_GROUP : GTID_GROUP;
13775   sid.copy_from((uchar *)Uuid_parent_struct.bytes);
13776   spec.gtid.sidno= gtid_info_struct.rpl_gtid_sidno;
13777   //GNO sanity check
13778   if (spec.type == GTID_GROUP) {
13779     if (gtid_info_struct.rpl_gtid_gno <= 0 || gtid_info_struct.rpl_gtid_gno >= GNO_END)
13780       goto err;
13781   } else { //ANONYMOUS_GTID_LOG_EVENT
13782     if (gtid_info_struct.rpl_gtid_gno != 0)
13783       goto err;
13784   }
13785   spec.gtid.gno= gtid_info_struct.rpl_gtid_gno;
13786 
13787   DBUG_VOID_RETURN;
13788 
13789 err:
13790   is_valid_param= false;
13791   DBUG_VOID_RETURN;
13792 }
13793 
13794 #ifndef MYSQL_CLIENT
Gtid_log_event(THD * thd_arg,bool using_trans,int64 last_committed_arg,int64 sequence_number_arg,bool may_have_sbr_stmts_arg)13795 Gtid_log_event::Gtid_log_event(THD* thd_arg, bool using_trans,
13796                                int64 last_committed_arg,
13797                                int64 sequence_number_arg,
13798                                bool may_have_sbr_stmts_arg)
13799 : binary_log::Gtid_event(last_committed_arg, sequence_number_arg,
13800                          may_have_sbr_stmts_arg),
13801   Log_event(thd_arg, thd_arg->variables.gtid_next.type == ANONYMOUS_GROUP ?
13802             LOG_EVENT_IGNORABLE_F : 0,
13803             using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13804             Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING,
13805             header(), footer())
13806 {
13807   DBUG_ENTER("Gtid_log_event::Gtid_log_event(THD *)");
13808   if (thd->owned_gtid.sidno > 0)
13809   {
13810     spec.set(thd->owned_gtid);
13811     sid= thd->owned_sid;
13812   }
13813   else
13814   {
13815     assert(thd->owned_gtid.sidno == THD::OWNED_SIDNO_ANONYMOUS);
13816     spec.set_anonymous();
13817     spec.gtid.clear();
13818     sid.clear();
13819   }
13820 
13821   Log_event_type event_type= (spec.type == ANONYMOUS_GROUP ?
13822                               binary_log::ANONYMOUS_GTID_LOG_EVENT :
13823                               binary_log::GTID_LOG_EVENT);
13824   common_header->type_code= event_type;
13825 
13826 #ifndef NDEBUG
13827   char buf[MAX_SET_STRING_LENGTH + 1];
13828   to_string(buf);
13829   DBUG_PRINT("info", ("%s", buf));
13830 #endif
13831   is_valid_param= true;
13832   DBUG_VOID_RETURN;
13833 }
13834 
Gtid_log_event(uint32 server_id_arg,bool using_trans,int64 last_committed_arg,int64 sequence_number_arg,bool may_have_sbr_stmts_arg,const Gtid_specification spec_arg)13835 Gtid_log_event::Gtid_log_event(uint32 server_id_arg, bool using_trans,
13836                                int64 last_committed_arg,
13837                                int64 sequence_number_arg,
13838                                bool may_have_sbr_stmts_arg,
13839                                const Gtid_specification spec_arg)
13840  : binary_log::Gtid_event(last_committed_arg, sequence_number_arg,
13841                           may_have_sbr_stmts_arg),
13842    Log_event(header(), footer(),
13843              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13844              Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING)
13845 {
13846   DBUG_ENTER("Gtid_log_event::Gtid_log_event(uint32, bool, int64, int64, const Gtid_specification)");
13847   server_id= server_id_arg;
13848   common_header->unmasked_server_id= server_id_arg;
13849   is_valid_param= true;
13850 
13851   if (spec_arg.type == GTID_GROUP)
13852   {
13853     assert(spec_arg.gtid.sidno > 0);
13854     assert(spec_arg.gtid.gno > 0);
13855     assert(spec_arg.gtid.gno < GNO_END);
13856     if (spec_arg.gtid.gno <= 0 || spec_arg.gtid.gno >= GNO_END)
13857       is_valid_param= false;
13858     spec.set(spec_arg.gtid);
13859     global_sid_lock->rdlock();
13860     sid= global_sid_map->sidno_to_sid(spec_arg.gtid.sidno);
13861     global_sid_lock->unlock();
13862   }
13863   else
13864   {
13865     assert(spec_arg.type == ANONYMOUS_GROUP);
13866     spec.set_anonymous();
13867     spec.gtid.clear();
13868     sid.clear();
13869     common_header->flags|= LOG_EVENT_IGNORABLE_F;
13870   }
13871 
13872   Log_event_type event_type= (spec.type == ANONYMOUS_GROUP ?
13873                               binary_log::ANONYMOUS_GTID_LOG_EVENT :
13874                               binary_log::GTID_LOG_EVENT);
13875   common_header->type_code= event_type;
13876 
13877 #ifndef NDEBUG
13878   char buf[MAX_SET_STRING_LENGTH + 1];
13879   to_string(buf);
13880   DBUG_PRINT("info", ("%s", buf));
13881 #endif
13882   DBUG_VOID_RETURN;
13883 }
13884 #endif
13885 
13886 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13887 int Gtid_log_event::pack_info(Protocol *protocol)
13888 {
13889   char buffer[MAX_SET_STRING_LENGTH + 1];
13890   size_t len= to_string(buffer);
13891   protocol->store(buffer, len, &my_charset_bin);
13892   return 0;
13893 }
13894 #endif
13895 
to_string(char * buf) const13896 size_t Gtid_log_event::to_string(char *buf) const
13897 {
13898   char *p= buf;
13899   assert(strlen(SET_STRING_PREFIX) == SET_STRING_PREFIX_LENGTH);
13900   strcpy(p, SET_STRING_PREFIX);
13901   p+= SET_STRING_PREFIX_LENGTH;
13902   p+= spec.to_string(&sid, p);
13903   *p++= '\'';
13904   *p= '\0';
13905   return p - buf;
13906 }
13907 
13908 #ifdef MYSQL_CLIENT
13909 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13910 Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
13911 {
13912   char buffer[MAX_SET_STRING_LENGTH + 1];
13913   IO_CACHE *const head= &print_event_info->head_cache;
13914   if (!print_event_info->short_form)
13915   {
13916     print_header(head, print_event_info, FALSE);
13917     my_b_printf(head, "\t%s\tlast_committed=%llu\tsequence_number=%llu\t"
13918                 "rbr_only=%s\n",
13919                 get_type_code() == binary_log::GTID_LOG_EVENT ?
13920                 "GTID" : "Anonymous_GTID",
13921                 last_committed, sequence_number,
13922                 may_have_sbr_stmts ? "no" : "yes");
13923   }
13924 
13925   /*
13926     The applier thread can always use "READ COMMITTED" isolation for
13927     transactions containing only RBR events (Table_map + Rows).
13928 
13929     This would prevent some deadlock issues because InnoDB doesn't
13930     acquire GAP locks in "READ COMMITTED" isolation level since
13931     MySQL 5.7.18.
13932   */
13933   if (!may_have_sbr_stmts)
13934   {
13935     my_b_printf(head,
13936                 "/*!50718 SET TRANSACTION ISOLATION LEVEL "
13937                 "READ COMMITTED*/%s\n",
13938                 print_event_info->delimiter);
13939   }
13940 
13941   to_string(buffer);
13942   my_b_printf(head, "%s%s\n", buffer, print_event_info->delimiter);
13943 }
13944 #endif
13945 
13946 #ifdef MYSQL_SERVER
write_data_header_to_memory(uchar * buffer)13947 uint32 Gtid_log_event::write_data_header_to_memory(uchar *buffer)
13948 {
13949   DBUG_ENTER("Gtid_log_event::write_data_header_to_memory");
13950   uchar *ptr_buffer= buffer;
13951 
13952   /* Encode the GTID flags */
13953   uchar gtid_flags= 0;
13954   gtid_flags|= may_have_sbr_stmts ?
13955                binary_log::Gtid_event::FLAG_MAY_HAVE_SBR : 0;
13956   *ptr_buffer= gtid_flags;
13957   ptr_buffer+= ENCODED_FLAG_LENGTH;
13958 
13959 #ifndef NDEBUG
13960   char buf[binary_log::Uuid::TEXT_LENGTH + 1];
13961   sid.to_string(buf);
13962   DBUG_PRINT("info", ("sid=%s sidno=%d gno=%lld",
13963                       buf, spec.gtid.sidno, spec.gtid.gno));
13964 #endif
13965 
13966   sid.copy_to(ptr_buffer);
13967   ptr_buffer+= ENCODED_SID_LENGTH;
13968 
13969 #ifndef NDEBUG
13970   if (DBUG_EVALUATE_IF("send_invalid_gno_to_replica", true, false))
13971     int8store(ptr_buffer, GNO_END);
13972   else
13973 #endif
13974   int8store(ptr_buffer, spec.gtid.gno);
13975   ptr_buffer+= ENCODED_GNO_LENGTH;
13976 
13977   *ptr_buffer= LOGICAL_TIMESTAMP_TYPECODE;
13978   ptr_buffer+= LOGICAL_TIMESTAMP_TYPECODE_LENGTH;
13979 
13980   assert((sequence_number == 0 && last_committed == 0) ||
13981          (sequence_number > last_committed));
13982   DBUG_EXECUTE_IF("set_commit_parent_100",
13983                   { last_committed= max<int64>(sequence_number > 1 ? 1 : 0,
13984                                                sequence_number - 100); });
13985   DBUG_EXECUTE_IF("set_commit_parent_150",
13986                   { last_committed= max<int64>(sequence_number > 1 ? 1 : 0,
13987                                                sequence_number - 150); });
13988   DBUG_EXECUTE_IF("feign_commit_parent", { last_committed= sequence_number; });
13989   int8store(ptr_buffer, last_committed);
13990   int8store(ptr_buffer + 8, sequence_number);
13991   ptr_buffer+= LOGICAL_TIMESTAMP_LENGTH;
13992 
13993   assert(ptr_buffer == (buffer + POST_HEADER_LENGTH));
13994 
13995   DBUG_RETURN(POST_HEADER_LENGTH);
13996 }
13997 
write_data_header(IO_CACHE * file)13998 bool Gtid_log_event::write_data_header(IO_CACHE *file)
13999 {
14000   DBUG_ENTER("Gtid_log_event::write_data_header");
14001   uchar buffer[POST_HEADER_LENGTH];
14002   write_data_header_to_memory(buffer);
14003   DBUG_RETURN(wrapper_my_b_safe_write(file, (uchar *) buffer,
14004                                       POST_HEADER_LENGTH));
14005 }
14006 
14007 #endif // MYSQL_SERVER
14008 
14009 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)14010 int Gtid_log_event::do_apply_event(Relay_log_info const *rli)
14011 {
14012   DBUG_ENTER("Gtid_log_event::do_apply_event");
14013   assert(rli->info_thd == thd);
14014 
14015   /*
14016     In rare cases it is possible that we already own a GTID (either
14017     ANONYMOUS or GTID_GROUP). This can happen if a transaction was truncated
14018     in the middle in the relay log and then next relay log begins with a
14019     Gtid_log_events without closing the transaction context from the previous
14020     relay log. In this case the only sensible thing to do is to discard the
14021     truncated transaction and move on.
14022 
14023     Note that when the applier is "GTID skipping" a transactions it
14024     owns nothing, but its gtid_next->type == GTID_GROUP.
14025   */
14026   const Gtid_specification *gtid_next= &thd->variables.gtid_next;
14027   if (!thd->owned_gtid.is_empty() ||
14028       (thd->owned_gtid.is_empty() && gtid_next->type == GTID_GROUP))
14029   {
14030     /*
14031       Slave will execute this code if a previous Gtid_log_event was applied
14032       but the GTID wasn't consumed yet (the transaction was not committed,
14033       nor rolled back, nor skipped).
14034       On a client session we cannot do consecutive SET GTID_NEXT without
14035       a COMMIT or a ROLLBACK in the middle.
14036       Applying this event without rolling back the current transaction may
14037       lead to problems, as a "BEGIN" event following this GTID will
14038       implicitly commit the "partial transaction" and will consume the
14039       GTID. If this "partial transaction" was left in the relay log by the
14040       IO thread restarting in the middle of a transaction, you could have
14041       the partial transaction being logged with the GTID on the slave,
14042       causing data corruption on replication.
14043     */
14044     if (thd->server_status & SERVER_STATUS_IN_TRANS)
14045     {
14046       /* This is not an error (XA is safe), just an information */
14047       rli->report(INFORMATION_LEVEL, 0,
14048                   "Rolling back unfinished transaction (no COMMIT "
14049                   "or ROLLBACK in relay log). A probable cause is partial "
14050                   "transaction left on relay log because of restarting IO "
14051                   "thread with auto-positioning protocol.");
14052       const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
14053     }
14054     gtid_state->update_on_rollback(thd);
14055   }
14056 
14057   global_sid_lock->rdlock();
14058 
14059   // make sure that sid has been converted to sidno
14060   if (spec.type == GTID_GROUP)
14061   {
14062     if (get_sidno(false) < 0)
14063     {
14064       global_sid_lock->unlock();
14065       DBUG_RETURN(1); // out of memory
14066     }
14067   }
14068 
14069   // set_gtid_next releases global_sid_lock
14070   if (set_gtid_next(thd, spec))
14071     // This can happen e.g. if gtid_mode is incompatible with spec.
14072     DBUG_RETURN(1);
14073 
14074   thd->set_currently_executing_gtid_for_slave_thread();
14075 
14076   /*
14077     If the current transaction contains no changes logged with SBR
14078     we can assume this transaction as a pure row based replicated one.
14079 
14080     Based on this assumption, we can set current transaction tx_isolation to
14081     READ COMMITTED in order to avoid concurrent transactions to be blocked by
14082     InnoDB gap locks.
14083 
14084     The session tx_isolation will be restored:
14085     - When the transaction finishes with QUERY(COMMIT|ROLLBACK),
14086       as the MySQL server does for ordinary user sessions;
14087     - When applying a Xid_log_event, after committing the transaction;
14088     - When applying a XA_prepare_log_event, after preparing the transaction;
14089     - When the applier needs to abort a transaction execution.
14090 
14091     Notice that when a transaction is being "gtid skipped", its statements are
14092     not actually executed (see mysql_execute_command()). So, the call to the
14093     function that would restore the tx_isolation after finishing the transaction
14094     may not happen.
14095   */
14096   if (DBUG_EVALUATE_IF("force_trx_as_rbr_only", true,
14097                        !may_have_sbr_stmts &&
14098                        thd->tx_isolation > ISO_READ_COMMITTED &&
14099                        gtid_pre_statement_checks(thd) != GTID_STATEMENT_SKIP))
14100   {
14101     assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
14102     assert(thd->get_transaction()->is_empty(Transaction_ctx::SESSION));
14103     assert(!thd->lock);
14104     DBUG_PRINT("info", ("setting tx_isolation to READ COMMITTED"));
14105     set_tx_isolation(thd, ISO_READ_COMMITTED, true/*one_shot*/);
14106   }
14107 
14108   DBUG_RETURN(0);
14109 }
14110 
do_update_pos(Relay_log_info * rli)14111 int Gtid_log_event::do_update_pos(Relay_log_info *rli)
14112 {
14113   /*
14114     This event does not increment group positions. This means
14115     that if there is a failure after it has been processed,
14116     it will be automatically re-executed.
14117   */
14118   rli->inc_event_relay_log_pos();
14119   DBUG_EXECUTE_IF("crash_after_update_pos_gtid",
14120                   sql_print_information("Crashing crash_after_update_pos_gtid.");
14121                   DBUG_SUICIDE(););
14122   return 0;
14123 }
14124 
do_shall_skip(Relay_log_info * rli)14125 Log_event::enum_skip_reason Gtid_log_event::do_shall_skip(Relay_log_info *rli)
14126 {
14127   return Log_event::continue_group(rli);
14128 }
14129 #endif
14130 
14131 Previous_gtids_log_event::
Previous_gtids_log_event(const char * buf,uint event_len,const Format_description_event * description_event)14132 Previous_gtids_log_event(const char *buf, uint event_len,
14133                          const Format_description_event *description_event)
14134 : binary_log::Previous_gtids_event(buf, event_len, description_event),
14135   Log_event(header(), footer())
14136 {
14137   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event");
14138   if (buf != NULL)
14139     is_valid_param= true;
14140   DBUG_VOID_RETURN;
14141 }
14142 
14143 #ifndef MYSQL_CLIENT
Previous_gtids_log_event(const Gtid_set * set)14144 Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set)
14145 : binary_log::Previous_gtids_event(),
14146   Log_event(header(), footer(),
14147             Log_event::EVENT_NO_CACHE,
14148             Log_event::EVENT_IMMEDIATE_LOGGING)
14149 {
14150   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event(THD *, const Gtid_set *)");
14151   common_header->type_code= binary_log::PREVIOUS_GTIDS_LOG_EVENT;
14152   common_header->flags|= LOG_EVENT_IGNORABLE_F;
14153   global_sid_lock->assert_some_lock();
14154   buf_size= set->get_encoded_length();
14155   uchar *buffer= (uchar *) my_malloc(key_memory_log_event,
14156                                      buf_size, MYF(MY_WME));
14157   if (buffer != NULL)
14158   {
14159     set->encode(buffer);
14160     register_temp_buf((char *)buffer);
14161   }
14162   buf= buffer;
14163   // if buf is empty, is_valid will be false
14164   if(buf != 0)
14165     is_valid_param= true;
14166   DBUG_VOID_RETURN;
14167 }
14168 #endif
14169 
14170 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14171 int Previous_gtids_log_event::pack_info(Protocol *protocol)
14172 {
14173   size_t length= 0;
14174   char *str= get_str(&length, &Gtid_set::default_string_format);
14175   if (str == NULL)
14176     return 1;
14177   protocol->store(str, length, &my_charset_bin);
14178   my_free(str);
14179   return 0;
14180 }
14181 #endif
14182 
14183 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14184 void Previous_gtids_log_event::print(FILE *file,
14185                                      PRINT_EVENT_INFO *print_event_info)
14186 {
14187   IO_CACHE *const head= &print_event_info->head_cache;
14188   char *str= get_str(NULL, &Gtid_set::commented_string_format);
14189   if (str != NULL)
14190   {
14191     if (!print_event_info->short_form)
14192     {
14193       print_header(head, print_event_info, FALSE);
14194       my_b_printf(head, "\tPrevious-GTIDs\n");
14195     }
14196     my_b_printf(head, "%s\n", str);
14197     my_free(str);
14198   }
14199 }
14200 #endif
14201 
add_to_set(Gtid_set * target) const14202 int Previous_gtids_log_event::add_to_set(Gtid_set *target) const
14203 {
14204   DBUG_ENTER("Previous_gtids_log_event::add_to_set(Gtid_set *)");
14205   size_t end_pos= 0;
14206   size_t add_size= DBUG_EVALUATE_IF("gtid_has_extra_data", 10, 0);
14207   /* Silently ignore additional unknown data at the end of the encoding */
14208   PROPAGATE_REPORTED_ERROR_INT(target->add_gtid_encoding(buf,
14209                                                          buf_size + add_size,
14210                                                          &end_pos));
14211   assert(end_pos <= buf_size);
14212   DBUG_RETURN(0);
14213 }
14214 
get_str(size_t * length_p,const Gtid_set::String_format * string_format) const14215 char *Previous_gtids_log_event::get_str(
14216   size_t *length_p, const Gtid_set::String_format *string_format) const
14217 {
14218   DBUG_ENTER("Previous_gtids_log_event::get_str(size_t *, const Gtid_set::String_format *)");
14219   Sid_map sid_map(NULL);
14220   Gtid_set set(&sid_map, NULL);
14221   DBUG_PRINT("info", ("temp_buf=%p buf=%p", temp_buf, buf));
14222   if (set.add_gtid_encoding(buf, buf_size) != RETURN_STATUS_OK)
14223     DBUG_RETURN(NULL);
14224   set.dbug_print("set");
14225   size_t length= set.get_string_length(string_format);
14226   DBUG_PRINT("info", ("string length= %lu", (ulong) length));
14227   char* str= (char *)my_malloc(key_memory_log_event,
14228                                length + 1, MYF(MY_WME));
14229   if (str != NULL)
14230   {
14231     set.to_string(str, false/*need_lock*/, string_format);
14232     if (length_p != NULL)
14233       *length_p= length;
14234   }
14235   DBUG_RETURN(str);
14236 }
14237 
14238 #ifndef MYSQL_CLIENT
write_data_body(IO_CACHE * file)14239 bool Previous_gtids_log_event::write_data_body(IO_CACHE *file)
14240 {
14241   DBUG_ENTER("Previous_gtids_log_event::write_data_body");
14242   DBUG_PRINT("info", ("size=%d", static_cast<int>(buf_size)));
14243   bool ret= wrapper_my_b_safe_write(file, buf, buf_size);
14244   DBUG_RETURN(ret);
14245 }
14246 #endif
14247 
14248 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_update_pos(Relay_log_info * rli)14249 int Previous_gtids_log_event::do_update_pos(Relay_log_info *rli)
14250 {
14251   rli->inc_event_relay_log_pos();
14252   return 0;
14253 }
14254 #endif
14255 
14256 
14257 /**************************************************************************
14258 	Transaction_context_log_event methods
14259 **************************************************************************/
14260 #ifndef MYSQL_CLIENT
14261 Transaction_context_log_event::
Transaction_context_log_event(const char * server_uuid_arg,bool using_trans,my_thread_id thread_id_arg,bool is_gtid_specified_arg)14262 Transaction_context_log_event(const char *server_uuid_arg,
14263                               bool using_trans,
14264                               my_thread_id thread_id_arg,
14265                               bool is_gtid_specified_arg)
14266   : binary_log::Transaction_context_event(thread_id_arg,
14267                                           is_gtid_specified_arg),
14268     Log_event(header(), footer(),
14269               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
14270               Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING)
14271 {
14272   DBUG_ENTER("Transaction_context_log_event::Transaction_context_log_event(THD *, const char *, ulonglong)");
14273   common_header->flags|= LOG_EVENT_IGNORABLE_F;
14274   server_uuid= NULL;
14275   sid_map= new Sid_map(NULL);
14276   snapshot_version= new Gtid_set(sid_map);
14277 
14278   /*
14279     Copy global_sid_map to a local copy to avoid the acquisition
14280     of the global_sid_lock for operations on top of this snapshot
14281     version.
14282     The Sid_map and Gtid_executed must be read under the protection
14283     of MYSQL_BIN_LOG.LOCK_commit to avoid race conditions between
14284     ordered commits in the storage engine and gtid_state update.
14285   */
14286   if (mysql_bin_log.get_gtid_executed(sid_map, snapshot_version))
14287     goto err;
14288 
14289   server_uuid= my_strdup(key_memory_log_event, server_uuid_arg, MYF(MY_WME));
14290   if (server_uuid == NULL)
14291     goto err;
14292 
14293   // These two fields are only populated on event decoding.
14294   // Encoding is done directly from snapshot_version field.
14295   encoded_snapshot_version= NULL;
14296   encoded_snapshot_version_length= 0;
14297 
14298   // Debug sync point for SQL threads.
14299   DBUG_EXECUTE_IF("debug.wait_after_set_snapshot_version_on_transaction_context_log_event",
14300                   {
14301                     const char act[]=
14302                         "now wait_for "
14303                         "signal.resume_after_set_snapshot_version_on_transaction_context_log_event";
14304                     assert(opt_debug_sync_timeout > 0);
14305                     assert(!debug_sync_set_action(current_thd,
14306                                                   STRING_WITH_LEN(act)));
14307                   };);
14308 
14309   is_valid_param= true;
14310   DBUG_VOID_RETURN;
14311 
14312 err:
14313   is_valid_param= false;
14314   DBUG_VOID_RETURN;
14315 }
14316 #endif
14317 
14318 Transaction_context_log_event::
Transaction_context_log_event(const char * buffer,uint event_len,const Format_description_event * descr_event)14319 Transaction_context_log_event(const char *buffer, uint event_len,
14320                               const Format_description_event *descr_event)
14321   : binary_log::Transaction_context_event(buffer, event_len, descr_event),
14322     Log_event(header(), footer())
14323 {
14324   DBUG_ENTER("Transaction_context_log_event::Transaction_context_log_event (const char *, uint, const Format_description_event*)");
14325   common_header->flags|= LOG_EVENT_IGNORABLE_F;
14326 
14327   sid_map= new Sid_map(NULL);
14328   snapshot_version= new Gtid_set(sid_map);
14329 
14330   if (server_uuid == NULL || encoded_snapshot_version == NULL)
14331     goto err;
14332 
14333   is_valid_param= true;
14334   DBUG_VOID_RETURN;
14335 
14336 err:
14337   is_valid_param= false;
14338   DBUG_VOID_RETURN;
14339 }
14340 
~Transaction_context_log_event()14341 Transaction_context_log_event::~Transaction_context_log_event()
14342 {
14343   DBUG_ENTER("Transaction_context_log_event::~Transaction_context_log_event");
14344   if (server_uuid)
14345     my_free((void*)server_uuid);
14346   server_uuid= NULL;
14347   if (encoded_snapshot_version)
14348     my_free((void*) encoded_snapshot_version);
14349   encoded_snapshot_version= NULL;
14350   delete snapshot_version;
14351   delete sid_map;
14352   DBUG_VOID_RETURN;
14353 }
14354 
to_string(char * buf,ulong len) const14355 size_t Transaction_context_log_event::to_string(char *buf, ulong len) const
14356 {
14357   DBUG_ENTER("Transaction_context_log_event::to_string");
14358   DBUG_RETURN(my_snprintf(buf, len,
14359                           "server_uuid=%s\tthread_id=%lu",
14360                           server_uuid, thread_id));
14361 }
14362 
14363 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14364 int Transaction_context_log_event::pack_info(Protocol *protocol)
14365 {
14366   DBUG_ENTER("Transaction_context_log_event::pack_info");
14367   char buf[256];
14368   size_t bytes= to_string(buf, 256);
14369   protocol->store(buf, bytes, &my_charset_bin);
14370   DBUG_RETURN(0);
14371 }
14372 #endif
14373 
14374 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14375 void Transaction_context_log_event::print(FILE *file,
14376                                           PRINT_EVENT_INFO *print_event_info)
14377 {
14378   DBUG_ENTER("Transaction_context_log_event::print");
14379   char buf[256];
14380   IO_CACHE *const head= &print_event_info->head_cache;
14381 
14382   if (!print_event_info->short_form)
14383   {
14384     to_string(buf, 256);
14385     print_header(head, print_event_info, FALSE);
14386     my_b_printf(head, "Transaction_context: %s\n", buf);
14387   }
14388   DBUG_VOID_RETURN;
14389 }
14390 #endif
14391 
14392 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_update_pos(Relay_log_info * rli)14393 int Transaction_context_log_event::do_update_pos(Relay_log_info *rli)
14394 {
14395   DBUG_ENTER("Transaction_context_log_event::do_update_pos");
14396   rli->inc_event_relay_log_pos();
14397   DBUG_RETURN(0);
14398 }
14399 #endif
14400 
get_data_size()14401 size_t Transaction_context_log_event::get_data_size()
14402 {
14403   DBUG_ENTER("Transaction_context_log_event::get_data_size");
14404 
14405   size_t size= Binary_log_event::TRANSACTION_CONTEXT_HEADER_LEN;
14406   size += strlen(server_uuid);
14407   size += get_snapshot_version_size();
14408   size += get_data_set_size(&write_set);
14409   size += get_data_set_size(&read_set);
14410 
14411   DBUG_RETURN(size);
14412 }
14413 
14414 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)14415 bool Transaction_context_log_event::write_data_header(IO_CACHE* file)
14416 {
14417   DBUG_ENTER("Transaction_context_log_event::write_data_header");
14418   char buf[Binary_log_event::TRANSACTION_CONTEXT_HEADER_LEN];
14419 
14420   buf[ENCODED_SERVER_UUID_LEN_OFFSET] = (char) strlen(server_uuid);
14421   int4store(buf + ENCODED_THREAD_ID_OFFSET, thread_id);
14422   buf[ENCODED_GTID_SPECIFIED_OFFSET] = gtid_specified;
14423   int4store(buf + ENCODED_SNAPSHOT_VERSION_LEN_OFFSET, get_snapshot_version_size());
14424   int4store(buf + ENCODED_WRITE_SET_ITEMS_OFFSET, write_set.size());
14425   int4store(buf + ENCODED_READ_SET_ITEMS_OFFSET, read_set.size());
14426   DBUG_RETURN(wrapper_my_b_safe_write(file, (const uchar *) buf,
14427                                       Binary_log_event::TRANSACTION_CONTEXT_HEADER_LEN));
14428 }
14429 
write_data_body(IO_CACHE * file)14430 bool Transaction_context_log_event::write_data_body(IO_CACHE* file)
14431 {
14432   DBUG_ENTER("Transaction_context_log_event::write_data_body");
14433 
14434   if (wrapper_my_b_safe_write(file,
14435                               (const uchar*) server_uuid,
14436                               strlen(server_uuid)) ||
14437       write_snapshot_version(file) ||
14438       write_data_set(file, &write_set) ||
14439       write_data_set(file, &read_set))
14440     DBUG_RETURN(true);
14441 
14442   DBUG_RETURN(false);
14443 }
14444 
write_snapshot_version(IO_CACHE * file)14445 bool Transaction_context_log_event::write_snapshot_version(IO_CACHE* file)
14446 {
14447   DBUG_ENTER("Transaction_context_log_event::write_snapshot_version");
14448   bool result= false;
14449 
14450   uint32 len= get_snapshot_version_size();
14451   uchar *buffer= (uchar *) my_malloc(key_memory_log_event,
14452                                      len, MYF(MY_WME));
14453   if (buffer == NULL)
14454     DBUG_RETURN(true);
14455 
14456   snapshot_version->encode(buffer);
14457   if (wrapper_my_b_safe_write(file, buffer, len))
14458     result= true;
14459 
14460   my_free(buffer);
14461   DBUG_RETURN(result);
14462 }
14463 
write_data_set(IO_CACHE * file,std::list<const char * > * set)14464 bool Transaction_context_log_event::write_data_set(IO_CACHE* file,
14465                                                    std::list<const char*> *set)
14466 {
14467   DBUG_ENTER("Transaction_context_log_event::write_data_set");
14468   for (std::list<const char*>::iterator it=set->begin();
14469        it != set->end();
14470        ++it)
14471   {
14472     char buf[ENCODED_READ_WRITE_SET_ITEM_LEN];
14473     const char* hash= *it;
14474     uint16 len= strlen(hash);
14475 
14476     int2store(buf, len);
14477     if (wrapper_my_b_safe_write(file,
14478                                 (const uchar*) buf,
14479                                 ENCODED_READ_WRITE_SET_ITEM_LEN) ||
14480         wrapper_my_b_safe_write(file, (const uchar*) hash, len))
14481       DBUG_RETURN(true);
14482   }
14483 
14484   DBUG_RETURN(false);
14485 }
14486 #endif
14487 
read_snapshot_version()14488 bool Transaction_context_log_event::read_snapshot_version()
14489 {
14490   DBUG_ENTER("Transaction_context_log_event::read_snapshot_version");
14491   assert(snapshot_version->is_empty());
14492 
14493   global_sid_lock->wrlock();
14494   enum_return_status return_status= global_sid_map->copy(sid_map);
14495   global_sid_lock->unlock();
14496   if (return_status != RETURN_STATUS_OK)
14497     DBUG_RETURN(true);
14498 
14499   DBUG_RETURN(snapshot_version->add_gtid_encoding(encoded_snapshot_version,
14500                                                   encoded_snapshot_version_length)
14501                   != RETURN_STATUS_OK);
14502 }
14503 
get_snapshot_version_size()14504 size_t Transaction_context_log_event::get_snapshot_version_size()
14505 {
14506   DBUG_ENTER("Transaction_context_log_event::get_snapshot_version_size");
14507   size_t result= snapshot_version->get_encoded_length();
14508   DBUG_RETURN(result);
14509 }
14510 
get_data_set_size(std::list<const char * > * set)14511 int Transaction_context_log_event::get_data_set_size(std::list<const char*> *set)
14512 {
14513   DBUG_ENTER("Transaction_context_log_event::get_data_set_size");
14514   int size= 0;
14515 
14516   for (std::list<const char*>::iterator it=set->begin();
14517        it != set->end();
14518        ++it)
14519     size += ENCODED_READ_WRITE_SET_ITEM_LEN + strlen(*it);
14520 
14521   DBUG_RETURN(size);
14522 }
14523 
add_write_set(const char * hash)14524 void Transaction_context_log_event::add_write_set(const char *hash)
14525 {
14526   DBUG_ENTER("Transaction_context_log_event::add_write_set");
14527   write_set.push_back(hash);
14528   DBUG_VOID_RETURN;
14529 }
14530 
add_read_set(const char * hash)14531 void Transaction_context_log_event::add_read_set(const char *hash)
14532 {
14533   DBUG_ENTER("Transaction_context_log_event::add_read_set");
14534   read_set.push_back(hash);
14535   DBUG_VOID_RETURN;
14536 }
14537 
14538 /**************************************************************************
14539 	View_change_log_event methods
14540 **************************************************************************/
14541 
14542 #ifndef MYSQL_CLIENT
View_change_log_event(char * raw_view_id)14543 View_change_log_event::View_change_log_event(char* raw_view_id)
14544   : binary_log::View_change_event(raw_view_id),
14545     Log_event(header(), footer(), Log_event::EVENT_TRANSACTIONAL_CACHE,
14546               Log_event::EVENT_NORMAL_LOGGING)
14547 {
14548   DBUG_ENTER("View_change_log_event::View_change_log_event(char*)");
14549   common_header->flags|= LOG_EVENT_IGNORABLE_F;
14550 
14551   if (strlen(view_id) != 0)
14552     is_valid_param= true;
14553 
14554   DBUG_VOID_RETURN;
14555 }
14556 #endif
14557 
14558 View_change_log_event::
View_change_log_event(const char * buffer,uint event_len,const Format_description_event * descr_event)14559 View_change_log_event(const char *buffer,
14560                       uint event_len,
14561                       const Format_description_event *descr_event)
14562   : binary_log::View_change_event(buffer, event_len, descr_event),
14563     Log_event(header(), footer())
14564 {
14565   DBUG_ENTER("View_change_log_event::View_change_log_event(const char *,"
14566              " uint, const Format_description_event*)");
14567   common_header->flags|= LOG_EVENT_IGNORABLE_F;
14568 
14569   if (strlen(view_id) != 0)
14570     is_valid_param= true;
14571 
14572   //Change the cache/logging types to allow writing to the binary log cache
14573   event_cache_type= EVENT_TRANSACTIONAL_CACHE;
14574   event_logging_type= EVENT_NORMAL_LOGGING;
14575 
14576   DBUG_VOID_RETURN;
14577 }
14578 
~View_change_log_event()14579 View_change_log_event::~View_change_log_event()
14580 {
14581   DBUG_ENTER("View_change_log_event::~View_change_log_event");
14582   certification_info.clear();
14583   DBUG_VOID_RETURN;
14584 }
14585 
get_data_size()14586 size_t View_change_log_event::get_data_size()
14587 {
14588   DBUG_ENTER("View_change_log_event::get_data_size");
14589 
14590   size_t size= Binary_log_event::VIEW_CHANGE_HEADER_LEN;
14591   size+= get_size_data_map(&certification_info);
14592 
14593   DBUG_RETURN(size);
14594 }
14595 
14596 size_t
get_size_data_map(std::map<std::string,std::string> * map)14597 View_change_log_event::get_size_data_map(std::map<std::string, std::string> *map)
14598 {
14599   DBUG_ENTER("View_change_log_event::get_size_data_map");
14600   size_t size= 0;
14601 
14602   std::map<std::string, std::string>::iterator iter;
14603   size+= (ENCODED_CERT_INFO_KEY_SIZE_LEN +
14604           ENCODED_CERT_INFO_VALUE_LEN) * map->size();
14605   for (iter= map->begin(); iter!= map->end(); iter++)
14606     size+= iter->first.length() + iter->second.length();
14607 
14608   DBUG_RETURN(size);
14609 }
14610 
to_string(char * buf,ulong len) const14611 size_t View_change_log_event::to_string(char *buf, ulong len) const
14612 {
14613   DBUG_ENTER("View_change_log_event::to_string");
14614   DBUG_RETURN(my_snprintf(buf, len, "view_id=%s", view_id));
14615 }
14616 
14617 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14618 int View_change_log_event::pack_info(Protocol *protocol)
14619 {
14620   DBUG_ENTER("View_change_log_event::pack_info");
14621   char buf[256];
14622   size_t bytes= to_string(buf, 256);
14623   protocol->store(buf, bytes, &my_charset_bin);
14624   DBUG_RETURN(0);
14625 }
14626 #endif
14627 
14628 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14629 void View_change_log_event::print(FILE *file,
14630                                   PRINT_EVENT_INFO *print_event_info)
14631 {
14632   DBUG_ENTER("View_change_log_event::print");
14633   char buf[256];
14634   IO_CACHE *const head= &print_event_info->head_cache;
14635 
14636   if (!print_event_info->short_form)
14637   {
14638     to_string(buf, 256);
14639     print_header(head, print_event_info, FALSE);
14640     my_b_printf(head, "View_change_log_event: %s\n", buf);
14641   }
14642   DBUG_VOID_RETURN;
14643 }
14644 #endif
14645 
14646 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
14647 
do_apply_event(Relay_log_info const * rli)14648 int View_change_log_event::do_apply_event(Relay_log_info const *rli)
14649 {
14650   enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
14651   if (state == GTID_STATEMENT_SKIP)
14652     return 0;
14653 
14654   if (state == GTID_STATEMENT_CANCEL ||
14655          (state == GTID_STATEMENT_EXECUTE &&
14656           gtid_pre_statement_post_implicit_commit_checks(thd)))
14657   {
14658     uint error= thd->get_stmt_da()->mysql_errno();
14659     assert(error != 0);
14660     rli->report(ERROR_LEVEL, error,
14661                 "Error executing View Change event: '%s'",
14662                 thd->get_stmt_da()->message_text());
14663     thd->is_slave_error= 1;
14664     return -1;
14665   }
14666 
14667   if (!opt_bin_log)
14668   {
14669     return 0;
14670   }
14671 
14672   int error= mysql_bin_log.write_event(this);
14673   if (error)
14674     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
14675                 "Could not write the VIEW CHANGE event in the binary log.");
14676 
14677   return (error);
14678 }
14679 
do_update_pos(Relay_log_info * rli)14680 int View_change_log_event::do_update_pos(Relay_log_info *rli)
14681 {
14682   DBUG_ENTER("View_change_log_event::do_update_pos");
14683   rli->inc_event_relay_log_pos();
14684   DBUG_RETURN(0);
14685 }
14686 #endif
14687 
14688 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)14689 bool View_change_log_event::write_data_header(IO_CACHE* file){
14690   DBUG_ENTER("View_change_log_event::write_data_header");
14691   char buf[Binary_log_event::VIEW_CHANGE_HEADER_LEN];
14692 
14693   memcpy(buf, view_id, ENCODED_VIEW_ID_MAX_LEN);
14694   int8store(buf + ENCODED_SEQ_NUMBER_OFFSET, seq_number);
14695   int4store(buf + ENCODED_CERT_INFO_SIZE_OFFSET, certification_info.size());
14696   DBUG_RETURN(wrapper_my_b_safe_write(file,(const uchar *) buf,
14697                                       Binary_log_event::VIEW_CHANGE_HEADER_LEN));
14698 }
14699 
write_data_body(IO_CACHE * file)14700 bool View_change_log_event::write_data_body(IO_CACHE* file){
14701   DBUG_ENTER("Transaction_context_log_event::write_data_body");
14702 
14703   if (write_data_map(file, &certification_info))
14704     DBUG_RETURN(true);
14705 
14706   DBUG_RETURN(false);
14707 }
14708 
write_data_map(IO_CACHE * file,std::map<std::string,std::string> * map)14709 bool View_change_log_event::write_data_map(IO_CACHE* file,
14710                                            std::map<std::string, std::string> *map)
14711 {
14712   DBUG_ENTER("View_change_log_event::write_data_set");
14713   bool result= false;
14714 
14715   std::map<std::string, std::string>::iterator iter;
14716   for (iter= map->begin(); iter!= map->end(); iter++)
14717   {
14718     uchar buf_key_len[ENCODED_CERT_INFO_KEY_SIZE_LEN];
14719     uint16 key_len= iter->first.length();
14720     int2store(buf_key_len, key_len);
14721 
14722     const char *key= iter->first.c_str();
14723 
14724     uchar buf_value_len[ENCODED_CERT_INFO_VALUE_LEN];
14725     uint32 value_len= iter->second.length();
14726     int4store(buf_value_len, value_len);
14727 
14728     const char *value= iter->second.c_str();
14729 
14730     if (wrapper_my_b_safe_write(file, buf_key_len,
14731                                 ENCODED_CERT_INFO_KEY_SIZE_LEN) ||
14732         wrapper_my_b_safe_write(file, (const uchar*) key, key_len) ||
14733         wrapper_my_b_safe_write(file, buf_value_len,
14734                                 ENCODED_CERT_INFO_VALUE_LEN) ||
14735         wrapper_my_b_safe_write(file, (const uchar*) value, value_len))
14736       DBUG_RETURN(result);
14737   }
14738 
14739   DBUG_RETURN(false);
14740 }
14741 
14742 #endif
14743 
14744 /*
14745   Updates the certification info map.
14746 */
set_certification_info(std::map<std::string,std::string> * info,size_t * event_size)14747 void View_change_log_event::set_certification_info(
14748     std::map<std::string, std::string> *info, size_t *event_size) {
14749   DBUG_ENTER("View_change_log_event::set_certification_database_snapshot");
14750   certification_info.clear();
14751 
14752   *event_size = Binary_log_event::VIEW_CHANGE_HEADER_LEN;
14753   std::map<std::string, std::string>::iterator it;
14754   for(it= info->begin(); it != info->end(); ++it)
14755   {
14756     std::string key= it->first;
14757     std::string value= it->second;
14758     certification_info[key]= value;
14759     *event_size += it->first.length() + it->second.length();
14760   }
14761   *event_size +=
14762       (ENCODED_CERT_INFO_KEY_SIZE_LEN + ENCODED_CERT_INFO_VALUE_LEN) *
14763       certification_info.size();
14764 
14765   DBUG_VOID_RETURN;
14766 }
14767 
14768 
14769 #ifdef MYSQL_CLIENT
14770 /**
14771   The default values for these variables should be values that are
14772   *incorrect*, i.e., values that cannot occur in an event.  This way,
14773   they will always be printed for the first event.
14774 */
st_print_event_info()14775 st_print_event_info::st_print_event_info()
14776   :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
14777    auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
14778    lc_time_names_number(~0),
14779    charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
14780    thread_id(0), thread_id_printed(false),
14781    base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE),
14782    have_unflushed_events(false), skipped_event_in_transaction(false)
14783 {
14784   /*
14785     Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
14786     program's startup, but these explicit memset() is for the day someone
14787     creates dynamic instances.
14788   */
14789   memset(db, 0, sizeof(db));
14790   memset(charset, 0, sizeof(charset));
14791   memset(time_zone_str, 0, sizeof(time_zone_str));
14792   delimiter[0]= ';';
14793   delimiter[1]= 0;
14794   myf const flags = MYF(MY_WME | MY_NABP);
14795   open_cached_file(&head_cache, NULL, NULL, 0, flags);
14796   open_cached_file(&body_cache, NULL, NULL, 0, flags);
14797   open_cached_file(&footer_cache, NULL, NULL, 0, flags);
14798 }
14799 #endif
14800 
14801 
14802 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event(const char * buf,uint event_len,const Format_description_event * description_event)14803 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
14804                                          const Format_description_event*
14805                                          description_event)
14806   : binary_log::Heartbeat_event(buf, event_len, description_event),
14807     Log_event(header(), footer())
14808 {
14809   if ((log_ident != NULL && header()->log_pos >= BIN_LOG_HEADER_SIZE))
14810     is_valid_param= true;
14811 }
14812 #endif
14813 
14814 #ifdef MYSQL_SERVER
14815 /*
14816   This is a utility function that adds a quoted identifier into the a buffer.
14817   This also escapes any existance of the quote string inside the identifier.
14818 
14819   SYNOPSIS
14820     my_strmov_quoted_identifier
14821     thd                   thread handler
14822     buffer                target buffer
14823     identifier            the identifier to be quoted
14824     length                length of the identifier
14825 */
my_strmov_quoted_identifier(THD * thd,char * buffer,const char * identifier,size_t length)14826 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
14827                                    const char* identifier,
14828                                    size_t length)
14829 {
14830   int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
14831   return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
14832 }
14833 #else
my_strmov_quoted_identifier(char * buffer,const char * identifier)14834 size_t my_strmov_quoted_identifier(char *buffer,  const char* identifier)
14835 {
14836   int q= '`';
14837   return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
14838 }
14839 
14840 #endif
14841 
my_strmov_quoted_identifier_helper(int q,char * buffer,const char * identifier,size_t length)14842 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
14843                                           const char* identifier,
14844                                           size_t length)
14845 {
14846   size_t written= 0;
14847   char quote_char;
14848   size_t id_length= (length) ? length : strlen(identifier);
14849 
14850   if (q == EOF)
14851   {
14852     (void) strncpy(buffer, identifier, id_length);
14853     return id_length;
14854   }
14855   quote_char= (char) q;
14856   *buffer++= quote_char;
14857   written++;
14858   while (id_length--)
14859   {
14860     if (*identifier == quote_char)
14861     {
14862       *buffer++= quote_char;
14863       written++;
14864     }
14865     *buffer++= *identifier++;
14866     written++;
14867   }
14868   *buffer++= quote_char;
14869   return ++written;
14870 }
14871 
14872