MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
log_event.h
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15 
28 #ifndef _log_event_h
29 #define _log_event_h
30 
31 #include <my_bitmap.h>
32 #include "rpl_constants.h"
33 #include "table_id.h"
34 
35 #ifdef MYSQL_CLIENT
36 #include "sql_const.h"
37 #include "rpl_utility.h"
38 #include "hash.h"
39 #include "rpl_tblmap.h"
40 #endif
41 
42 #ifdef MYSQL_SERVER
43 #include "rpl_record.h"
44 #include "rpl_reporting.h"
45 #include "sql_class.h" /* THD */
46 #include "rpl_utility.h" /* Hash_slave_rows */
47 #include "rpl_filter.h"
48 #endif
49 
50 /* Forward declarations */
51 class String;
52 typedef ulonglong sql_mode_t;
53 typedef struct st_db_worker_hash_entry db_worker_hash_entry;
54 
55 #define PREFIX_SQL_LOAD "SQL_LOAD-"
56 
67 #define TEMP_FILE_MAX_LEN UUID_LENGTH+38
68 
78 #ifdef DBUG_OFF
79 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
80  do { if (!(COND)) return ERRNO; } while (0)
81 #else
82 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
83  DBUG_ASSERT(COND)
84 #endif
85 
86 #define LOG_READ_EOF -1
87 #define LOG_READ_BOGUS -2
88 #define LOG_READ_IO -3
89 #define LOG_READ_MEM -5
90 #define LOG_READ_TRUNC -6
91 #define LOG_READ_TOO_LARGE -7
92 #define LOG_READ_CHECKSUM_FAILURE -8
93 
94 #define LOG_EVENT_OFFSET 4
95 
96 /*
97  3 is MySQL 4.x; 4 is MySQL 5.0.0.
98  Compared to version 3, version 4 has:
99  - a different Start_log_event, which includes info about the binary log
100  (sizes of headers); this info is included for better compatibility if the
101  master's MySQL version is different from the slave's.
102  - all events have a unique ID (the triplet (server_id, timestamp at server
103  start, other) to be sure an event is not executed more than once in a
104  multimaster setup, example:
105  M1
106  / \
107  v v
108  M2 M3
109  \ /
110  v v
111  S
112  if a query is run on M1, it will arrive twice on S, so we need that S
113  remembers the last unique ID it has processed, to compare and know if the
114  event should be skipped or not. Example of ID: we already have the server id
115  (4 bytes), plus:
116  timestamp_when_the_master_started (4 bytes), a counter (a sequence number
117  which increments every time we write an event to the binlog) (3 bytes).
118  Q: how do we handle when the counter is overflowed and restarts from 0 ?
119 
120  - Query and Load (Create or Execute) events may have a more precise
121  timestamp (with microseconds), number of matched/affected/warnings rows
122  and fields of session variables: SQL_MODE,
123  FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and
124  charsets, the PASSWORD() version (old/new/...).
125 */
126 #define BINLOG_VERSION 4
127 
128 /*
129  We could have used SERVER_VERSION_LENGTH, but this introduces an
130  obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
131  this would break the replication protocol
132 */
133 #define ST_SERVER_VER_LEN 50
134 
135 /*
136  These are flags and structs to handle all the LOAD DATA INFILE options (LINES
137  TERMINATED etc).
138 */
139 
140 /*
141  These are flags and structs to handle all the LOAD DATA INFILE options (LINES
142  TERMINATED etc).
143  DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD
144  DATA).
145 */
146 #define DUMPFILE_FLAG 0x1
147 #define OPT_ENCLOSED_FLAG 0x2
148 #define REPLACE_FLAG 0x4
149 #define IGNORE_FLAG 0x8
150 
151 #define FIELD_TERM_EMPTY 0x1
152 #define ENCLOSED_EMPTY 0x2
153 #define LINE_TERM_EMPTY 0x4
154 #define LINE_START_EMPTY 0x8
155 #define ESCAPED_EMPTY 0x10
156 
157 /*****************************************************************************
158 
159  old_sql_ex struct
160 
161  ****************************************************************************/
163 {
164  char field_term;
165  char enclosed;
166  char line_term;
167  char line_start;
168  char escaped;
169  char opt_flags;
170  char empty_flags;
171 };
172 
173 #define NUM_LOAD_DELIM_STRS 5
174 
175 /*****************************************************************************
176 
177  sql_ex_info struct
178 
179  ****************************************************************************/
181 {
182  sql_ex_info() {} /* Remove gcc warning */
183  const char* field_term;
184  const char* enclosed;
185  const char* line_term;
186  const char* line_start;
187  const char* escaped;
188  int cached_new_format;
189  uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
190  char opt_flags;
191  char empty_flags;
192 
193  // store in new format even if old is possible
194  void force_new_format() { cached_new_format = 1;}
195  int data_size()
196  {
197  return (new_format() ?
198  field_term_len + enclosed_len + line_term_len +
199  line_start_len + escaped_len + 6 : 7);
200  }
201  bool write_data(IO_CACHE* file);
202  const char* init(const char* buf, const char* buf_end, bool use_new_format);
203  bool new_format()
204  {
205  return ((cached_new_format != -1) ? cached_new_format :
206  (cached_new_format=(field_term_len > 1 ||
207  enclosed_len > 1 ||
208  line_term_len > 1 || line_start_len > 1 ||
209  escaped_len > 1)));
210  }
211 };
212 
213 /*****************************************************************************
214 
215  MySQL Binary Log
216 
217  This log consists of events. Each event has a fixed-length header,
218  possibly followed by a variable length data body.
219 
220  The data body consists of an optional fixed length segment (post-header)
221  and an optional variable length segment.
222 
223  See the #defines below for the format specifics.
224 
225  The events which really update data are Query_log_event,
226  Execute_load_query_log_event and old Load_log_event and
227  Execute_load_log_event events (Execute_load_query is used together with
228  Begin_load_query and Append_block events to replicate LOAD DATA INFILE.
229  Create_file/Append_block/Execute_load (which includes Load_log_event)
230  were used to replicate LOAD DATA before the 5.0.3).
231 
232  ****************************************************************************/
233 
234 #define LOG_EVENT_HEADER_LEN 19U /* the fixed header length */
235 #define OLD_HEADER_LEN 13U /* the fixed header length in 3.23 */
236 /*
237  Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer
238  header (it will for sure when we have the unique event's ID), but at least
239  the first 19 bytes are the same in 4.x and 5.0. So when we have the unique
240  event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but
241  LOG_EVENT_MINIMAL_HEADER_LEN will remain 19.
242 */
243 #define LOG_EVENT_MINIMAL_HEADER_LEN 19U
244 
245 /* event-specific post-header sizes */
246 // where 3.23, 4.x and 5.0 agree
247 #define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2)
248 // where 5.0 differs: 2 for len of N-bytes vars.
249 #define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2)
250 #define STOP_HEADER_LEN 0
251 #define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4)
252 #define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4)
253 #define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen)
254 #define INTVAR_HEADER_LEN 0
255 #define CREATE_FILE_HEADER_LEN 4
256 #define APPEND_BLOCK_HEADER_LEN 4
257 #define EXEC_LOAD_HEADER_LEN 4
258 #define DELETE_FILE_HEADER_LEN 4
259 #define NEW_LOAD_HEADER_LEN LOAD_HEADER_LEN
260 #define RAND_HEADER_LEN 0
261 #define USER_VAR_HEADER_LEN 0
262 #define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
263 #define XID_HEADER_LEN 0
264 #define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
265 #define ROWS_HEADER_LEN_V1 8
266 #define TABLE_MAP_HEADER_LEN 8
267 #define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
268 #define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
269 #define INCIDENT_HEADER_LEN 2
270 #define HEARTBEAT_HEADER_LEN 0
271 #define IGNORABLE_HEADER_LEN 0
272 #define ROWS_HEADER_LEN_V2 10
273 
274 /*
275  The maximum number of updated databases that a status of
276  Query-log-event can carry. It can redefined within a range
277  [1.. OVER_MAX_DBS_IN_EVENT_MTS].
278 */
279 #define MAX_DBS_IN_EVENT_MTS 16
280 
281 /*
282  When the actual number of databases exceeds MAX_DBS_IN_EVENT_MTS
283  the value of OVER_MAX_DBS_IN_EVENT_MTS is is put into the
284  mts_accessed_dbs status.
285 */
286 #define OVER_MAX_DBS_IN_EVENT_MTS 254
287 
288 /*
289  Max number of possible extra bytes in a replication event compared to a
290  packet (i.e. a query) sent from client to master;
291  First, an auxiliary log_event status vars estimation:
292 */
293 #define MAX_SIZE_LOG_EVENT_STATUS (1U + 4 /* type, flags2 */ + \
294  1U + 8 /* type, sql_mode */ + \
295  1U + 1 + 255 /* type, length, catalog */ + \
296  1U + 4 /* type, auto_increment */ + \
297  1U + 6 /* type, charset */ + \
298  1U + 1 + 255 /* type, length, time_zone */ + \
299  1U + 2 /* type, lc_time_names_number */ + \
300  1U + 2 /* type, charset_database_number */ + \
301  1U + 8 /* type, table_map_for_update */ + \
302  1U + 4 /* type, master_data_written */ + \
303  /* type, db_1, db_2, ... */ \
304  1U + (MAX_DBS_IN_EVENT_MTS * (1 + NAME_LEN)) + \
305  3U + /* type, microseconds */ + \
306  1U + 16 + 1 + 60/* type, user_len, user, host_len, host */)
307 #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
308  LOG_EVENT_HEADER_LEN + /* write_header */ \
309  QUERY_HEADER_LEN + /* write_data */ \
310  EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \
311  MAX_SIZE_LOG_EVENT_STATUS + /* status */ \
312  NAME_LEN + 1)
313 
314 /*
315  The new option is added to handle large packets that are sent from the master
316  to the slave. It is used to increase the thd(max_allowed) for both the
317  DUMP thread on the master and the SQL/IO thread on the slave.
318 */
319 #define MAX_MAX_ALLOWED_PACKET 1024*1024*1024
320 
321 /*
322  Event header offsets;
323  these point to places inside the fixed header.
324 */
325 
326 #define EVENT_TYPE_OFFSET 4
327 #define SERVER_ID_OFFSET 5
328 #define EVENT_LEN_OFFSET 9
329 #define LOG_POS_OFFSET 13
330 #define FLAGS_OFFSET 17
331 
332 /* start event post-header (for v3 and v4) */
333 
334 #define ST_BINLOG_VER_OFFSET 0
335 #define ST_SERVER_VER_OFFSET 2
336 #define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
337 #define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4)
338 
339 /* slave event post-header (this event is never written) */
340 
341 #define SL_MASTER_PORT_OFFSET 8
342 #define SL_MASTER_POS_OFFSET 0
343 #define SL_MASTER_HOST_OFFSET 10
344 
345 /* query event post-header */
346 
347 #define Q_THREAD_ID_OFFSET 0
348 #define Q_EXEC_TIME_OFFSET 4
349 #define Q_DB_LEN_OFFSET 8
350 #define Q_ERR_CODE_OFFSET 9
351 #define Q_STATUS_VARS_LEN_OFFSET 11
352 #define Q_DATA_OFFSET QUERY_HEADER_LEN
353 /* these are codes, not offsets; not more than 256 values (1 byte). */
354 #define Q_FLAGS2_CODE 0
355 #define Q_SQL_MODE_CODE 1
356 /*
357  Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL
358  5.0.x where 0<=x<=3. We have to keep it to be able to replicate these
359  old masters.
360 */
361 #define Q_CATALOG_CODE 2
362 #define Q_AUTO_INCREMENT 3
363 #define Q_CHARSET_CODE 4
364 #define Q_TIME_ZONE_CODE 5
365 /*
366  Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL
367  5.0.x where x>=4. Saves one byte in every Query_log_event in binlog,
368  compared to Q_CATALOG_CODE. The reason we didn't simply re-use
369  Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would
370  crash (segfault etc) because it would expect a 0 when there is none.
371 */
372 #define Q_CATALOG_NZ_CODE 6
373 
374 #define Q_LC_TIME_NAMES_CODE 7
375 
376 #define Q_CHARSET_DATABASE_CODE 8
377 
378 #define Q_TABLE_MAP_FOR_UPDATE_CODE 9
379 
380 #define Q_MASTER_DATA_WRITTEN_CODE 10
381 
382 #define Q_INVOKER 11
383 
384 /*
385  Q_UPDATED_DB_NAMES status variable collects of the updated databases
386  total number and their names to be propagated to the slave in order
387  to facilitate the parallel applying of the Query events.
388 */
389 #define Q_UPDATED_DB_NAMES 12
390 
391 #define Q_MICROSECONDS 13
392 
393 /* Intvar event post-header */
394 
395 /* Intvar event data */
396 #define I_TYPE_OFFSET 0
397 #define I_VAL_OFFSET 1
398 
399 /* Rand event data */
400 #define RAND_SEED1_OFFSET 0
401 #define RAND_SEED2_OFFSET 8
402 
403 /* User_var event data */
404 #define UV_VAL_LEN_SIZE 4
405 #define UV_VAL_IS_NULL 1
406 #define UV_VAL_TYPE_SIZE 1
407 #define UV_NAME_LEN_SIZE 4
408 #define UV_CHARSET_NUMBER_SIZE 4
409 
410 /* Load event post-header */
411 #define L_THREAD_ID_OFFSET 0
412 #define L_EXEC_TIME_OFFSET 4
413 #define L_SKIP_LINES_OFFSET 8
414 #define L_TBL_LEN_OFFSET 12
415 #define L_DB_LEN_OFFSET 13
416 #define L_NUM_FIELDS_OFFSET 14
417 #define L_SQL_EX_OFFSET 18
418 #define L_DATA_OFFSET LOAD_HEADER_LEN
419 
420 /* Rotate event post-header */
421 #define R_POS_OFFSET 0
422 #define R_IDENT_OFFSET 8
423 
424 /* CF to DF handle LOAD DATA INFILE */
425 
426 /* CF = "Create File" */
427 #define CF_FILE_ID_OFFSET 0
428 #define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN
429 
430 /* AB = "Append Block" */
431 #define AB_FILE_ID_OFFSET 0
432 #define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN
433 
434 /* EL = "Execute Load" */
435 #define EL_FILE_ID_OFFSET 0
436 
437 /* DF = "Delete File" */
438 #define DF_FILE_ID_OFFSET 0
439 
440 /* TM = "Table Map" */
441 #define TM_MAPID_OFFSET 0
442 #define TM_FLAGS_OFFSET 6
443 
444 /* RW = "RoWs" */
445 #define RW_MAPID_OFFSET 0
446 #define RW_FLAGS_OFFSET 6
447 #define RW_VHLEN_OFFSET 8
448 #define RW_V_TAG_LEN 1
449 #define RW_V_EXTRAINFO_TAG 0
450 
451 /* ELQ = "Execute Load Query" */
452 #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
453 #define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4
454 #define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8
455 #define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12
456 
457 /* 4 bytes which all binlogs should begin with */
458 #define BINLOG_MAGIC "\xfe\x62\x69\x6e"
459 
460 /*
461  The 2 flags below were useless :
462  - the first one was never set
463  - the second one was set in all Rotate events on the master, but not used for
464  anything useful.
465  So they are now removed and their place may later be reused for other
466  flags. Then one must remember that Rotate events in 4.x have
467  LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the
468  replacing flag when reading a Rotate event.
469  I keep the defines here just to remember what they were.
470 */
471 #ifdef TO_BE_REMOVED
472 #define LOG_EVENT_TIME_F 0x1
473 #define LOG_EVENT_FORCED_ROTATE_F 0x2
474 #endif
475 
476 /*
477  This flag only makes sense for Format_description_log_event. It is set
478  when the event is written, and *reset* when a binlog file is
479  closed (yes, it's the only case when MySQL modifies already written
480  part of binlog). Thus it is a reliable indicator that binlog was
481  closed correctly. (Stop_log_event is not enough, there's always a
482  small chance that mysqld crashes in the middle of insert and end of
483  the binlog would look like a Stop_log_event).
484 
485  This flag is used to detect a restart after a crash, and to provide
486  "unbreakable" binlog. The problem is that on a crash storage engines
487  rollback automatically, while binlog does not. To solve this we use this
488  flag and automatically append ROLLBACK to every non-closed binlog (append
489  virtually, on reading, file itself is not changed). If this flag is found,
490  mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on
491  binlog corruption, but takes it as EOF, and replication slave forces a
492  rollback in this case.
493 
494  Note, that old binlogs does not have this flag set, so we get a
495  a backward-compatible behaviour.
496 */
497 
498 #define LOG_EVENT_BINLOG_IN_USE_F 0x1
499 
508 #define LOG_EVENT_THREAD_SPECIFIC_F 0x4
509 
523 #define LOG_EVENT_SUPPRESS_USE_F 0x8
524 
525 /*
526  Note: this is a place holder for the flag
527  LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any
528  more, please do not reused this value for other flags.
529  */
530 
540 #define LOG_EVENT_ARTIFICIAL_F 0x20
541 
548 #define LOG_EVENT_RELAY_LOG_F 0x40
549 
559 #define LOG_EVENT_IGNORABLE_F 0x80
560 
568 #define LOG_EVENT_NO_FILTER_F 0x100
569 
579 #define LOG_EVENT_MTS_ISOLATE_F 0x200
580 
581 
603 #define OPTIONS_WRITTEN_TO_BIN_LOG \
604  (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \
605  OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT)
606 
607 /* Shouldn't be defined before */
608 #define EXPECTED_OPTIONS \
609  ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19))
610 
611 #if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS
612 #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values!
613 #endif
614 #undef EXPECTED_OPTIONS /* You shouldn't use this one */
615 
616 enum enum_binlog_checksum_alg {
617  BINLOG_CHECKSUM_ALG_OFF= 0, // Events are without checksum though its generator
618  // is checksum-capable New Master (NM).
619  BINLOG_CHECKSUM_ALG_CRC32= 1, // CRC32 of zlib algorithm.
620  BINLOG_CHECKSUM_ALG_ENUM_END, // the cut line: valid alg range is [1, 0x7f].
621  BINLOG_CHECKSUM_ALG_UNDEF= 255 // special value to tag undetermined yet checksum
622  // or events from checksum-unaware servers
623 };
624 
625 #define CHECKSUM_CRC32_SIGNATURE_LEN 4
626 
629 #define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
630 #define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */
631 
638 {
639  /*
640  Every time you update this enum (when you add a type), you have to
641  fix Format_description_log_event::Format_description_log_event().
642  */
643  UNKNOWN_EVENT= 0,
644  START_EVENT_V3= 1,
645  QUERY_EVENT= 2,
646  STOP_EVENT= 3,
647  ROTATE_EVENT= 4,
648  INTVAR_EVENT= 5,
649  LOAD_EVENT= 6,
650  SLAVE_EVENT= 7, /* Unused. Slave_log_event code has been removed. (15th Oct. 2010) */
651  CREATE_FILE_EVENT= 8,
652  APPEND_BLOCK_EVENT= 9,
653  EXEC_LOAD_EVENT= 10,
654  DELETE_FILE_EVENT= 11,
655  /*
656  NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
657  sql_ex, allowing multibyte TERMINATED BY etc; both types share the
658  same class (Load_log_event)
659  */
660  NEW_LOAD_EVENT= 12,
661  RAND_EVENT= 13,
662  USER_VAR_EVENT= 14,
663  FORMAT_DESCRIPTION_EVENT= 15,
664  XID_EVENT= 16,
665  BEGIN_LOAD_QUERY_EVENT= 17,
666  EXECUTE_LOAD_QUERY_EVENT= 18,
667 
668  TABLE_MAP_EVENT = 19,
669 
670  /*
671  These event numbers were used for 5.1.0 to 5.1.15 and are
672  therefore obsolete.
673  */
674  PRE_GA_WRITE_ROWS_EVENT = 20,
675  PRE_GA_UPDATE_ROWS_EVENT = 21,
676  PRE_GA_DELETE_ROWS_EVENT = 22,
677 
678  /*
679  These event numbers are used from 5.1.16 until mysql-trunk-xx
680  */
681  WRITE_ROWS_EVENT_V1 = 23,
682  UPDATE_ROWS_EVENT_V1 = 24,
683  DELETE_ROWS_EVENT_V1 = 25,
684 
685  /*
686  Something out of the ordinary happened on the master
687  */
688  INCIDENT_EVENT= 26,
689 
690  /*
691  Heartbeat event to be send by master at its idle time
692  to ensure master's online status to slave
693  */
694  HEARTBEAT_LOG_EVENT= 27,
695 
696  /*
697  In some situations, it is necessary to send over ignorable
698  data to the slave: data that a slave can handle in case there
699  is code for handling it, but which can be ignored if it is not
700  recognized.
701  */
702  IGNORABLE_LOG_EVENT= 28,
703  ROWS_QUERY_LOG_EVENT= 29,
704 
705  /* Version 2 of the Row events */
706  WRITE_ROWS_EVENT = 30,
707  UPDATE_ROWS_EVENT = 31,
708  DELETE_ROWS_EVENT = 32,
709 
710  GTID_LOG_EVENT= 33,
711  ANONYMOUS_GTID_LOG_EVENT= 34,
712 
713  PREVIOUS_GTIDS_LOG_EVENT= 35,
714  /*
715  Add new events here - right above this comment!
716  Existing events (except ENUM_END_EVENT) should never change their numbers
717  */
718 
719  ENUM_END_EVENT /* end marker */
720 };
721 
722 /*
723  The number of types we handle in Format_description_log_event (UNKNOWN_EVENT
724  is not to be handled, it does not exist in binlogs, it does not have a
725  format).
726 */
727 #define LOG_EVENT_TYPES (ENUM_END_EVENT-1)
728 
729 enum Int_event_type
730 {
731  INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
732 };
733 
734 
735 #ifdef MYSQL_SERVER
736 class String;
737 class MYSQL_BIN_LOG;
738 class THD;
739 #endif
740 
742 class Relay_log_info;
743 class Slave_worker;
744 class Slave_committed_queue;
745 
746 #ifdef MYSQL_CLIENT
747 enum enum_base64_output_mode {
748  BASE64_OUTPUT_NEVER= 0,
749  BASE64_OUTPUT_AUTO= 1,
750  BASE64_OUTPUT_UNSPEC= 2,
751  BASE64_OUTPUT_DECODE_ROWS= 3,
752  /* insert new output modes here */
753  BASE64_OUTPUT_MODE_COUNT
754 };
755 
756 /*
757  A structure for mysqlbinlog to know how to print events
758 
759  This structure is passed to the event's print() methods,
760 
761  There are two types of settings stored here:
762  1. Last db, flags2, sql_mode etc comes from the last printed event.
763  They are stored so that only the necessary USE and SET commands
764  are printed.
765  2. Other information on how to print the events, e.g. short_form,
766  hexdump_from. These are not dependent on the last event.
767 */
768 typedef struct st_print_event_info
769 {
770  /*
771  Settings for database, sql_mode etc that comes from the last event
772  that was printed. We cache these so that we don't have to print
773  them if they are unchanged.
774  */
775  // TODO: have the last catalog here ??
776  char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
777  bool flags2_inited;
778  uint32 flags2;
779  bool sql_mode_inited;
780  sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */
781  ulong auto_increment_increment, auto_increment_offset;
782  bool charset_inited;
783  char charset[6]; // 3 variables, each of them storable in 2 bytes
784  char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
785  uint lc_time_names_number;
786  uint charset_database_number;
787  uint thread_id;
788  bool thread_id_printed;
789 
790  st_print_event_info();
791 
792  ~st_print_event_info() {
793  close_cached_file(&head_cache);
794  close_cached_file(&body_cache);
795  }
796  bool init_ok() /* tells if construction was successful */
797  { return my_b_inited(&head_cache) && my_b_inited(&body_cache); }
798 
799 
800  /* Settings on how to print the events */
801  bool short_form;
802  enum_base64_output_mode base64_output_mode;
803  /*
804  This is set whenever a Format_description_event is printed.
805  Later, when an event is printed in base64, this flag is tested: if
806  no Format_description_event has been seen, it is unsafe to print
807  the base64 event, so an error message is generated.
808  */
809  bool printed_fd_event;
810  my_off_t hexdump_from;
811  uint8 common_header_len;
812  char delimiter[16];
813 
814  uint verbose;
815  table_mapping m_table_map;
816  table_mapping m_table_map_ignored;
817 
818  /*
819  These two caches are used by the row-based replication events to
820  collect the header information and the main body of the events
821  making up a statement.
822  */
823  IO_CACHE head_cache;
824  IO_CACHE body_cache;
825  /* Indicate if the body cache has unflushed events */
826  bool have_unflushed_events;
827 
828  /*
829  True if an event was skipped while printing the events of
830  a transaction and no COMMIT statement or XID event was ever
831  output (ie, was filtered out as well). This can be triggered
832  by the --database option of mysqlbinlog.
833 
834  False, otherwise.
835  */
836  bool skipped_event_in_transaction;
837 } PRINT_EVENT_INFO;
838 #endif
839 
971 {
972 public:
985 
992 
997  };
998 
999 protected:
1000  enum enum_event_cache_type
1001  {
1002  EVENT_INVALID_CACHE= 0,
1003  /*
1004  If possible the event should use a non-transactional cache before
1005  being flushed to the binary log. This means that it must be flushed
1006  right after its correspondent statement is completed.
1007  */
1008  EVENT_STMT_CACHE,
1009  /*
1010  The event should use a transactional cache before being flushed to
1011  the binary log. This means that it must be flushed upon commit or
1012  rollback.
1013  */
1014  EVENT_TRANSACTIONAL_CACHE,
1015  /*
1016  The event must be written directly to the binary log without going
1017  through any cache.
1018  */
1019  EVENT_NO_CACHE,
1020  /*
1021  If there is a need for different types, introduce them before this.
1022  */
1023  EVENT_CACHE_COUNT
1024  };
1025 
1026  enum enum_event_logging_type
1027  {
1028  EVENT_INVALID_LOGGING= 0,
1029  /*
1030  The event must be written to a cache and upon commit or rollback
1031  written to the binary log.
1032  */
1033  EVENT_NORMAL_LOGGING,
1034  /*
1035  The event must be written to an empty cache and immediatly written
1036  to the binary log without waiting for any other event.
1037  */
1038  EVENT_IMMEDIATE_LOGGING,
1039  /*
1040  If there is a need for different types, introduce them before this.
1041  */
1042  EVENT_CACHE_LOGGING_COUNT
1043  };
1044 
1045 public:
1046  /*
1047  The following type definition is to be used whenever data is placed
1048  and manipulated in a common buffer. Use this typedef for buffers
1049  that contain data containing binary and character data.
1050  */
1051  typedef unsigned char Byte;
1052 
1053  /*
1054  The offset in the log where this event originally appeared (it is
1055  preserved in relay logs, making SHOW SLAVE STATUS able to print
1056  coordinates of the event in the master's binlog). Note: when a
1057  transaction is written by the master to its binlog (wrapped in
1058  BEGIN/COMMIT) the log_pos of all the queries it contains is the
1059  one of the BEGIN (this way, when one does SHOW SLAVE STATUS it
1060  sees the offset of the BEGIN, which is logical as rollback may
1061  occur), except the COMMIT query which has its real offset.
1062  */
1063  my_off_t log_pos;
1064  /*
1065  A temp buffer for read_log_event; it is later analysed according to the
1066  event's type, and its content is distributed in the event-specific fields.
1067  */
1068  char *temp_buf;
1069  /*
1070  Timestamp on the master(for debugging and replication of
1071  NOW()/TIMESTAMP). It is important for queries and LOAD DATA
1072  INFILE. This is set at the event's creation time, except for Query
1073  and Load (et al.) events where this is set at the query's
1074  execution time, which guarantees good replication (otherwise, we
1075  could have a query and its event with different timestamps).
1076  */
1077  struct timeval when;
1078  /* The number of seconds the query took to run on the master. */
1079  ulong exec_time;
1080  /* Number of bytes written by write() function */
1081  ulong data_written;
1082 
1083  /*
1084  The master's server id (is preserved in the relay log; used to
1085  prevent from infinite loops in circular replication).
1086  */
1087  uint32 server_id;
1088 
1089  /*
1090  The server id read from the Binlog. server_id above has
1091  lowest bits of this only according to the value of
1092  opt_server_id_bits
1093  */
1094  uint32 unmasked_server_id;
1095 
1101  uint16 flags;
1102 
1108 
1113  enum_event_cache_type event_cache_type;
1114 
1119  enum_event_logging_type event_logging_type;
1120 
1124  ha_checksum crc;
1125 
1133 
1140 
1145 
1146 #ifdef MYSQL_SERVER
1147  THD* thd;
1151  db_worker_hash_entry *mts_assigned_partitions[MAX_DBS_IN_EVENT_MTS];
1152 
1153  Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE,
1154  enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING);
1155  Log_event(THD* thd_arg, uint16 flags_arg,
1156  enum_event_cache_type cache_type_arg,
1157  enum_event_logging_type logging_type_arg);
1158  /*
1159  read_log_event() functions read an event from a binlog or relay
1160  log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the
1161  master (reads master's binlog), the slave IO thread (reads the
1162  event sent by binlog_dump), the slave SQL thread (reads the event
1163  from the relay log). If mutex is 0, the read will proceed without
1164  mutex. We need the description_event to be able to parse the
1165  event (to know the post-header's size); in fact in read_log_event
1166  we detect the event's type, then call the specific event's
1167  constructor and pass description_event as an argument.
1168  */
1169  static Log_event* read_log_event(IO_CACHE* file,
1170  mysql_mutex_t* log_lock,
1172  *description_event,
1173  my_bool crc_check);
1174 
1199  static int read_log_event(IO_CACHE* file, String* packet,
1200  mysql_mutex_t* log_lock,
1201  uint8 checksum_alg_arg,
1202  const char *log_file_name_arg= NULL,
1203  bool* is_binlog_active= NULL);
1204  /*
1205  init_show_field_list() prepares the column names and types for the
1206  output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
1207  EVENTS.
1208  */
1209  static void init_show_field_list(List<Item>* field_list);
1210 #ifdef HAVE_REPLICATION
1211  int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
1212 
1220  virtual int pack_info(Protocol *protocol);
1221 
1222 #endif /* HAVE_REPLICATION */
1223  virtual const char* get_db()
1224  {
1225  return thd ? thd->db : 0;
1226  }
1227 #else // ifdef MYSQL_SERVER
1228  Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE,
1229  enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING)
1230  : temp_buf(0), flags(0), event_cache_type(cache_type_arg),
1231  event_logging_type(logging_type_arg)
1232  { }
1233  /* avoid having to link mysqlbinlog against libpthread */
1234  static Log_event* read_log_event(IO_CACHE* file,
1236  *description_event, my_bool crc_check);
1237  /* print*() functions are used by mysqlbinlog */
1238  virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
1239  void print_timestamp(IO_CACHE* file, time_t* ts);
1240  void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
1241  bool is_more);
1242  void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
1243  bool is_more);
1244 #endif // ifdef MYSQL_SERVER ... else
1245  /*
1246  The value is set by caller of FD constructor and
1247  Log_event::write_header() for the rest.
1248  In the FD case it's propagated into the last byte
1249  of post_header_len[] at FD::write().
1250  On the slave side the value is assigned from post_header_len[last]
1251  of the last seen FD event.
1252  */
1253  uint8 checksum_alg;
1254 
1255  static void *operator new(size_t size)
1256  {
1257  return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
1258  }
1259 
1260  static void operator delete(void *ptr, size_t)
1261  {
1262  my_free(ptr);
1263  }
1264 
1265  /* Placement version of the above operators */
1266  static void *operator new(size_t, void* ptr) { return ptr; }
1267  static void operator delete(void*, void*) { }
1268  bool wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong data_length);
1269 
1270 #ifdef MYSQL_SERVER
1271  bool write_header(IO_CACHE* file, ulong data_length);
1272  bool write_footer(IO_CACHE* file);
1273  my_bool need_checksum();
1274 
1275  virtual bool write(IO_CACHE* file)
1276  {
1277  return(write_header(file, get_data_size()) ||
1278  write_data_header(file) ||
1279  write_data_body(file) ||
1280  write_footer(file));
1281  }
1282  virtual bool write_data_header(IO_CACHE* file)
1283  { return 0; }
1284  virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
1285  { return 0; }
1286  inline time_t get_time()
1287  {
1288  if (!when.tv_sec && !when.tv_usec) /* Not previously initialized */
1289  {
1290  THD *tmp_thd= thd ? thd : current_thd;
1291  if (tmp_thd)
1292  when= tmp_thd->start_time;
1293  else
1294  my_micro_time_to_timeval(my_micro_time(), &when);
1295  }
1296  return (time_t) when.tv_sec;
1297  }
1298 #endif
1299  virtual Log_event_type get_type_code() = 0;
1300  virtual bool is_valid() const = 0;
1301  void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
1302  void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
1303  bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
1304  bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
1305  bool is_ignorable_event() const { return flags & LOG_EVENT_IGNORABLE_F; }
1306  bool is_no_filter_event() const { return flags & LOG_EVENT_NO_FILTER_F; }
1307  inline bool is_using_trans_cache() const
1308  {
1309  return (event_cache_type == EVENT_TRANSACTIONAL_CACHE);
1310  }
1311  inline bool is_using_stmt_cache() const
1312  {
1313  return(event_cache_type == EVENT_STMT_CACHE);
1314  }
1315  inline bool is_using_immediate_logging() const
1316  {
1317  return(event_logging_type == EVENT_IMMEDIATE_LOGGING);
1318  }
1319  Log_event(const char* buf, const Format_description_log_event
1320  *description_event);
1321  virtual ~Log_event() { free_temp_buf();}
1322  void register_temp_buf(char* buf) { temp_buf = buf; }
1323  void free_temp_buf()
1324  {
1325  if (temp_buf)
1326  {
1327  my_free(temp_buf);
1328  temp_buf = 0;
1329  }
1330  }
1331  /*
1332  Get event length for simple events. For complicated events the length
1333  is calculated during write()
1334  */
1335  virtual int get_data_size() { return 0;}
1336  static Log_event* read_log_event(const char* buf, uint event_len,
1337  const char **error,
1339  *description_event, my_bool crc_check);
1343  static const char* get_type_str(Log_event_type type);
1347  const char* get_type_str();
1348 
1349  /* Return start of query time or current time */
1350 
1351 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
1352 
1353 private:
1354 
1355  /*
1356  possible decisions by get_mts_execution_mode().
1357  The execution mode can be PARALLEL or not (thereby sequential
1358  unless impossible at all). When it's sequential it further breaks into
1359  ASYNChronous and SYNChronous.
1360  */
1361  enum enum_mts_event_exec_mode
1362  {
1363  /*
1364  Event is run by a Worker.
1365  */
1366  EVENT_EXEC_PARALLEL,
1367  /*
1368  Event is run by Coordinator.
1369  */
1370  EVENT_EXEC_ASYNC,
1371  /*
1372  Event is run by Coordinator and requires synchronization with Workers.
1373  */
1374  EVENT_EXEC_SYNC,
1375  /*
1376  Event can't be executed neither by Workers nor Coordinator.
1377  */
1378  EVENT_EXEC_CAN_NOT
1379  };
1380 
1394  bool is_mts_sequential_exec()
1395  {
1396  return
1397  get_type_code() == START_EVENT_V3 ||
1398  get_type_code() == STOP_EVENT ||
1399  get_type_code() == ROTATE_EVENT ||
1400  get_type_code() == LOAD_EVENT ||
1401  get_type_code() == SLAVE_EVENT ||
1402  get_type_code() == CREATE_FILE_EVENT ||
1403  get_type_code() == DELETE_FILE_EVENT ||
1404  get_type_code() == NEW_LOAD_EVENT ||
1405  get_type_code() == EXEC_LOAD_EVENT ||
1406  get_type_code() == FORMAT_DESCRIPTION_EVENT||
1407 
1408  get_type_code() == INCIDENT_EVENT;
1409  }
1410 
1423  enum enum_mts_event_exec_mode get_mts_execution_mode(ulong slave_server_id,
1424  bool mts_in_group)
1425  {
1426  if ((get_type_code() == FORMAT_DESCRIPTION_EVENT &&
1427  ((server_id == (uint32) ::server_id) || (log_pos == 0))) ||
1428  (get_type_code() == ROTATE_EVENT &&
1429  ((server_id == (uint32) ::server_id) ||
1430  (log_pos == 0 /* very first fake Rotate (R_f) */
1431  && mts_in_group /* ignored event turned into R_f at slave stop */))))
1432  return EVENT_EXEC_ASYNC;
1433  else if (is_mts_sequential_exec())
1434  return EVENT_EXEC_SYNC;
1435  else
1436  return EVENT_EXEC_PARALLEL;
1437  }
1438 
1444  Slave_worker *get_slave_worker(Relay_log_info *rli);
1445 
1446  /*
1447  The method returns a list of updated by the event databases.
1448  Other than in the case of Query-log-event the list is just one item.
1449  */
1450  virtual List<char>* get_mts_dbs(MEM_ROOT *mem_root)
1451  {
1452  List<char> *res= new List<char>;
1453  res->push_back(strdup_root(mem_root, get_db()));
1454  return res;
1455  }
1456 
1457  /*
1458  Group of events can be marked to force its execution
1459  in isolation from any other Workers.
1460  Typically that is done for a transaction that contains
1461  a query accessing more than OVER_MAX_DBS_IN_EVENT_MTS databases.
1462  Factually that's a sequential mode where a Worker remains to
1463  be the applier.
1464  */
1465  virtual void set_mts_isolate_group()
1466  {
1467  DBUG_ASSERT(ends_group() ||
1468  get_type_code() == QUERY_EVENT ||
1469  get_type_code() == EXEC_LOAD_EVENT ||
1470  get_type_code() == EXECUTE_LOAD_QUERY_EVENT);
1472  }
1473 
1474 
1475 public:
1476 
1480  bool contains_partition_info(bool);
1481 
1482  /*
1483  @return the number of updated by the event databases.
1484 
1485  @note In other than Query-log-event case that's one.
1486  */
1487  virtual uint8 mts_number_dbs() { return 1; }
1488 
1494  bool is_mts_group_isolated() { return flags & LOG_EVENT_MTS_ISOLATE_F; }
1495 
1505  virtual bool starts_group() { return FALSE; }
1506 
1511  virtual bool ends_group() { return FALSE; }
1512 
1521  int apply_event(Relay_log_info *rli);
1522 
1531  int update_pos(Relay_log_info *rli)
1532  {
1533  return do_update_pos(rli);
1534  }
1535 
1542  enum_skip_reason shall_skip(Relay_log_info *rli)
1543  {
1544  return do_shall_skip(rli);
1545  }
1546 
1562  virtual int do_apply_event(Relay_log_info const *rli)
1563  {
1564  return 0; /* Default implementation does nothing */
1565  }
1566 
1567  virtual int do_apply_event_worker(Slave_worker *w);
1568 
1569 protected:
1570 
1588  enum_skip_reason continue_group(Relay_log_info *rli);
1589 
1613  virtual int do_update_pos(Relay_log_info *rli);
1614 
1615 
1645  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
1646 #endif
1647 };
1648 
1649 
1650 /*
1651  One class for each type of event.
1652  Two constructors for each class:
1653  - one to create the event for logging (when the server acts as a master),
1654  called after an update to the database is done,
1655  which accepts parameters like the query, the database, the options for LOAD
1656  DATA INFILE...
1657  - one to create the event from a packet (when the server acts as a slave),
1658  called before reproducing the update, which accepts parameters (like a
1659  buffer). Used to read from the master, from the relay log, and in
1660  mysqlbinlog. This constructor must be format-tolerant.
1661 */
1662 
2004 {
2005  LEX_STRING user;
2006  LEX_STRING host;
2007 protected:
2008  Log_event::Byte* data_buf;
2009 public:
2010  const char* query;
2011  const char* catalog;
2012  const char* db;
2013  /*
2014  If we already know the length of the query string
2015  we pass it with q_len, so we would not have to call strlen()
2016  otherwise, set it to 0, in which case, we compute it with strlen()
2017  */
2018  uint32 q_len;
2019  uint32 db_len;
2020  uint16 error_code;
2021  ulong thread_id;
2022  /*
2023  For events created by Query_log_event::do_apply_event (and
2024  Load_log_event::do_apply_event()) we need the *original* thread
2025  id, to be able to log the event with the original (=master's)
2026  thread id (fix for BUG#1686).
2027  */
2028  ulong slave_proxy_id;
2029 
2030  /*
2031  Binlog format 3 and 4 start to differ (as far as class members are
2032  concerned) from here.
2033  */
2034 
2035  uint catalog_len; // <= 255 char; 0 means uninited
2036 
2037  /*
2038  We want to be able to store a variable number of N-bit status vars:
2039  (generally N=32; but N=64 for SQL_MODE) a user may want to log the number
2040  of affected rows (for debugging) while another does not want to lose 4
2041  bytes in this.
2042  The storage on disk is the following:
2043  status_vars_len is part of the post-header,
2044  status_vars are in the variable-length part, after the post-header, before
2045  the db & query.
2046  status_vars on disk is a sequence of pairs (code, value) where 'code' means
2047  'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so
2048  its first byte is its length. For now the order of status vars is:
2049  flags2 - sql_mode - catalog - autoinc - charset
2050  We should add the same thing to Load_log_event, but in fact
2051  LOAD DATA INFILE is going to be logged with a new type of event (logging of
2052  the plain text query), so Load_log_event would be frozen, so no need. The
2053  new way of logging LOAD DATA INFILE would use a derived class of
2054  Query_log_event, so automatically benefit from the work already done for
2055  status variables in Query_log_event.
2056  */
2057  uint16 status_vars_len;
2058 
2059  /*
2060  'flags2' is a second set of flags (on top of those in Log_event), for
2061  session variables. These are thd->options which is & against a mask
2062  (OPTIONS_WRITTEN_TO_BIN_LOG).
2063  flags2_inited helps make a difference between flags2==0 (3.23 or 4.x
2064  master, we don't know flags2, so use the slave server's global options) and
2065  flags2==0 (5.0 master, we know this has a meaning of flags all down which
2066  must influence the query).
2067  */
2068  bool flags2_inited;
2069  bool sql_mode_inited;
2070  bool charset_inited;
2071 
2072  uint32 flags2;
2073  /* In connections sql_mode is 32 bits now but will be 64 bits soon */
2074  sql_mode_t sql_mode;
2075  ulong auto_increment_increment, auto_increment_offset;
2076  char charset[6];
2077  uint time_zone_len; /* 0 means uninited */
2078  const char *time_zone_str;
2079  uint lc_time_names_number; /* 0 means en_US */
2080  uint charset_database_number;
2081  /*
2082  map for tables that will be updated for a multi-table update query
2083  statement, for other query statements, this will be zero.
2084  */
2085  ulonglong table_map_for_update;
2086  /*
2087  Holds the original length of a Query_log_event that comes from a
2088  master of version < 5.0 (i.e., binlog_version < 4). When the IO
2089  thread writes the relay log, it augments the Query_log_event with a
2090  Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event
2091  length. This field is initialized to non-zero in the SQL thread when
2092  it reads this augmented event. SQL thread does not write
2093  Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog.
2094  */
2095  uint32 master_data_written;
2096  /*
2097  number of updated databases by the query and their names. This info
2098  is requested by both Coordinator and Worker.
2099  */
2100  uchar mts_accessed_dbs;
2101  char mts_accessed_db_names[MAX_DBS_IN_EVENT_MTS][NAME_LEN];
2102 
2103 #ifdef MYSQL_SERVER
2104 
2105  Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
2106  bool using_trans, bool immediate, bool suppress_use,
2107  int error, bool ignore_command= FALSE);
2108  const char* get_db() { return db; }
2109 
2114  virtual List<char>* get_mts_dbs(MEM_ROOT *mem_root)
2115  {
2116  List<char> *res= new (mem_root) List<char>;
2117  if (mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS)
2118  {
2119  // the empty string db name is special to indicate sequential applying
2120  mts_accessed_db_names[0][0]= 0;
2121  res->push_back((char*) mts_accessed_db_names[0]);
2122  }
2123  else
2124  {
2125  for (uchar i= 0; i < mts_accessed_dbs; i++)
2126  {
2127  char *db_name= mts_accessed_db_names[i];
2128 
2129  // Only default database is rewritten.
2130  if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
2131  {
2132  size_t dummy_len;
2133  const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
2134  // db_name != db_filtered means that db_name is rewritten.
2135  if (strcmp(db_name, db_filtered))
2136  db_name= (char*)db_filtered;
2137  }
2138 
2139  res->push_back(db_name);
2140  }
2141  }
2142  return res;
2143  }
2144 
2145  void attach_temp_tables_worker(THD*);
2146  void detach_temp_tables_worker(THD*);
2147 
2148  virtual uchar mts_number_dbs() { return mts_accessed_dbs; }
2149 
2150 #ifdef HAVE_REPLICATION
2151  int pack_info(Protocol* protocol);
2152 #endif /* HAVE_REPLICATION */
2153 #else
2154  void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
2155  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2156 #endif
2157 
2158  Query_log_event();
2159  Query_log_event(const char* buf, uint event_len,
2160  const Format_description_log_event *description_event,
2161  Log_event_type event_type);
2162  ~Query_log_event()
2163  {
2164  if (data_buf)
2165  my_free(data_buf);
2166  }
2167  Log_event_type get_type_code() { return QUERY_EVENT; }
2168 #ifdef MYSQL_SERVER
2169  bool write(IO_CACHE* file);
2170  virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
2171 #endif
2172  bool is_valid() const { return query != 0; }
2173 
2174  /*
2175  Returns number of bytes additionaly written to post header by derived
2176  events (so far it is only Execute_load_query event).
2177  */
2178  virtual ulong get_post_header_size_for_derived() { return 0; }
2179  /* Writes derived event-specific part of post header. */
2180 
2181 public: /* !!! Public in this patch to allow old usage */
2182 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2183  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
2184  virtual int do_apply_event(Relay_log_info const *rli);
2185  virtual int do_update_pos(Relay_log_info *rli);
2186 
2187  int do_apply_event(Relay_log_info const *rli,
2188  const char *query_arg,
2189  uint32 q_len_arg);
2190 #endif /* HAVE_REPLICATION */
2191  /*
2192  If true, the event always be applied by slave SQL thread or be printed by
2193  mysqlbinlog
2194  */
2195  bool is_trans_keyword()
2196  {
2197  /*
2198  Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO'
2199  queries input by user was written into log events directly.
2200  So the keywords can be written in both upper case and lower case
2201  together, strncasecmp is used to check both cases. they also could be
2202  binlogged with comments in the front of these keywords. for examples:
2203  / * bla bla * / SAVEPOINT a;
2204  / * bla bla * / ROLLBACK TO a;
2205  but we don't handle these cases and after the patch, both quiries are
2206  binlogged in upper case with no comments.
2207  */
2208  return !strncmp(query, "BEGIN", q_len) ||
2209  !strncmp(query, "COMMIT", q_len) ||
2210  !strncasecmp(query, "SAVEPOINT", 9) ||
2211  !strncasecmp(query, "ROLLBACK", 8);
2212  }
2218  bool starts_group() { return !strncmp(query, "BEGIN", q_len); }
2219  virtual bool ends_group()
2220  {
2221  return
2222  !strncmp(query, "COMMIT", q_len) ||
2223  (!strncasecmp(query, STRING_WITH_LEN("ROLLBACK"))
2224  && strncasecmp(query, STRING_WITH_LEN("ROLLBACK TO ")));
2225  }
2226 };
2227 
2228 
2429 {
2430 private:
2431 protected:
2432  int copy_log_event(const char *buf, ulong event_len,
2433  int body_offset,
2434  const Format_description_log_event* description_event);
2435 
2436 public:
2437  uint get_query_buffer_length();
2438  void print_query(bool need_db, const char *cs, char *buf, char **end,
2439  char **fn_start, char **fn_end);
2440  ulong thread_id;
2441  ulong slave_proxy_id;
2442  uint32 table_name_len;
2443  /*
2444  No need to have a catalog, as these events can only come from 4.x.
2445  TODO: this may become false if Dmitri pushes his new LOAD DATA INFILE in
2446  5.0 only (not in 4.x).
2447  */
2448  uint32 db_len;
2449  uint32 fname_len;
2450  uint32 num_fields;
2451  const char* fields;
2452  const uchar* field_lens;
2453  uint32 field_block_len;
2454 
2455  const char* table_name;
2456  const char* db;
2457  const char* fname;
2458  uint32 skip_lines;
2459  sql_ex_info sql_ex;
2460  bool local_fname;
2472 
2473  /* fname doesn't point to memory inside Log_event::temp_buf */
2474  void set_fname_outside_temp_buf(const char *afname, uint alen)
2475  {
2476  fname= afname;
2477  fname_len= alen;
2478  local_fname= TRUE;
2479  }
2480  /* fname doesn't point to memory inside Log_event::temp_buf */
2481  int check_fname_outside_temp_buf()
2482  {
2483  return local_fname;
2484  }
2485 
2486 #ifdef MYSQL_SERVER
2487  String field_lens_buf;
2488  String fields_buf;
2489 
2490  Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
2491  const char* table_name_arg,
2492  List<Item>& fields_arg,
2493  bool is_concurrent_arg,
2494  enum enum_duplicates handle_dup, bool ignore,
2495  bool using_trans);
2496  void set_fields(const char* db, List<Item> &fields_arg,
2497  Name_resolution_context *context);
2498  const char* get_db() { return db; }
2499 #ifdef HAVE_REPLICATION
2500  int pack_info(Protocol* protocol);
2501 #endif /* HAVE_REPLICATION */
2502 #else
2503  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2504  void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
2505 #endif
2506 
2507  /*
2508  Note that for all the events related to LOAD DATA (Load_log_event,
2509  Create_file/Append/Exec/Delete, we pass description_event; however as
2510  logging of LOAD DATA is going to be changed in 4.1 or 5.0, this is only used
2511  for the common_header_len (post_header_len will not be changed).
2512  */
2513  Load_log_event(const char* buf, uint event_len,
2514  const Format_description_log_event* description_event);
2515  ~Load_log_event()
2516  {}
2517  Log_event_type get_type_code()
2518  {
2519  return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
2520  }
2521 #ifdef MYSQL_SERVER
2522  bool write_data_header(IO_CACHE* file);
2523  bool write_data_body(IO_CACHE* file);
2524 #endif
2525  bool is_valid() const { return table_name != 0; }
2526  int get_data_size()
2527  {
2528  return (table_name_len + db_len + 2 + fname_len
2529  + LOAD_HEADER_LEN
2530  + sql_ex.data_size() + field_block_len + num_fields);
2531  }
2532 
2533 public: /* !!! Public in this patch to allow old usage */
2534 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2535  virtual int do_apply_event(Relay_log_info const* rli)
2536  {
2537  return do_apply_event(thd->slave_net,rli,0);
2538  }
2539 
2540  int do_apply_event(NET *net, Relay_log_info const *rli,
2541  bool use_rli_only_for_errors);
2542 #endif
2543 };
2544 
2545 extern char server_version[SERVER_VERSION_LENGTH];
2546 
2563 {
2564 public:
2565  /*
2566  If this event is at the start of the first binary log since server
2567  startup 'created' should be the timestamp when the event (and the
2568  binary log) was created. In the other case (i.e. this event is at
2569  the start of a binary log created by FLUSH LOGS or automatic
2570  rotation), 'created' should be 0. This "trick" is used by MySQL
2571  >=4.0.14 slaves to know whether they must drop stale temporary
2572  tables and whether they should abort unfinished transaction.
2573 
2574  Note that when 'created'!=0, it is always equal to the event's
2575  timestamp; indeed Start_log_event is written only in log.cc where
2576  the first constructor below is called, in which 'created' is set
2577  to 'when'. So in fact 'created' is a useless variable. When it is
2578  0 we can read the actual value from timestamp ('when') and when it
2579  is non-zero we can read the same value from timestamp
2580  ('when'). Conclusion:
2581  - we use timestamp to print when the binlog was created.
2582  - we use 'created' only to know if this is a first binlog or not.
2583  In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in
2584  3.23.57 does not print 'created the_date' if created was zero. This is now
2585  fixed.
2586  */
2587  time_t created;
2588  uint16 binlog_version;
2589  char server_version[ST_SERVER_VER_LEN];
2590  /*
2591  We set this to 1 if we don't want to have the created time in the log,
2592  which is the case when we rollover to a new log.
2593  */
2594  bool dont_set_created;
2595 
2596 #ifdef MYSQL_SERVER
2598 #ifdef HAVE_REPLICATION
2599  int pack_info(Protocol* protocol);
2600 #endif /* HAVE_REPLICATION */
2601 #else
2602  Start_log_event_v3() {}
2603  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2604 #endif
2605 
2606  Start_log_event_v3(const char* buf,
2607  const Format_description_log_event* description_event);
2608  ~Start_log_event_v3() {}
2609  Log_event_type get_type_code() { return START_EVENT_V3;}
2610 #ifdef MYSQL_SERVER
2611  bool write(IO_CACHE* file);
2612 #endif
2613  bool is_valid() const { return 1; }
2614  int get_data_size()
2615  {
2616  return START_V3_HEADER_LEN; //no variable-sized part
2617  }
2618 
2619 protected:
2620 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2621  virtual int do_apply_event(Relay_log_info const *rli);
2622  virtual enum_skip_reason do_shall_skip(Relay_log_info*)
2623  {
2624  /*
2625  Events from ourself should be skipped, but they should not
2626  decrease the slave skip counter.
2627  */
2628  if (this->server_id == ::server_id)
2630  else
2632  }
2633 #endif
2634 };
2635 
2636 
2648 {
2649 public:
2650  /*
2651  The size of the fixed header which _all_ events have
2652  (for binlogs written by this version, this is equal to
2653  LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT
2654  (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN).
2655  */
2656  uint8 common_header_len;
2657  uint8 number_of_event_types;
2658  /*
2659  The list of post-headers' lengths followed
2660  by the checksum alg decription byte
2661  */
2662  uint8 *post_header_len;
2663  uchar server_version_split[3];
2664  const uint8 *event_type_permutation;
2665 
2666  Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
2667  Format_description_log_event(const char* buf, uint event_len,
2669  *description_event);
2671  {
2672  my_free(post_header_len);
2673  }
2674  Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
2675 #ifdef MYSQL_SERVER
2676  bool write(IO_CACHE* file);
2677 #endif
2678  bool header_is_valid() const
2679  {
2680  return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
2681  LOG_EVENT_MINIMAL_HEADER_LEN)) &&
2682  (post_header_len != NULL));
2683  }
2684 
2685  bool version_is_valid() const
2686  {
2687  /* It is invalid only when all version numbers are 0 */
2688  return !(server_version_split[0] == 0 &&
2689  server_version_split[1] == 0 &&
2690  server_version_split[2] == 0);
2691  }
2692 
2693  bool is_valid() const
2694  {
2695  return header_is_valid() && version_is_valid();
2696  }
2697 
2698  int get_data_size()
2699  {
2700  /*
2701  The vector of post-header lengths is considered as part of the
2702  post-header, because in a given version it never changes (contrary to the
2703  query in a Query_log_event).
2704  */
2705  return FORMAT_DESCRIPTION_HEADER_LEN;
2706  }
2707 
2709  ulong get_version_product() const;
2710  bool is_version_before_checksum() const;
2711 protected:
2712 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2713  virtual int do_apply_event(Relay_log_info const *rli);
2714  virtual int do_update_pos(Relay_log_info *rli);
2715  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
2716 #endif
2717 };
2718 
2719 
2759 {
2760 public:
2761  ulonglong val;
2762  uchar type;
2763 
2764 #ifdef MYSQL_SERVER
2765  Intvar_log_event(THD* thd_arg, uchar type_arg, ulonglong val_arg,
2766  enum_event_cache_type cache_type_arg,
2767  enum_event_logging_type logging_type_arg)
2768  :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg),
2769  val(val_arg), type(type_arg) { }
2770 #ifdef HAVE_REPLICATION
2771  int pack_info(Protocol* protocol);
2772 #endif /* HAVE_REPLICATION */
2773 #else
2774  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2775 #endif
2776 
2777  Intvar_log_event(const char* buf,
2778  const Format_description_log_event *description_event);
2779  ~Intvar_log_event() {}
2780  Log_event_type get_type_code() { return INTVAR_EVENT;}
2781  const char* get_var_type_name();
2782  int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;}
2783 #ifdef MYSQL_SERVER
2784  bool write(IO_CACHE* file);
2785 #endif
2786  bool is_valid() const { return 1; }
2787 
2788 private:
2789 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2790  virtual int do_apply_event(Relay_log_info const *rli);
2791  virtual int do_update_pos(Relay_log_info *rli);
2792  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
2793 #endif
2794 };
2795 
2796 
2837 {
2838  public:
2839  ulonglong seed1;
2840  ulonglong seed2;
2841 
2842 #ifdef MYSQL_SERVER
2843  Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg,
2844  enum_event_cache_type cache_type_arg,
2845  enum_event_logging_type logging_type_arg)
2846  :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg),
2847  seed1(seed1_arg), seed2(seed2_arg) { }
2848 #ifdef HAVE_REPLICATION
2849  int pack_info(Protocol* protocol);
2850 #endif /* HAVE_REPLICATION */
2851 #else
2852  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2853 #endif
2854 
2855  Rand_log_event(const char* buf,
2856  const Format_description_log_event *description_event);
2857  ~Rand_log_event() {}
2858  Log_event_type get_type_code() { return RAND_EVENT;}
2859  int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
2860 #ifdef MYSQL_SERVER
2861  bool write(IO_CACHE* file);
2862 #endif
2863  bool is_valid() const { return 1; }
2864 
2865 private:
2866 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2867  virtual int do_apply_event(Relay_log_info const *rli);
2868  virtual int do_update_pos(Relay_log_info *rli);
2869  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
2870 #endif
2871 };
2872 
2881 #ifdef MYSQL_CLIENT
2882 typedef ulonglong my_xid; // this line is the same as in handler.h
2883 #endif
2884 
2886 {
2887  public:
2888  my_xid xid;
2889 
2890 #ifdef MYSQL_SERVER
2891  Xid_log_event(THD* thd_arg, my_xid x)
2892  : Log_event(thd_arg, 0,
2893  Log_event::EVENT_TRANSACTIONAL_CACHE,
2894  Log_event::EVENT_NORMAL_LOGGING),
2895  xid(x)
2896  { }
2897 #ifdef HAVE_REPLICATION
2898  int pack_info(Protocol* protocol);
2899 #endif /* HAVE_REPLICATION */
2900 #else
2901  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2902 #endif
2903 
2904  Xid_log_event(const char* buf,
2905  const Format_description_log_event *description_event);
2906  ~Xid_log_event() {}
2907  Log_event_type get_type_code() { return XID_EVENT;}
2908  int get_data_size() { return sizeof(xid); }
2909 #ifdef MYSQL_SERVER
2910  bool write(IO_CACHE* file);
2911 #endif
2912  bool is_valid() const { return 1; }
2913  virtual bool ends_group() { return TRUE; }
2914 private:
2915 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2916  virtual int do_apply_event(Relay_log_info const *rli);
2917  virtual int do_apply_event_worker(Slave_worker *rli);
2918  enum_skip_reason do_shall_skip(Relay_log_info *rli);
2919  bool do_commit(THD *thd);
2920 #endif
2921 };
2922 
2933 {
2934 public:
2935  enum {
2936  UNDEF_F= 0,
2937  UNSIGNED_F= 1
2938  };
2939  const char *name;
2940  uint name_len;
2941  char *val;
2942  ulong val_len;
2943  Item_result type;
2944  uint charset_number;
2945  bool is_null;
2946  uchar flags;
2947 #ifdef MYSQL_SERVER
2948  bool deferred;
2949  query_id_t query_id;
2950  User_var_log_event(THD* thd_arg, const char *name_arg, uint name_len_arg,
2951  char *val_arg, ulong val_len_arg, Item_result type_arg,
2952  uint charset_number_arg, uchar flags_arg,
2953  enum_event_cache_type cache_type_arg,
2954  enum_event_logging_type logging_type_arg)
2955  :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), name(name_arg),
2956  name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg),
2957  charset_number(charset_number_arg), flags(flags_arg), deferred(false)
2958  {
2959  is_null= !val;
2960  }
2961  int pack_info(Protocol* protocol);
2962 #else
2963  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
2964 #endif
2965 
2966  User_var_log_event(const char* buf, uint event_len,
2967  const Format_description_log_event *description_event);
2968  ~User_var_log_event() {}
2969  Log_event_type get_type_code() { return USER_VAR_EVENT;}
2970 #ifdef MYSQL_SERVER
2971  bool write(IO_CACHE* file);
2972  /*
2973  Getter and setter for deferred User-event.
2974  Returns true if the event is not applied directly
2975  and which case the applier adjusts execution path.
2976  */
2977  bool is_deferred() { return deferred; }
2978  /*
2979  In case of the deffered applying the variable instance is flagged
2980  and the parsing time query id is stored to be used at applying time.
2981  */
2982  void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
2983 #endif
2984  bool is_valid() const { return name != 0; }
2985 
2986 private:
2987 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
2988  virtual int do_apply_event(Relay_log_info const *rli);
2989  virtual int do_update_pos(Relay_log_info *rli);
2990  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
2991 #endif
2992 };
2993 
2994 
3004 {
3005 public:
3006 #ifdef MYSQL_SERVER
3008  {}
3009 #else
3010  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3011 #endif
3012 
3013  Stop_log_event(const char* buf,
3014  const Format_description_log_event *description_event):
3015  Log_event(buf, description_event)
3016  {}
3017  ~Stop_log_event() {}
3018  Log_event_type get_type_code() { return STOP_EVENT;}
3019  bool is_valid() const { return 1; }
3020 
3021 private:
3022 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3023  virtual int do_update_pos(Relay_log_info *rli);
3024  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli)
3025  {
3026  /*
3027  Events from ourself should be skipped, but they should not
3028  decrease the slave skip counter.
3029  */
3030  if (this->server_id == ::server_id)
3032  else
3034  }
3035 #endif
3036 };
3037 
3088 {
3089 public:
3090  enum {
3091  DUP_NAME= 2, // if constructor should dup the string argument
3092  RELAY_LOG=4 // rotate event for relay log
3093  };
3094  const char* new_log_ident;
3095  ulonglong pos;
3096  uint ident_len;
3097  uint flags;
3098 #ifdef MYSQL_SERVER
3099  Rotate_log_event(const char* new_log_ident_arg,
3100  uint ident_len_arg,
3101  ulonglong pos_arg, uint flags);
3102 #ifdef HAVE_REPLICATION
3103  int pack_info(Protocol* protocol);
3104 #endif /* HAVE_REPLICATION */
3105 #else
3106  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3107 #endif
3108 
3109  Rotate_log_event(const char* buf, uint event_len,
3110  const Format_description_log_event* description_event);
3111  ~Rotate_log_event()
3112  {
3113  if (flags & DUP_NAME)
3114  my_free((void*) new_log_ident);
3115  }
3116  Log_event_type get_type_code() { return ROTATE_EVENT;}
3117  int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
3118  bool is_valid() const { return new_log_ident != 0; }
3119 #ifdef MYSQL_SERVER
3120  bool write(IO_CACHE* file);
3121 #endif
3122 
3123 private:
3124 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3125  virtual int do_update_pos(Relay_log_info *rli);
3126  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
3127 #endif
3128 };
3129 
3130 
3131 /* the classes below are for the new LOAD DATA INFILE logging */
3132 
3140 {
3141 protected:
3142  /*
3143  Pretend we are Load event, so we can write out just
3144  our Load part - used on the slave when writing event out to
3145  SQL_LOAD-*.info file
3146  */
3147  bool fake_base;
3148 public:
3149  uchar* block;
3150  const char *event_buf;
3151  uint block_len;
3152  uint file_id;
3153  bool inited_from_old;
3154 
3155 #ifdef MYSQL_SERVER
3156  Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
3157  const char* table_name_arg,
3158  List<Item>& fields_arg,
3159  bool is_concurrent_arg,
3160  enum enum_duplicates handle_dup, bool ignore,
3161  uchar* block_arg, uint block_len_arg,
3162  bool using_trans);
3163 #ifdef HAVE_REPLICATION
3164  int pack_info(Protocol* protocol);
3165 #endif /* HAVE_REPLICATION */
3166 #else
3167  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3168  void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
3169  bool enable_local);
3170 #endif
3171 
3172  Create_file_log_event(const char* buf, uint event_len,
3173  const Format_description_log_event* description_event);
3175  {
3176  my_free((void*) event_buf);
3177  }
3178 
3179  Log_event_type get_type_code()
3180  {
3181  return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
3182  }
3183  int get_data_size()
3184  {
3185  return (fake_base ? Load_log_event::get_data_size() :
3186  Load_log_event::get_data_size() +
3187  4 + 1 + block_len);
3188  }
3189  bool is_valid() const { return inited_from_old || block != 0; }
3190 #ifdef MYSQL_SERVER
3191  bool write_data_header(IO_CACHE* file);
3192  bool write_data_body(IO_CACHE* file);
3193  /*
3194  Cut out Create_file extentions and
3195  write it as Load event - used on the slave
3196  */
3197  bool write_base(IO_CACHE* file);
3198 #endif
3199 
3200 private:
3201 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3202  virtual int do_apply_event(Relay_log_info const *rli);
3203 #endif
3204 };
3205 
3206 
3214 {
3215 public:
3216  uchar* block;
3217  uint block_len;
3218  uint file_id;
3219  /*
3220  'db' is filled when the event is created in mysql_load() (the
3221  event needs to have a 'db' member to be well filtered by
3222  binlog-*-db rules). 'db' is not written to the binlog (it's not
3223  used by Append_block_log_event::write()), so it can't be read in
3224  the Append_block_log_event(const char* buf, int event_len)
3225  constructor. In other words, 'db' is used only for filtering by
3226  binlog-*-db rules. Create_file_log_event is different: it's 'db'
3227  (which is inherited from Load_log_event) is written to the binlog
3228  and can be re-read.
3229  */
3230  const char* db;
3231 
3232 #ifdef MYSQL_SERVER
3233  Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
3234  uint block_len_arg, bool using_trans);
3235 #ifdef HAVE_REPLICATION
3236  int pack_info(Protocol* protocol);
3237  virtual int get_create_or_append() const;
3238 #endif /* HAVE_REPLICATION */
3239 #else
3240  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3241 #endif
3242 
3243  Append_block_log_event(const char* buf, uint event_len,
3245  *description_event);
3247  Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
3248  int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;}
3249  bool is_valid() const { return block != 0; }
3250 #ifdef MYSQL_SERVER
3251  bool write(IO_CACHE* file);
3252  const char* get_db() { return db; }
3253 #endif
3254 
3255 private:
3256 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3257  virtual int do_apply_event(Relay_log_info const *rli);
3258 #endif
3259 };
3260 
3261 
3269 {
3270 public:
3271  uint file_id;
3272  const char* db; /* see comment in Append_block_log_event */
3273 
3274 #ifdef MYSQL_SERVER
3275  Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
3276 #ifdef HAVE_REPLICATION
3277  int pack_info(Protocol* protocol);
3278 #endif /* HAVE_REPLICATION */
3279 #else
3280  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3281  void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
3282  bool enable_local);
3283 #endif
3284 
3285  Delete_file_log_event(const char* buf, uint event_len,
3286  const Format_description_log_event* description_event);
3287  ~Delete_file_log_event() {}
3288  Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
3289  int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
3290  bool is_valid() const { return file_id != 0; }
3291 #ifdef MYSQL_SERVER
3292  bool write(IO_CACHE* file);
3293  const char* get_db() { return db; }
3294 #endif
3295 
3296 private:
3297 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3298  virtual int do_apply_event(Relay_log_info const *rli);
3299 #endif
3300 };
3301 
3302 
3310 {
3311 public:
3312  uint file_id;
3313  const char* db; /* see comment in Append_block_log_event */
3314 
3315 #ifdef MYSQL_SERVER
3316  Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
3317 #ifdef HAVE_REPLICATION
3318  int pack_info(Protocol* protocol);
3319 #endif /* HAVE_REPLICATION */
3320 #else
3321  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3322 #endif
3323 
3324  Execute_load_log_event(const char* buf, uint event_len,
3326  *description_event);
3328  Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
3329  int get_data_size() { return EXEC_LOAD_HEADER_LEN ;}
3330  bool is_valid() const { return file_id != 0; }
3331 #ifdef MYSQL_SERVER
3332  bool write(IO_CACHE* file);
3333  const char* get_db() { return db; }
3334 #endif
3335 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3336  virtual uint8 mts_number_dbs() { return OVER_MAX_DBS_IN_EVENT_MTS; }
3337  virtual List<char>* get_mts_dbs(MEM_ROOT *mem_root)
3338  {
3339  List<char> *res= new List<char>;
3340  res->push_back(strdup_root(mem_root, ""));
3341  return res;
3342  }
3343 #endif
3344 
3345 private:
3346 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3347  virtual int do_apply_event(Relay_log_info const *rli);
3348 #endif
3349 };
3350 
3351 
3362 {
3363 public:
3364 #ifdef MYSQL_SERVER
3365  Begin_load_query_log_event(THD* thd_arg, const char *db_arg,
3366  uchar* block_arg, uint block_len_arg,
3367  bool using_trans);
3368 #ifdef HAVE_REPLICATION
3369  Begin_load_query_log_event(THD* thd);
3370  int get_create_or_append() const;
3371 #endif /* HAVE_REPLICATION */
3372 #endif
3373  Begin_load_query_log_event(const char* buf, uint event_len,
3375  *description_event);
3377  Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; }
3378 private:
3379 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3380  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
3381 #endif
3382 };
3383 
3384 
3385 /*
3386  Elements of this enum describe how LOAD DATA handles duplicates.
3387 */
3388 enum enum_load_dup_handling { LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE,
3389  LOAD_DUP_REPLACE };
3390 
3401 {
3402 public:
3403  uint file_id; // file_id of temporary file
3404  uint fn_pos_start; // pointer to the part of the query that should
3405  // be substituted
3406  uint fn_pos_end; // pointer to the end of this part of query
3407  /*
3408  We have to store type of duplicate handling explicitly, because
3409  for LOAD DATA it also depends on LOCAL option. And this part
3410  of query will be rewritten during replication so this information
3411  may be lost...
3412  */
3413  enum_load_dup_handling dup_handling;
3414 
3415 #ifdef MYSQL_SERVER
3416  Execute_load_query_log_event(THD* thd, const char* query_arg,
3417  ulong query_length, uint fn_pos_start_arg,
3418  uint fn_pos_end_arg,
3419  enum_load_dup_handling dup_handling_arg,
3420  bool using_trans, bool immediate,
3421  bool suppress_use, int errcode);
3422 #ifdef HAVE_REPLICATION
3423  int pack_info(Protocol* protocol);
3424 #endif /* HAVE_REPLICATION */
3425 #else
3426  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3427  /* Prints the query as LOAD DATA LOCAL and with rewritten filename */
3428  void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
3429  const char *local_fname);
3430 #endif
3431  Execute_load_query_log_event(const char* buf, uint event_len,
3433  *description_event);
3435 
3436  Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; }
3437  bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
3438 
3439  ulong get_post_header_size_for_derived();
3440 #ifdef MYSQL_SERVER
3441  bool write_post_header_for_derived(IO_CACHE* file);
3442 #endif
3443 
3444 private:
3445 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3446  virtual int do_apply_event(Relay_log_info const *rli);
3447 #endif
3448 };
3449 
3450 
3451 #ifdef MYSQL_CLIENT
3452 
3457 class Unknown_log_event: public Log_event
3458 {
3459 public:
3460  /*
3461  Even if this is an unknown event, we still pass description_event to
3462  Log_event's ctor, this way we can extract maximum information from the
3463  event's header (the unique ID for example).
3464  */
3465  Unknown_log_event(const char* buf,
3466  const Format_description_log_event *description_event):
3467  Log_event(buf, description_event)
3468  {}
3469  ~Unknown_log_event() {}
3470  void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
3471  Log_event_type get_type_code() { return UNKNOWN_EVENT;}
3472  bool is_valid() const { return 1; }
3473 };
3474 #endif
3475 char *str_to_hex(char *to, const char *from, uint len);
3476 
3792 {
3793 public:
3794  /* Constants */
3795  enum
3796  {
3797  TYPE_CODE = TABLE_MAP_EVENT
3798  };
3799 
3804  {
3806  ERR_OK = 0,
3811  };
3812 
3813  enum enum_flag
3814  {
3815  /*
3816  Nothing here right now, but the flags support is there in
3817  preparation for changes that are coming. Need to add a
3818  constant to make it compile under HP-UX: aCC does not like
3819  empty enumerations.
3820  */
3821  ENUM_FLAG_COUNT
3822  };
3823 
3824  typedef uint16 flag_set;
3825 
3826  /* Special constants representing sets of flags */
3827  enum
3828  {
3829  TM_NO_FLAGS = 0U,
3830  TM_BIT_LEN_EXACT_F = (1U << 0),
3831  TM_REFERRED_FK_DB_F = (1U << 1)
3832  };
3833 
3834  flag_set get_flags(flag_set flag) const { return m_flags & flag; }
3835 
3836 #ifdef MYSQL_SERVER
3837  Table_map_log_event(THD *thd, TABLE *tbl, const Table_id& tid,
3838  bool is_transactional);
3839 #endif
3840 #ifdef HAVE_REPLICATION
3841  Table_map_log_event(const char *buf, uint event_len,
3842  const Format_description_log_event *description_event);
3843 #endif
3844 
3846 
3847 #ifdef MYSQL_CLIENT
3848  table_def *create_table_def()
3849  {
3850  return new table_def(m_coltype, m_colcnt, m_field_metadata,
3851  m_field_metadata_size, m_null_bits, m_flags);
3852  }
3853 #endif
3854  const Table_id& get_table_id() const { return m_table_id; }
3855  const char *get_table_name() const { return m_tblnam; }
3856  const char *get_db_name() const { return m_dbnam; }
3857 
3858  virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
3859  virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
3860 
3861  virtual int get_data_size() { return (uint) m_data_size; }
3862 #ifdef MYSQL_SERVER
3863  virtual int save_field_metadata();
3864  virtual bool write_data_header(IO_CACHE *file);
3865  virtual bool write_data_body(IO_CACHE *file);
3866  virtual const char *get_db() { return m_dbnam; }
3867  virtual uint8 mts_number_dbs()
3868  {
3869  return get_flags(TM_REFERRED_FK_DB_F) ? OVER_MAX_DBS_IN_EVENT_MTS : 1;
3870  }
3871  virtual List<char>* get_mts_dbs(MEM_ROOT *mem_root)
3872  {
3873  List<char> *res= new List<char>;
3874  const char *db_name= get_db();
3875 
3876  if (!rpl_filter->is_rewrite_empty() && !get_flags(TM_REFERRED_FK_DB_F))
3877  {
3878  size_t dummy_len;
3879  const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
3880  // db_name != db_filtered means that db_name is rewritten.
3881  if (strcmp(db_name, db_filtered))
3882  db_name= db_filtered;
3883  }
3884 
3885  res->push_back(strdup_root(mem_root,
3886  get_flags(TM_REFERRED_FK_DB_F) ? "" : db_name));
3887  return res;
3888  }
3889 
3890 #endif
3891 
3892 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3893  virtual int pack_info(Protocol *protocol);
3894 #endif
3895 
3896 #ifdef MYSQL_CLIENT
3897  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
3898 #endif
3899 
3900 
3901 private:
3902 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
3903  virtual int do_apply_event(Relay_log_info const *rli);
3904  virtual int do_update_pos(Relay_log_info *rli);
3905  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
3906 #endif
3907 
3908 #ifdef MYSQL_SERVER
3909  TABLE *m_table;
3910 #endif
3911  char const *m_dbnam;
3912  size_t m_dblen;
3913  char const *m_tblnam;
3914  size_t m_tbllen;
3915  ulong m_colcnt;
3916  uchar *m_coltype;
3917 
3918  uchar *m_memory;
3919  Table_id m_table_id;
3920  flag_set m_flags;
3921 
3922  size_t m_data_size;
3923 
3924  uchar *m_field_metadata; // buffer for field metadata
3925  /*
3926  The size of field metadata buffer set by calling save_field_metadata()
3927  */
3928  ulong m_field_metadata_size;
3929  uchar *m_null_bits;
3930  uchar *m_meta_memory;
3931 };
3932 
3933 
3950 {
3951 public:
3952  enum row_lookup_mode {
3953  ROW_LOOKUP_UNDEFINED= 0,
3954  ROW_LOOKUP_NOT_NEEDED= 1,
3955  ROW_LOOKUP_INDEX_SCAN= 2,
3956  ROW_LOOKUP_TABLE_SCAN= 3,
3957  ROW_LOOKUP_HASH_SCAN= 4
3958  };
3959 
3964  {
3966  ERR_OK = 0,
3971  };
3972 
3973  /*
3974  These definitions allow you to combine the flags into an
3975  appropriate flag set using the normal bitwise operators. The
3976  implicit conversion from an enum-constant to an integer is
3977  accepted by the compiler, which is then used to set the real set
3978  of flags.
3979  */
3981  {
3982  /* Last event of a statement */
3983  STMT_END_F = (1U << 0),
3984 
3985  /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
3986  NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
3987 
3988  /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
3989  RELAXED_UNIQUE_CHECKS_F = (1U << 2),
3990 
3995  COMPLETE_ROWS_F = (1U << 3)
3996  };
3997 
3998  typedef uint16 flag_set;
3999 
4000  /* Special constants representing sets of flags */
4001  enum
4002  {
4003  RLE_NO_FLAGS = 0U
4004  };
4005 
4006  virtual ~Rows_log_event();
4007 
4008  void set_flags(flag_set flags_arg) { m_flags |= flags_arg; }
4009  void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
4010  flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
4011 
4012  Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */
4013  virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */
4014 
4015 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4016  virtual int pack_info(Protocol *protocol);
4017 #endif
4018 
4019 #ifdef MYSQL_CLIENT
4020  /* not for direct call, each derived has its own ::print() */
4021  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
4022  void print_verbose(IO_CACHE *file,
4023  PRINT_EVENT_INFO *print_event_info);
4024  size_t print_verbose_one_row(IO_CACHE *file, table_def *td,
4025  PRINT_EVENT_INFO *print_event_info,
4026  MY_BITMAP *cols_bitmap,
4027  const uchar *ptr, const uchar *prefix);
4028 #endif
4029 
4030 #ifdef MYSQL_SERVER
4031  int add_row_data(uchar *data, size_t length)
4032  {
4033  return do_add_row_data(data,length);
4034  }
4035 #endif
4036 
4037  /* Member functions to implement superclass interface */
4038  virtual int get_data_size();
4039 
4040  MY_BITMAP const *get_cols() const { return &m_cols; }
4041  MY_BITMAP const *get_cols_ai() const { return &m_cols_ai; }
4042  size_t get_width() const { return m_width; }
4043  const Table_id& get_table_id() const { return m_table_id; }
4044 
4045 #if defined(MYSQL_SERVER)
4046  /*
4047  This member function compares the table's read/write_set
4048  with this event's m_cols and m_cols_ai. Comparison takes
4049  into account what type of rows event is this: Delete, Write or
4050  Update, therefore it uses the correct m_cols[_ai] according
4051  to the event type code.
4052 
4053  Note that this member function should only be called for the
4054  following events:
4055  - Delete_rows_log_event
4056  - Write_rows_log_event
4057  - Update_rows_log_event
4058 
4059  @param[IN] table The table to compare this events bitmaps
4060  against.
4061 
4062  @return TRUE if sets match, FALSE otherwise. (following
4063  bitmap_cmp return logic).
4064 
4065  */
4066  virtual bool read_write_bitmaps_cmp(TABLE *table)
4067  {
4068  bool res= FALSE;
4069 
4070  switch (get_general_type_code())
4071  {
4072  case DELETE_ROWS_EVENT:
4073  res= bitmap_cmp(get_cols(), table->read_set);
4074  break;
4075  case UPDATE_ROWS_EVENT:
4076  res= (bitmap_cmp(get_cols(), table->read_set) &&
4077  bitmap_cmp(get_cols_ai(), table->write_set));
4078  break;
4079  case WRITE_ROWS_EVENT:
4080  res= bitmap_cmp(get_cols(), table->write_set);
4081  break;
4082  default:
4083  /*
4084  We should just compare bitmaps for Delete, Write
4085  or Update rows events.
4086  */
4087  DBUG_ASSERT(0);
4088  }
4089  return res;
4090  }
4091 #endif
4092 
4093 #ifdef MYSQL_SERVER
4094  virtual bool write_data_header(IO_CACHE *file);
4095  virtual bool write_data_body(IO_CACHE *file);
4096  virtual const char *get_db() { return m_table->s->db.str; }
4097 #endif
4098  /*
4099  Check that malloc() succeeded in allocating memory for the rows
4100  buffer and the COLS vector. Checking that an Update_rows_log_event
4101  is valid is done in the Update_rows_log_event::is_valid()
4102  function.
4103  */
4104  virtual bool is_valid() const
4105  {
4106  return m_rows_buf && m_cols.bitmap;
4107  }
4108 
4109  uint m_row_count; /* The number of rows added to the event */
4110 
4111  const uchar* get_extra_row_data() const { return m_extra_row_data; }
4112 
4113 protected:
4114  /*
4115  The constructors are protected since you're supposed to inherit
4116  this class, not create instances of this class.
4117  */
4118 #ifdef MYSQL_SERVER
4119  Rows_log_event(THD*, TABLE*, const Table_id& table_id,
4120  MY_BITMAP const *cols, bool is_transactional,
4121  Log_event_type event_type,
4122  const uchar* extra_row_info);
4123 #endif
4124  Rows_log_event(const char *row_data, uint event_len,
4125  const Format_description_log_event *description_event);
4126 
4127 #ifdef MYSQL_CLIENT
4128  void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
4129 #endif
4130 
4131 #ifdef MYSQL_SERVER
4132  virtual int do_add_row_data(uchar *data, size_t length);
4133 #endif
4134 
4135 #ifdef MYSQL_SERVER
4136  TABLE *m_table; /* The table the rows belong to */
4137 #endif
4138  Table_id m_table_id; /* Table ID */
4139  MY_BITMAP m_cols; /* Bitmap denoting columns available */
4140  ulong m_width; /* The width of the columns bitmap */
4141 #ifndef MYSQL_CLIENT
4142 
4147 
4153 #endif
4154  /*
4155  Bitmap for columns available in the after image, if present. These
4156  fields are only available for Update_rows events. Observe that the
4157  width of both the before image COLS vector and the after image
4158  COLS vector is the same: the number of columns of the table on the
4159  master.
4160  */
4161  MY_BITMAP m_cols_ai;
4162 
4163  ulong m_master_reclength; /* Length of record on master side */
4164 
4165  /* Bit buffers in the same memory as the class */
4166  uint32 m_bitbuf[128/(sizeof(uint32)*8)];
4167  uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)];
4168 
4169  uchar *m_rows_buf; /* The rows in packed format */
4170  uchar *m_rows_cur; /* One-after the end of the data */
4171  uchar *m_rows_end; /* One-after the end of the allocated space */
4172 
4173  flag_set m_flags; /* Flags for row-level events */
4174 
4175  Log_event_type m_type; /* Actual event type */
4176 
4177  uchar *m_extra_row_data; /* Pointer to extra row data if any */
4178  /* If non null, first byte is length */
4179 
4180  /* helper functions */
4181 
4182 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4183  const uchar *m_curr_row; /* Start of the row being processed */
4184  const uchar *m_curr_row_end; /* One-after the end of the current row */
4185  uchar *m_key; /* Buffer to keep key value during searches */
4186  uchar *last_hashed_key;
4187  uint m_key_index;
4188  List<uchar> m_distinct_key_list;
4190 
4191  // Unpack the current row into m_table->record[0]
4192  int unpack_current_row(const Relay_log_info *const rli,
4193  MY_BITMAP const *cols)
4194  {
4195  DBUG_ASSERT(m_table);
4196 
4197  ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT);
4198  int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
4199  &m_curr_row_end, &m_master_reclength);
4200  if (m_curr_row_end > m_rows_end)
4201  my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
4202  ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
4203  return result;
4204  }
4205 
4206  /*
4207  This member function is called when deciding the algorithm to be used to
4208  find the rows to be updated on the slave during row based replication.
4209  This this functions sets the m_rows_lookup_algorithm and also the
4210  m_key_index with the key index to be used if the algorithm is dependent on
4211  an index.
4212  */
4213  void decide_row_lookup_algorithm_and_key();
4214 
4215  /*
4216  Encapsulates the operations to be done before applying
4217  row event for update and delete.
4218  */
4219  int row_operations_scan_and_key_setup();
4220 
4221  /*
4222  Encapsulates the operations to be done after applying
4223  row event for update and delete.
4224  */
4225  int row_operations_scan_and_key_teardown(int error);
4226 
4227 #endif
4228 
4229 private:
4230 
4231 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4232  virtual int do_apply_event(Relay_log_info const *rli);
4233  virtual int do_update_pos(Relay_log_info *rli);
4234  virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
4235 
4236  /*
4237  Primitive to prepare for a sequence of row executions.
4238 
4239  DESCRIPTION
4240 
4241  Before doing a sequence of do_prepare_row() and do_exec_row()
4242  calls, this member function should be called to prepare for the
4243  entire sequence. Typically, this member function will allocate
4244  space for any buffers that are needed for the two member
4245  functions mentioned above.
4246 
4247  RETURN VALUE
4248 
4249  The member function will return 0 if all went OK, or a non-zero
4250  error code otherwise.
4251  */
4252  virtual
4253  int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
4254 
4255  /*
4256  Primitive to clean up after a sequence of row executions.
4257 
4258  DESCRIPTION
4259 
4260  After doing a sequence of do_prepare_row() and do_exec_row(),
4261  this member function should be called to clean up and release
4262  any allocated buffers.
4263 
4264  The error argument, if non-zero, indicates an error which happened during
4265  row processing before this function was called. In this case, even if
4266  function is successful, it should return the error code given in the argument.
4267  */
4268  virtual
4269  int do_after_row_operations(const Slave_reporting_capability *const log,
4270  int error) = 0;
4271 
4272  /*
4273  Primitive to do the actual execution necessary for a row.
4274 
4275  DESCRIPTION
4276  The member function will do the actual execution needed to handle a row.
4277  The row is located at m_curr_row. When the function returns,
4278  m_curr_row_end should point at the next row (one byte after the end
4279  of the current row).
4280 
4281  RETURN VALUE
4282  0 if execution succeeded, 1 if execution failed.
4283 
4284  */
4285  virtual int do_exec_row(const Relay_log_info *const rli) = 0;
4286 
4294  int handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err);
4295 
4304  void do_post_row_operations(Relay_log_info const *rli, int err);
4305 
4310  int do_apply_row(Relay_log_info const *rli);
4311 
4317  int do_index_scan_and_update(Relay_log_info const *rli);
4318 
4326  int do_hash_scan_and_update(Relay_log_info const *rli);
4327 
4334  int do_table_scan_and_update(Relay_log_info const *rli);
4335 
4341  int open_record_scan();
4342 
4349  int close_record_scan();
4350 
4363  int next_record_scan(bool first_read);
4364 
4371  int add_key_to_distinct_keyset();
4372 
4385  int do_hash_row(Relay_log_info const *rli);
4386 
4395  int do_scan_and_update(Relay_log_info const *rli);
4396 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
4397 
4398  friend class Old_rows_log_event;
4399 };
4400 
4411 {
4412 public:
4413  enum
4414  {
4415  /* Support interface to THD::binlog_prepare_pending_rows_event */
4416  TYPE_CODE = WRITE_ROWS_EVENT
4417  };
4418 
4419 #if defined(MYSQL_SERVER)
4420  Write_rows_log_event(THD*, TABLE*, const Table_id& table_id,
4421  bool is_transactional,
4422  const uchar* extra_row_info);
4423 #endif
4424 #ifdef HAVE_REPLICATION
4425  Write_rows_log_event(const char *buf, uint event_len,
4426  const Format_description_log_event *description_event);
4427 #endif
4428 #if defined(MYSQL_SERVER)
4429  static bool binlog_row_logging_function(THD *thd, TABLE *table,
4430  bool is_transactional,
4431  const uchar *before_record
4432  __attribute__((unused)),
4433  const uchar *after_record)
4434  {
4435  return thd->binlog_write_row(table, is_transactional,
4436  after_record, NULL);
4437  }
4438 #endif
4439 
4440 protected:
4441  int write_row(const Relay_log_info *const, const bool);
4442 
4443 private:
4444  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
4445 
4446 #ifdef MYSQL_CLIENT
4447  void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4448 #endif
4449 
4450 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4451  virtual int do_before_row_operations(const Slave_reporting_capability *const);
4452  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
4453  virtual int do_exec_row(const Relay_log_info *const);
4454 #endif
4455 };
4456 
4457 
4471 {
4472 public:
4473  enum
4474  {
4475  /* Support interface to THD::binlog_prepare_pending_rows_event */
4476  TYPE_CODE = UPDATE_ROWS_EVENT
4477  };
4478 
4479 #ifdef MYSQL_SERVER
4480  Update_rows_log_event(THD*, TABLE*, const Table_id& table_id,
4481  MY_BITMAP const *cols_bi,
4482  MY_BITMAP const *cols_ai,
4483  bool is_transactional,
4484  const uchar* extra_row_info);
4485 
4486  Update_rows_log_event(THD*, TABLE*, const Table_id& table_id,
4487  bool is_transactional,
4488  const uchar* extra_row_info);
4489 
4490  void init(MY_BITMAP const *cols);
4491 #endif
4492 
4493  virtual ~Update_rows_log_event();
4494 
4495 #ifdef HAVE_REPLICATION
4496  Update_rows_log_event(const char *buf, uint event_len,
4497  const Format_description_log_event *description_event);
4498 #endif
4499 
4500 #ifdef MYSQL_SERVER
4501  static bool binlog_row_logging_function(THD *thd, TABLE *table,
4502  bool is_transactional,
4503  const uchar *before_record,
4504  const uchar *after_record)
4505  {
4506  return thd->binlog_update_row(table, is_transactional,
4507  before_record, after_record, NULL);
4508  }
4509 #endif
4510 
4511  virtual bool is_valid() const
4512  {
4513  return Rows_log_event::is_valid() && m_cols_ai.bitmap;
4514  }
4515 
4516 protected:
4517  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
4518 
4519 #ifdef MYSQL_CLIENT
4520  void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4521 #endif
4522 
4523 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4524  virtual int do_before_row_operations(const Slave_reporting_capability *const);
4525  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
4526  virtual int do_exec_row(const Relay_log_info *const);
4527 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
4528 };
4529 
4551 {
4552 public:
4553  enum
4554  {
4555  /* Support interface to THD::binlog_prepare_pending_rows_event */
4556  TYPE_CODE = DELETE_ROWS_EVENT
4557  };
4558 
4559 #ifdef MYSQL_SERVER
4560  Delete_rows_log_event(THD*, TABLE*, const Table_id&,
4561  bool is_transactional, const uchar* extra_row_info);
4562 #endif
4563 #ifdef HAVE_REPLICATION
4564  Delete_rows_log_event(const char *buf, uint event_len,
4565  const Format_description_log_event *description_event);
4566 #endif
4567 #ifdef MYSQL_SERVER
4568  static bool binlog_row_logging_function(THD *thd, TABLE *table,
4569  bool is_transactional,
4570  const uchar *before_record,
4571  const uchar *after_record
4572  __attribute__((unused)))
4573  {
4574  return thd->binlog_delete_row(table, is_transactional,
4575  before_record, NULL);
4576  }
4577 #endif
4578 
4579 protected:
4580  virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
4581 
4582 #ifdef MYSQL_CLIENT
4583  void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4584 #endif
4585 
4586 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4587  virtual int do_before_row_operations(const Slave_reporting_capability *const);
4588  virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
4589  virtual int do_exec_row(const Relay_log_info *const);
4590 #endif
4591 };
4592 
4593 
4594 #include "log_event_old.h"
4595 
4633 public:
4634 #ifdef MYSQL_SERVER
4635  Incident_log_event(THD *thd_arg, Incident incident)
4636  : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, Log_event::EVENT_NO_CACHE,
4637  Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident)
4638  {
4639  DBUG_ENTER("Incident_log_event::Incident_log_event");
4640  DBUG_PRINT("enter", ("m_incident: %d", m_incident));
4641  m_message.str= NULL; /* Just as a precaution */
4642  m_message.length= 0;
4643  DBUG_VOID_RETURN;
4644  }
4645 
4646  Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg)
4647  : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F,
4648  Log_event::EVENT_NO_CACHE,
4649  Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident)
4650  {
4651  DBUG_ENTER("Incident_log_event::Incident_log_event");
4652  DBUG_PRINT("enter", ("m_incident: %d", m_incident));
4653  m_message.str= NULL;
4654  m_message.length= 0;
4655  if (!(m_message.str= (char*) my_malloc(msg.length+1, MYF(MY_WME))))
4656  {
4657  /* Mark this event invalid */
4658  m_incident= INCIDENT_NONE;
4659  DBUG_VOID_RETURN;
4660  }
4661  strmake(m_message.str, msg.str, msg.length);
4662  m_message.length= msg.length;
4663  DBUG_VOID_RETURN;
4664  }
4665 #endif
4666 
4667 #ifdef MYSQL_SERVER
4668  int pack_info(Protocol*);
4669 #endif
4670 
4671  Incident_log_event(const char *buf, uint event_len,
4672  const Format_description_log_event *descr_event);
4673 
4674  virtual ~Incident_log_event();
4675 
4676 #ifdef MYSQL_CLIENT
4677  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4678 #endif
4679 
4680 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4681  virtual int do_apply_event(Relay_log_info const *rli);
4682 #endif
4683 
4684  virtual bool write_data_header(IO_CACHE *file);
4685  virtual bool write_data_body(IO_CACHE *file);
4686 
4687  virtual Log_event_type get_type_code() { return INCIDENT_EVENT; }
4688 
4689  virtual bool is_valid() const
4690  {
4691  return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT;
4692  }
4693  virtual int get_data_size() {
4694  return INCIDENT_HEADER_LEN + 1 + (uint) m_message.length;
4695  }
4696 
4697 private:
4698  const char *description() const;
4699 
4700  Incident m_incident;
4701  LEX_STRING m_message;
4702 };
4703 
4704 
4723 public:
4724 #ifndef MYSQL_CLIENT
4725  Ignorable_log_event(THD *thd_arg)
4726  : Log_event(thd_arg, LOG_EVENT_IGNORABLE_F,
4727  Log_event::EVENT_STMT_CACHE,
4728  Log_event::EVENT_NORMAL_LOGGING)
4729  {
4730  DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
4731  DBUG_VOID_RETURN;
4732  }
4733 #endif
4734 
4735  Ignorable_log_event(const char *buf,
4736  const Format_description_log_event *descr_event);
4737  virtual ~Ignorable_log_event();
4738 
4739 #ifndef MYSQL_CLIENT
4740  int pack_info(Protocol*);
4741 #endif
4742 
4743 #ifdef MYSQL_CLIENT
4744  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4745 #endif
4746 
4747  virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; }
4748 
4749  virtual bool is_valid() const { return 1; }
4750 
4751  virtual int get_data_size() { return IGNORABLE_HEADER_LEN; }
4752 };
4753 
4754 
4756 public:
4757 #ifndef MYSQL_CLIENT
4758  Rows_query_log_event(THD *thd_arg, const char * query, ulong query_len)
4759  : Ignorable_log_event(thd_arg)
4760  {
4761  DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
4762  if (!(m_rows_query= (char*) my_malloc(query_len + 1, MYF(MY_WME))))
4763  return;
4764  my_snprintf(m_rows_query, query_len + 1, "%s", query);
4765  DBUG_PRINT("enter", ("%s", m_rows_query));
4766  DBUG_VOID_RETURN;
4767  }
4768 #endif
4769 
4770 #ifndef MYSQL_CLIENT
4771  int pack_info(Protocol*);
4772 #endif
4773 
4774  Rows_query_log_event(const char *buf, uint event_len,
4775  const Format_description_log_event *descr_event);
4776 
4777  virtual ~Rows_query_log_event();
4778 
4779 #ifdef MYSQL_CLIENT
4780  virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4781 #endif
4782  virtual bool write_data_body(IO_CACHE *file);
4783 
4784  virtual Log_event_type get_type_code() { return ROWS_QUERY_LOG_EVENT; }
4785 
4786  virtual int get_data_size()
4787  {
4788  return IGNORABLE_HEADER_LEN + 1 + (uint) strlen(m_rows_query);
4789  }
4790 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4791  virtual int do_apply_event(Relay_log_info const *rli);
4792 #endif
4793 
4794 private:
4795 
4796  char * m_rows_query;
4797 };
4798 
4799 
4800 
4801 static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
4802  FILE *file,
4803  bool flush_stream)
4804 {
4805  return
4806  my_b_copy_to_file(cache, file) ||
4807  (flush_stream ? (fflush(file) || ferror(file)) : 0) ||
4808  reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
4809 }
4810 
4811 #ifdef MYSQL_SERVER
4812 /*****************************************************************************
4813 
4814  Heartbeat Log Event class
4815 
4816  Replication event to ensure to slave that master is alive.
4817  The event is originated by master's dump thread and sent straight to
4818  slave without being logged. Slave itself does not store it in relay log
4819  but rather uses a data for immediate checks and throws away the event.
4820 
4821  Two members of the class log_ident and Log_event::log_pos comprise
4822  @see the event_coordinates instance. The coordinates that a heartbeat
4823  instance carries correspond to the last event master has sent from
4824  its binlog.
4825 
4826  ****************************************************************************/
4827 class Heartbeat_log_event: public Log_event
4828 {
4829 public:
4830  Heartbeat_log_event(const char* buf, uint event_len,
4831  const Format_description_log_event* description_event);
4832  Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; }
4833  bool is_valid() const
4834  {
4835  return (log_ident != NULL &&
4836  log_pos >= BIN_LOG_HEADER_SIZE);
4837  }
4838  const char * get_log_ident() { return log_ident; }
4839  uint get_ident_len() { return ident_len; }
4840 
4841 private:
4842  const char* log_ident;
4843  uint ident_len;
4844 };
4845 
4852 bool slave_execute_deferred_events(THD *thd);
4853 #endif
4854 
4855 int append_query_string(THD *thd, const CHARSET_INFO *csinfo,
4856  String const *from, String *to);
4857 bool event_checksum_test(uchar *buf, ulong event_len, uint8 alg);
4858 uint8 get_checksum_alg(const char* buf, ulong len);
4859 extern TYPELIB binlog_checksum_typelib;
4860 
4862 {
4863 public:
4864 #ifndef MYSQL_CLIENT
4865 
4869  Gtid_log_event(THD *thd_arg, bool using_trans,
4870  const Gtid_specification *spec= NULL);
4871 #endif
4872 
4873 #ifndef MYSQL_CLIENT
4874  int pack_info(Protocol*);
4875 #endif
4876 
4877  Gtid_log_event(const char *buffer, uint event_len,
4878  const Format_description_log_event *descr_event);
4879 
4880  virtual ~Gtid_log_event() {}
4881 
4882  Log_event_type get_type_code()
4883  {
4884  DBUG_ENTER("Gtid_log_event::get_type_code()");
4885  Log_event_type ret= (spec.type == ANONYMOUS_GROUP ?
4886  ANONYMOUS_GTID_LOG_EVENT : GTID_LOG_EVENT);
4887  DBUG_PRINT("info", ("code=%d=%s", ret, get_type_str(ret)));
4888  DBUG_RETURN(ret);
4889  }
4890 
4891  int get_data_size() { return POST_HEADER_LENGTH; }
4892 
4893 private:
4895  size_t to_string(char *buf) const;
4896 
4897 public:
4898 #ifdef MYSQL_CLIENT
4899  void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
4900 #endif
4901 #ifdef MYSQL_SERVER
4902  bool write_data_header(IO_CACHE *file);
4903 #endif
4904 
4905 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
4906  int do_apply_event(Relay_log_info const *rli);
4907  int do_update_pos(Relay_log_info *rli);
4908 #endif
4909 
4914  enum_group_type get_type() const { return spec.type; }
4915  bool is_valid() const { return true; }
4916 
4921  const rpl_sid* get_sid() const { return &sid; }
4937  rpl_sidno get_sidno(bool need_lock)
4938  {
4939  if (spec.gtid.sidno < 0)
4940  {
4941  if (need_lock)
4942  global_sid_lock->rdlock();
4943  else
4944  global_sid_lock->assert_some_lock();
4945  spec.gtid.sidno= global_sid_map->add_sid(sid);
4946  if (need_lock)
4947  global_sid_lock->unlock();
4948  }
4949  return spec.gtid.sidno;
4950  }
4961  rpl_sidno get_sidno(Sid_map *sid_map)
4962  {
4963  return sid_map->add_sid(sid);
4964  }
4966  rpl_gno get_gno() const { return spec.gtid.gno; }
4968  bool get_commit_flag() const { return commit_flag; }
4969 
4970 private:
4972  static const char *SET_STRING_PREFIX;
4974  static const size_t SET_STRING_PREFIX_LENGTH= 26;
4976  static const size_t MAX_SET_STRING_LENGTH= SET_STRING_PREFIX_LENGTH +
4977  rpl_sid::TEXT_LENGTH + 1 + MAX_GNO_TEXT_LENGTH + 1;
4978 
4980  static const int ENCODED_FLAG_LENGTH= 1;
4982  static const int ENCODED_SID_LENGTH= rpl_sid::BYTE_LENGTH;
4984  static const int ENCODED_GNO_LENGTH= 8;
4985 
4986 public:
4988  static const int POST_HEADER_LENGTH=
4989  ENCODED_FLAG_LENGTH + ENCODED_SID_LENGTH + ENCODED_GNO_LENGTH;
4990 
4991 private:
4996  Gtid_specification spec;
4998  rpl_sid sid;
5000  bool commit_flag;
5001 };
5002 
5003 
5005 {
5006 public:
5007 #ifndef MYSQL_CLIENT
5008  Previous_gtids_log_event(const Gtid_set *set);
5009 #endif
5010 
5011 #ifndef MYSQL_CLIENT
5012  int pack_info(Protocol*);
5013 #endif
5014 
5015  Previous_gtids_log_event(const char *buffer, uint event_len,
5016  const Format_description_log_event *descr_event);
5017  virtual ~Previous_gtids_log_event() {}
5018 
5019  Log_event_type get_type_code() { return PREVIOUS_GTIDS_LOG_EVENT; }
5020 
5021  bool is_valid() const { return buf != NULL; }
5022  int get_data_size() { return buf_size; }
5023 
5024 #ifdef MYSQL_CLIENT
5025  void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
5026 #endif
5027 #ifdef MYSQL_SERVER
5028  bool write(IO_CACHE* file)
5029  {
5030  if (DBUG_EVALUATE_IF("skip_writing_previous_gtids_log_event", 1, 0))
5031  {
5032  DBUG_PRINT("info", ("skip writing Previous_gtids_log_event because of debug option 'skip_writing_previous_gtids_log_event'"));
5033  return false;
5034  }
5035 
5036  if (DBUG_EVALUATE_IF("write_partial_previous_gtids_log_event", 1, 0))
5037  {
5038  DBUG_PRINT("info", ("writing partial Previous_gtids_log_event because of debug option 'write_partial_previous_gtids_log_event'"));
5039  return (Log_event::write_header(file, get_data_size()) ||
5040  Log_event::write_data_header(file));
5041  }
5042 
5043  return (Log_event::write_header(file, get_data_size()) ||
5044  Log_event::write_data_header(file) ||
5045  write_data_body(file) ||
5046  Log_event::write_footer(file));
5047  }
5048  bool write_data_body(IO_CACHE *file);
5049 #endif
5050 
5052  const uchar *get_buf() { return buf; }
5059  char *get_str(size_t *length,
5060  const Gtid_set::String_format *string_format) const;
5062  int add_to_set(Gtid_set *gtid_set) const;
5063 
5064 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
5065  int do_apply_event(Relay_log_info const *rli) { return 0; }
5066  int do_update_pos(Relay_log_info *rli);
5067 #endif
5068 
5069 private:
5070  int buf_size;
5071  const uchar *buf;
5072 };
5073 
5074 inline bool is_gtid_event(Log_event* evt)
5075 {
5076  return (evt->get_type_code() == GTID_LOG_EVENT ||
5077  evt->get_type_code() == ANONYMOUS_GTID_LOG_EVENT);
5078 }
5079 
5080 inline ulong version_product(const uchar* version_split)
5081 {
5082  return ((version_split[0] * 256 + version_split[1]) * 256
5083  + version_split[2]);
5084 }
5085 
5092 inline void do_server_version_split(char* version, uchar split_versions[3])
5093 {
5094  char *p= version, *r;
5095  ulong number;
5096  for (uint i= 0; i<=2; i++)
5097  {
5098  number= strtoul(p, &r, 10);
5099  /*
5100  It is an invalid version if any version number greater than 255 or
5101  first number is not followed by '.'.
5102  */
5103  if (number < 256 && (*r == '.' || i != 0))
5104  split_versions[i]= (uchar)number;
5105  else
5106  {
5107  split_versions[0]= 0;
5108  split_versions[1]= 0;
5109  split_versions[2]= 0;
5110  break;
5111  }
5112 
5113  p= r;
5114  if (*r == '.')
5115  p++; // skip the dot
5116  }
5117 }
5118 
5119 #ifdef MYSQL_SERVER
5120 /*
5121  This is an utility function that adds a quoted identifier into the a buffer.
5122  This also escapes any existance of the quote string inside the identifier.
5123  */
5124 size_t my_strmov_quoted_identifier(THD *thd, char *buffer,
5125  const char* identifier,
5126  uint length);
5127 #else
5128 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier);
5129 #endif
5130 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
5131  const char* identifier,
5132  uint length);
5133 
5138 #endif /* _log_event_h */