1 | /* Copyright (c) 2000, 2014, Oracle and/or its affiliates. |
2 | Copyright (c) 2009, 2017, MariaDB Corporation. |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | /** |
18 | @addtogroup Replication |
19 | @{ |
20 | |
21 | @file |
22 | |
23 | @brief Binary log event definitions. This includes generic code |
24 | common to all types of log events, as well as specific code for each |
25 | type of log event. |
26 | */ |
27 | |
28 | |
29 | #ifndef _log_event_h |
30 | #define _log_event_h |
31 | |
32 | #if defined(USE_PRAGMA_INTERFACE) && defined(MYSQL_SERVER) |
33 | #pragma interface /* gcc class implementation */ |
34 | #endif |
35 | |
36 | #include <my_bitmap.h> |
37 | #include "rpl_constants.h" |
38 | |
39 | #ifdef MYSQL_CLIENT |
40 | #include "sql_const.h" |
41 | #include "rpl_utility.h" |
42 | #include "hash.h" |
43 | #include "rpl_tblmap.h" |
44 | #include "sql_string.h" |
45 | #endif |
46 | |
47 | #ifdef MYSQL_SERVER |
48 | #include "rpl_record.h" |
49 | #include "rpl_reporting.h" |
50 | #include "sql_class.h" /* THD */ |
51 | #endif |
52 | |
53 | #include "rpl_gtid.h" |
54 | |
55 | /* Forward declarations */ |
56 | #ifndef MYSQL_CLIENT |
57 | class String; |
58 | #endif |
59 | |
60 | #define PREFIX_SQL_LOAD "SQL_LOAD-" |
61 | #define LONG_FIND_ROW_THRESHOLD 60 /* seconds */ |
62 | |
63 | /** |
64 | Either assert or return an error. |
65 | |
66 | In debug build, the condition will be checked, but in non-debug |
67 | builds, the error code given will be returned instead. |
68 | |
69 | @param COND Condition to check |
70 | @param ERRNO Error number to return in non-debug builds |
71 | */ |
72 | #ifdef DBUG_OFF |
73 | #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \ |
74 | do { if (!(COND)) return ERRNO; } while (0) |
75 | #else |
76 | #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \ |
77 | DBUG_ASSERT(COND) |
78 | #endif |
79 | |
80 | #define LOG_READ_EOF -1 |
81 | #define LOG_READ_BOGUS -2 |
82 | #define LOG_READ_IO -3 |
83 | #define LOG_READ_MEM -5 |
84 | #define LOG_READ_TRUNC -6 |
85 | #define LOG_READ_TOO_LARGE -7 |
86 | #define LOG_READ_CHECKSUM_FAILURE -8 |
87 | #define LOG_READ_DECRYPT -9 |
88 | |
89 | #define LOG_EVENT_OFFSET 4 |
90 | |
91 | /* |
92 | 3 is MySQL 4.x; 4 is MySQL 5.0.0. |
93 | Compared to version 3, version 4 has: |
94 | - a different Start_log_event, which includes info about the binary log |
95 | (sizes of headers); this info is included for better compatibility if the |
96 | master's MySQL version is different from the slave's. |
97 | - all events have a unique ID (the triplet (server_id, timestamp at server |
98 | start, other) to be sure an event is not executed more than once in a |
99 | multimaster setup, example: |
100 | M1 |
101 | / \ |
102 | v v |
103 | M2 M3 |
104 | \ / |
105 | v v |
106 | S |
107 | if a query is run on M1, it will arrive twice on S, so we need that S |
108 | remembers the last unique ID it has processed, to compare and know if the |
109 | event should be skipped or not. Example of ID: we already have the server id |
110 | (4 bytes), plus: |
111 | timestamp_when_the_master_started (4 bytes), a counter (a sequence number |
112 | which increments every time we write an event to the binlog) (3 bytes). |
113 | Q: how do we handle when the counter is overflowed and restarts from 0 ? |
114 | |
115 | - Query and Load (Create or Execute) events may have a more precise |
116 | timestamp (with microseconds), number of matched/affected/warnings rows |
117 | and fields of session variables: SQL_MODE, |
118 | FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and |
119 | charsets, the PASSWORD() version (old/new/...). |
120 | */ |
121 | #define BINLOG_VERSION 4 |
122 | |
123 | /* |
124 | We could have used SERVER_VERSION_LENGTH, but this introduces an |
125 | obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH |
126 | this would break the replication protocol |
127 | */ |
128 | #define ST_SERVER_VER_LEN 50 |
129 | |
130 | /* |
131 | These are flags and structs to handle all the LOAD DATA INFILE options (LINES |
132 | TERMINATED etc). |
133 | */ |
134 | |
135 | /* |
136 | These are flags and structs to handle all the LOAD DATA INFILE options (LINES |
137 | TERMINATED etc). |
138 | DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD |
139 | DATA). |
140 | */ |
141 | #define DUMPFILE_FLAG 0x1 |
142 | #define OPT_ENCLOSED_FLAG 0x2 |
143 | #define REPLACE_FLAG 0x4 |
144 | #define IGNORE_FLAG 0x8 |
145 | |
146 | #define FIELD_TERM_EMPTY 0x1 |
147 | #define ENCLOSED_EMPTY 0x2 |
148 | #define LINE_TERM_EMPTY 0x4 |
149 | #define LINE_START_EMPTY 0x8 |
150 | #define ESCAPED_EMPTY 0x10 |
151 | |
152 | #define NUM_LOAD_DELIM_STRS 5 |
153 | |
154 | /***************************************************************************** |
155 | |
156 | MySQL Binary Log |
157 | |
158 | This log consists of events. Each event has a fixed-length header, |
159 | possibly followed by a variable length data body. |
160 | |
161 | The data body consists of an optional fixed length segment (post-header) |
162 | and an optional variable length segment. |
163 | |
164 | See the #defines below for the format specifics. |
165 | |
166 | The events which really update data are Query_log_event, |
167 | Execute_load_query_log_event and old Load_log_event and |
168 | Execute_load_log_event events (Execute_load_query is used together with |
169 | Begin_load_query and Append_block events to replicate LOAD DATA INFILE. |
170 | Create_file/Append_block/Execute_load (which includes Load_log_event) |
171 | were used to replicate LOAD DATA before the 5.0.3). |
172 | |
173 | ****************************************************************************/ |
174 | |
175 | #define 19 /* the fixed header length */ |
176 | #define 13 /* the fixed header length in 3.23 */ |
177 | /* |
178 | Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer |
179 | header (it will for sure when we have the unique event's ID), but at least |
180 | the first 19 bytes are the same in 4.x and 5.0. So when we have the unique |
181 | event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but |
182 | LOG_EVENT_MINIMAL_HEADER_LEN will remain 19. |
183 | */ |
184 | #define 19 |
185 | |
186 | /* event-specific post-header sizes */ |
187 | // where 3.23, 4.x and 5.0 agree |
188 | #define (4 + 4 + 1 + 2) |
189 | // where 5.0 differs: 2 for len of N-bytes vars. |
190 | #define (QUERY_HEADER_MINIMAL_LEN + 2) |
191 | #define 0 |
192 | #define (4 + 4 + 4 + 1 +1 + 4) |
193 | #define 0 |
194 | #define (2 + ST_SERVER_VER_LEN + 4) |
195 | #define 8 // this is FROZEN (the Rotate post-header is frozen) |
196 | #define 0 |
197 | #define 4 |
198 | #define 4 |
199 | #define 4 |
200 | #define 4 |
201 | #define LOAD_HEADER_LEN |
202 | #define RAND_HEADER_LEN 0 |
203 | #define 0 |
204 | #define (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES) |
205 | #define 0 |
206 | #define APPEND_BLOCK_HEADER_LEN |
207 | #define 8 |
208 | #define 8 |
209 | #define (4 + 4 + 4 + 1) |
210 | #define (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN) |
211 | #define 2 |
212 | #define 0 |
213 | #define 0 |
214 | #define 10 |
215 | #define 0 |
216 | #define 4 |
217 | #define 19 |
218 | #define 4 |
219 | #define 0 |
220 | |
221 | /* |
222 | Max number of possible extra bytes in a replication event compared to a |
223 | packet (i.e. a query) sent from client to master; |
224 | First, an auxiliary log_event status vars estimation: |
225 | */ |
226 | #define MAX_SIZE_LOG_EVENT_STATUS (1 + 4 /* type, flags2 */ + \ |
227 | 1 + 8 /* type, sql_mode */ + \ |
228 | 1 + 1 + 255 /* type, length, catalog */ + \ |
229 | 1 + 4 /* type, auto_increment */ + \ |
230 | 1 + 6 /* type, charset */ + \ |
231 | 1 + 1 + 255 /* type, length, time_zone */ + \ |
232 | 1 + 2 /* type, lc_time_names_number */ + \ |
233 | 1 + 2 /* type, charset_database_number */ + \ |
234 | 1 + 8 /* type, table_map_for_update */ + \ |
235 | 1 + 4 /* type, master_data_written */ + \ |
236 | 1 + 3 /* type, sec_part of NOW() */ + \ |
237 | 1 + 16 + 1 + 60/* type, user_len, user, host_len, host */) |
238 | #define ( /* in order of Query_log_event::write */ \ |
239 | LOG_EVENT_HEADER_LEN + /* write_header */ \ |
240 | QUERY_HEADER_LEN + /* write_data */ \ |
241 | EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \ |
242 | MAX_SIZE_LOG_EVENT_STATUS + /* status */ \ |
243 | NAME_LEN + 1) |
244 | |
245 | /* |
246 | The new option is added to handle large packets that are sent from the master |
247 | to the slave. It is used to increase the thd(max_allowed) for both the |
248 | DUMP thread on the master and the SQL/IO thread on the slave. |
249 | */ |
250 | #define MAX_MAX_ALLOWED_PACKET (1024*1024*1024) |
251 | |
252 | /* |
253 | Event header offsets; |
254 | these point to places inside the fixed header. |
255 | */ |
256 | |
257 | #define EVENT_TYPE_OFFSET 4 |
258 | #define SERVER_ID_OFFSET 5 |
259 | #define EVENT_LEN_OFFSET 9 |
260 | #define LOG_POS_OFFSET 13 |
261 | #define FLAGS_OFFSET 17 |
262 | |
263 | /* start event post-header (for v3 and v4) */ |
264 | |
265 | #define ST_BINLOG_VER_OFFSET 0 |
266 | #define ST_SERVER_VER_OFFSET 2 |
267 | #define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN) |
268 | #define (ST_CREATED_OFFSET + 4) |
269 | |
270 | /* slave event post-header (this event is never written) */ |
271 | |
272 | #define SL_MASTER_PORT_OFFSET 8 |
273 | #define SL_MASTER_POS_OFFSET 0 |
274 | #define SL_MASTER_HOST_OFFSET 10 |
275 | |
276 | /* query event post-header */ |
277 | |
278 | #define Q_THREAD_ID_OFFSET 0 |
279 | #define Q_EXEC_TIME_OFFSET 4 |
280 | #define Q_DB_LEN_OFFSET 8 |
281 | #define Q_ERR_CODE_OFFSET 9 |
282 | #define Q_STATUS_VARS_LEN_OFFSET 11 |
283 | #define Q_DATA_OFFSET QUERY_HEADER_LEN |
284 | /* these are codes, not offsets; not more than 256 values (1 byte). */ |
285 | #define Q_FLAGS2_CODE 0 |
286 | #define Q_SQL_MODE_CODE 1 |
287 | /* |
288 | Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL |
289 | 5.0.x where 0<=x<=3. We have to keep it to be able to replicate these |
290 | old masters. |
291 | */ |
292 | #define Q_CATALOG_CODE 2 |
293 | #define Q_AUTO_INCREMENT 3 |
294 | #define Q_CHARSET_CODE 4 |
295 | #define Q_TIME_ZONE_CODE 5 |
296 | /* |
297 | Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL |
298 | 5.0.x where x>=4. Saves one byte in every Query_log_event in binlog, |
299 | compared to Q_CATALOG_CODE. The reason we didn't simply re-use |
300 | Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would |
301 | crash (segfault etc) because it would expect a 0 when there is none. |
302 | */ |
303 | #define Q_CATALOG_NZ_CODE 6 |
304 | |
305 | #define Q_LC_TIME_NAMES_CODE 7 |
306 | |
307 | #define Q_CHARSET_DATABASE_CODE 8 |
308 | |
309 | #define Q_TABLE_MAP_FOR_UPDATE_CODE 9 |
310 | |
311 | #define Q_MASTER_DATA_WRITTEN_CODE 10 |
312 | |
313 | #define Q_INVOKER 11 |
314 | |
315 | #define Q_HRNOW 128 |
316 | |
317 | /* Intvar event post-header */ |
318 | |
319 | /* Intvar event data */ |
320 | #define I_TYPE_OFFSET 0 |
321 | #define I_VAL_OFFSET 1 |
322 | |
323 | /* Rand event data */ |
324 | #define RAND_SEED1_OFFSET 0 |
325 | #define RAND_SEED2_OFFSET 8 |
326 | |
327 | /* User_var event data */ |
328 | #define UV_VAL_LEN_SIZE 4 |
329 | #define UV_VAL_IS_NULL 1 |
330 | #define UV_VAL_TYPE_SIZE 1 |
331 | #define UV_NAME_LEN_SIZE 4 |
332 | #define UV_CHARSET_NUMBER_SIZE 4 |
333 | |
334 | /* Load event post-header */ |
335 | #define L_THREAD_ID_OFFSET 0 |
336 | #define L_EXEC_TIME_OFFSET 4 |
337 | #define L_SKIP_LINES_OFFSET 8 |
338 | #define L_TBL_LEN_OFFSET 12 |
339 | #define L_DB_LEN_OFFSET 13 |
340 | #define L_NUM_FIELDS_OFFSET 14 |
341 | #define L_SQL_EX_OFFSET 18 |
342 | #define L_DATA_OFFSET LOAD_HEADER_LEN |
343 | |
344 | /* Rotate event post-header */ |
345 | #define R_POS_OFFSET 0 |
346 | #define R_IDENT_OFFSET 8 |
347 | |
348 | /* CF to DF handle LOAD DATA INFILE */ |
349 | |
350 | /* CF = "Create File" */ |
351 | #define CF_FILE_ID_OFFSET 0 |
352 | #define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN |
353 | |
354 | /* AB = "Append Block" */ |
355 | #define AB_FILE_ID_OFFSET 0 |
356 | #define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN |
357 | |
358 | /* EL = "Execute Load" */ |
359 | #define EL_FILE_ID_OFFSET 0 |
360 | |
361 | /* DF = "Delete File" */ |
362 | #define DF_FILE_ID_OFFSET 0 |
363 | |
364 | /* TM = "Table Map" */ |
365 | #define TM_MAPID_OFFSET 0 |
366 | #define TM_FLAGS_OFFSET 6 |
367 | |
368 | /* RW = "RoWs" */ |
369 | #define RW_MAPID_OFFSET 0 |
370 | #define RW_FLAGS_OFFSET 6 |
371 | #define RW_VHLEN_OFFSET 8 |
372 | #define RW_V_TAG_LEN 1 |
373 | #define 0 |
374 | |
375 | /* ELQ = "Execute Load Query" */ |
376 | #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN |
377 | #define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4 |
378 | #define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8 |
379 | #define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12 |
380 | |
381 | /* 4 bytes which all binlogs should begin with */ |
382 | #define BINLOG_MAGIC (const uchar*) "\xfe\x62\x69\x6e" |
383 | |
384 | /* |
385 | The 2 flags below were useless : |
386 | - the first one was never set |
387 | - the second one was set in all Rotate events on the master, but not used for |
388 | anything useful. |
389 | So they are now removed and their place may later be reused for other |
390 | flags. Then one must remember that Rotate events in 4.x have |
391 | LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the |
392 | replacing flag when reading a Rotate event. |
393 | I keep the defines here just to remember what they were. |
394 | */ |
395 | #ifdef TO_BE_REMOVED |
396 | #define LOG_EVENT_TIME_F 0x1 |
397 | #define LOG_EVENT_FORCED_ROTATE_F 0x2 |
398 | #endif |
399 | |
400 | /* |
401 | This flag only makes sense for Format_description_log_event. It is set |
402 | when the event is written, and *reset* when a binlog file is |
403 | closed (yes, it's the only case when MySQL modifies already written |
404 | part of binlog). Thus it is a reliable indicator that binlog was |
405 | closed correctly. (Stop_log_event is not enough, there's always a |
406 | small chance that mysqld crashes in the middle of insert and end of |
407 | the binlog would look like a Stop_log_event). |
408 | |
409 | This flag is used to detect a restart after a crash, and to provide |
410 | "unbreakable" binlog. The problem is that on a crash storage engines |
411 | rollback automatically, while binlog does not. To solve this we use this |
412 | flag and automatically append ROLLBACK to every non-closed binlog (append |
413 | virtually, on reading, file itself is not changed). If this flag is found, |
414 | mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on |
415 | binlog corruption, but takes it as EOF, and replication slave forces a |
416 | rollback in this case. |
417 | |
418 | Note, that old binlogs does not have this flag set, so we get a |
419 | a backward-compatible behaviour. |
420 | */ |
421 | |
422 | #define LOG_EVENT_BINLOG_IN_USE_F 0x1 |
423 | |
424 | /** |
425 | @def LOG_EVENT_THREAD_SPECIFIC_F |
426 | |
427 | If the query depends on the thread (for example: TEMPORARY TABLE). |
428 | Currently this is used by mysqlbinlog to know it must print |
429 | SET @@PSEUDO_THREAD_ID=xx; before the query (it would not hurt to print it |
430 | for every query but this would be slow). |
431 | */ |
432 | #define LOG_EVENT_THREAD_SPECIFIC_F 0x4 |
433 | |
434 | /** |
435 | @def LOG_EVENT_SUPPRESS_USE_F |
436 | |
437 | Suppress the generation of 'USE' statements before the actual |
438 | statement. This flag should be set for any events that does not need |
439 | the current database set to function correctly. Most notable cases |
440 | are 'CREATE DATABASE' and 'DROP DATABASE'. |
441 | |
442 | This flags should only be used in exceptional circumstances, since |
443 | it introduce a significant change in behaviour regarding the |
444 | replication logic together with the flags --binlog-do-db and |
445 | --replicated-do-db. |
446 | */ |
447 | #define LOG_EVENT_SUPPRESS_USE_F 0x8 |
448 | |
449 | /* |
450 | Note: this is a place holder for the flag |
451 | LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any |
452 | more, please do not reused this value for other flags. |
453 | */ |
454 | |
455 | /** |
456 | @def LOG_EVENT_ARTIFICIAL_F |
457 | |
458 | Artificial events are created arbitarily and not written to binary |
459 | log |
460 | |
461 | These events should not update the master log position when slave |
462 | SQL thread executes them. |
463 | */ |
464 | #define LOG_EVENT_ARTIFICIAL_F 0x20 |
465 | |
466 | /** |
467 | @def LOG_EVENT_RELAY_LOG_F |
468 | |
469 | Events with this flag set are created by slave IO thread and written |
470 | to relay log |
471 | */ |
472 | #define LOG_EVENT_RELAY_LOG_F 0x40 |
473 | |
474 | /** |
475 | @def LOG_EVENT_IGNORABLE_F |
476 | |
477 | For an event, 'e', carrying a type code, that a slave, |
478 | 's', does not recognize, 's' will check 'e' for |
479 | LOG_EVENT_IGNORABLE_F, and if the flag is set, then 'e' |
480 | is ignored. Otherwise, 's' acknowledges that it has |
481 | found an unknown event in the relay log. |
482 | */ |
483 | #define LOG_EVENT_IGNORABLE_F 0x80 |
484 | |
485 | /** |
486 | @def LOG_EVENT_SKIP_REPLICATION_F |
487 | |
488 | Flag set by application creating the event (with @@skip_replication); the |
489 | slave will skip replication of such events if |
490 | --replicate-events-marked-for-skip is not set to REPLICATE. |
491 | |
492 | This is a MariaDB flag; we allocate it from the end of the available |
493 | values to reduce risk of conflict with new MySQL flags. |
494 | */ |
495 | #define LOG_EVENT_SKIP_REPLICATION_F 0x8000 |
496 | |
497 | |
498 | /** |
499 | @def OPTIONS_WRITTEN_TO_BIN_LOG |
500 | |
501 | OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must |
502 | be written to the binlog. OPTIONS_WRITTEN_TO_BIN_LOG could be |
503 | written into the Format_description_log_event, so that if later we |
504 | don't want to replicate a variable we did replicate, or the |
505 | contrary, it's doable. But it should not be too hard to decide once |
506 | for all of what we replicate and what we don't, among the fixed 32 |
507 | bits of thd->options. |
508 | |
509 | I (Guilhem) have read through every option's usage, and it looks |
510 | like OPTION_AUTO_IS_NULL and OPTION_NO_FOREIGN_KEYS are the only |
511 | ones which alter how the query modifies the table. It's good to |
512 | replicate OPTION_RELAXED_UNIQUE_CHECKS too because otherwise, the |
513 | slave may insert data slower than the master, in InnoDB. |
514 | OPTION_BIG_SELECTS is not needed (the slave thread runs with |
515 | max_join_size=HA_POS_ERROR) and OPTION_BIG_TABLES is not needed |
516 | either, as the manual says (because a too big in-memory temp table |
517 | is automatically written to disk). |
518 | */ |
519 | #define OPTIONS_WRITTEN_TO_BIN_LOG \ |
520 | (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \ |
521 | OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT) |
522 | |
523 | /* Shouldn't be defined before */ |
524 | #define EXPECTED_OPTIONS \ |
525 | ((1ULL << 14) | (1ULL << 26) | (1ULL << 27) | (1ULL << 19)) |
526 | |
527 | #if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS |
528 | #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values! |
529 | #endif |
530 | #undef EXPECTED_OPTIONS /* You shouldn't use this one */ |
531 | |
532 | #define CHECKSUM_CRC32_SIGNATURE_LEN 4 |
533 | /** |
534 | defined statically while there is just one alg implemented |
535 | */ |
536 | #define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN |
537 | #define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */ |
538 | |
539 | /* |
540 | These are capability numbers for MariaDB slave servers. |
541 | |
542 | Newer MariaDB slaves set this to inform the master about their capabilities. |
543 | This allows the master to decide which events it can send to the slave |
544 | without breaking replication on old slaves that maybe do not understand |
545 | all events from newer masters. |
546 | |
547 | As new releases are backwards compatible, a given capability implies also |
548 | all capabilities with smaller number. |
549 | |
550 | Older MariaDB slaves and other MySQL slave servers do not set this, so they |
551 | are recorded with capability 0. |
552 | */ |
553 | |
554 | /* MySQL or old MariaDB slave with no announced capability. */ |
555 | #define MARIA_SLAVE_CAPABILITY_UNKNOWN 0 |
556 | /* MariaDB >= 5.3, which understands ANNOTATE_ROWS_EVENT. */ |
557 | #define MARIA_SLAVE_CAPABILITY_ANNOTATE 1 |
558 | /* |
559 | MariaDB >= 5.5. This version has the capability to tolerate events omitted |
560 | from the binlog stream without breaking replication (MySQL slaves fail |
561 | because they mis-compute the offsets into the master's binlog). |
562 | */ |
563 | #define MARIA_SLAVE_CAPABILITY_TOLERATE_HOLES 2 |
564 | /* MariaDB >= 10.0, which knows about binlog_checkpoint_log_event. */ |
565 | #define MARIA_SLAVE_CAPABILITY_BINLOG_CHECKPOINT 3 |
566 | /* MariaDB >= 10.0.1, which knows about global transaction id events. */ |
567 | #define MARIA_SLAVE_CAPABILITY_GTID 4 |
568 | |
569 | /* Our capability. */ |
570 | #define MARIA_SLAVE_CAPABILITY_MINE MARIA_SLAVE_CAPABILITY_GTID |
571 | |
572 | |
573 | /** |
574 | @enum Log_event_type |
575 | |
576 | Enumeration type for the different types of log events. |
577 | */ |
578 | enum Log_event_type |
579 | { |
580 | /* |
581 | Every time you update this enum (when you add a type), you have to |
582 | fix Format_description_log_event::Format_description_log_event(). |
583 | */ |
584 | UNKNOWN_EVENT= 0, |
585 | START_EVENT_V3= 1, |
586 | QUERY_EVENT= 2, |
587 | STOP_EVENT= 3, |
588 | ROTATE_EVENT= 4, |
589 | INTVAR_EVENT= 5, |
590 | LOAD_EVENT= 6, |
591 | SLAVE_EVENT= 7, |
592 | CREATE_FILE_EVENT= 8, |
593 | APPEND_BLOCK_EVENT= 9, |
594 | EXEC_LOAD_EVENT= 10, |
595 | DELETE_FILE_EVENT= 11, |
596 | /* |
597 | NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer |
598 | sql_ex, allowing multibyte TERMINATED BY etc; both types share the |
599 | same class (Load_log_event) |
600 | */ |
601 | NEW_LOAD_EVENT= 12, |
602 | RAND_EVENT= 13, |
603 | USER_VAR_EVENT= 14, |
604 | FORMAT_DESCRIPTION_EVENT= 15, |
605 | XID_EVENT= 16, |
606 | BEGIN_LOAD_QUERY_EVENT= 17, |
607 | EXECUTE_LOAD_QUERY_EVENT= 18, |
608 | |
609 | TABLE_MAP_EVENT = 19, |
610 | |
611 | /* |
612 | These event numbers were used for 5.1.0 to 5.1.15 and are |
613 | therefore obsolete. |
614 | */ |
615 | PRE_GA_WRITE_ROWS_EVENT = 20, |
616 | PRE_GA_UPDATE_ROWS_EVENT = 21, |
617 | PRE_GA_DELETE_ROWS_EVENT = 22, |
618 | |
619 | /* |
620 | These event numbers are used from 5.1.16 until mysql-5.6.6, |
621 | and in MariaDB |
622 | */ |
623 | WRITE_ROWS_EVENT_V1 = 23, |
624 | UPDATE_ROWS_EVENT_V1 = 24, |
625 | DELETE_ROWS_EVENT_V1 = 25, |
626 | |
627 | /* |
628 | Something out of the ordinary happened on the master |
629 | */ |
630 | INCIDENT_EVENT= 26, |
631 | |
632 | /* |
633 | Heartbeat event to be send by master at its idle time |
634 | to ensure master's online status to slave |
635 | */ |
636 | HEARTBEAT_LOG_EVENT= 27, |
637 | |
638 | /* |
639 | In some situations, it is necessary to send over ignorable |
640 | data to the slave: data that a slave can handle in case there |
641 | is code for handling it, but which can be ignored if it is not |
642 | recognized. |
643 | |
644 | These mysql-5.6 events are not recognized (and ignored) by MariaDB |
645 | */ |
646 | IGNORABLE_LOG_EVENT= 28, |
647 | ROWS_QUERY_LOG_EVENT= 29, |
648 | |
649 | /* Version 2 of the Row events, generated only by mysql-5.6.6+ */ |
650 | WRITE_ROWS_EVENT = 30, |
651 | UPDATE_ROWS_EVENT = 31, |
652 | DELETE_ROWS_EVENT = 32, |
653 | |
654 | /* MySQL 5.6 GTID events, ignored by MariaDB */ |
655 | GTID_LOG_EVENT= 33, |
656 | ANONYMOUS_GTID_LOG_EVENT= 34, |
657 | PREVIOUS_GTIDS_LOG_EVENT= 35, |
658 | |
659 | /* MySQL 5.7 events, ignored by MariaDB */ |
660 | TRANSACTION_CONTEXT_EVENT= 36, |
661 | VIEW_CHANGE_EVENT= 37, |
662 | XA_PREPARE_LOG_EVENT= 38, |
663 | |
664 | /* |
665 | Add new events here - right above this comment! |
666 | Existing events (except ENUM_END_EVENT) should never change their numbers |
667 | */ |
668 | |
669 | /* New MySQL/Sun events are to be added right above this comment */ |
670 | MYSQL_EVENTS_END, |
671 | |
672 | MARIA_EVENTS_BEGIN= 160, |
673 | /* New Maria event numbers start from here */ |
674 | ANNOTATE_ROWS_EVENT= 160, |
675 | /* |
676 | Binlog checkpoint event. Used for XA crash recovery on the master, not used |
677 | in replication. |
678 | A binlog checkpoint event specifies a binlog file such that XA crash |
679 | recovery can start from that file - and it is guaranteed to find all XIDs |
680 | that are prepared in storage engines but not yet committed. |
681 | */ |
682 | BINLOG_CHECKPOINT_EVENT= 161, |
683 | /* |
684 | Gtid event. For global transaction ID, used to start a new event group, |
685 | instead of the old BEGIN query event, and also to mark stand-alone |
686 | events. |
687 | */ |
688 | GTID_EVENT= 162, |
689 | /* |
690 | Gtid list event. Logged at the start of every binlog, to record the |
691 | current replication state. This consists of the last GTID seen for |
692 | each replication domain. |
693 | */ |
694 | GTID_LIST_EVENT= 163, |
695 | |
696 | START_ENCRYPTION_EVENT= 164, |
697 | |
698 | /* |
699 | Compressed binlog event. |
700 | |
701 | Note that the order between WRITE/UPDATE/DELETE events is significant; |
702 | this is so that we can convert from the compressed to the uncompressed |
703 | event type with (type-WRITE_ROWS_COMPRESSED_EVENT + WRITE_ROWS_EVENT) |
704 | and similar for _V1. |
705 | */ |
706 | QUERY_COMPRESSED_EVENT = 165, |
707 | WRITE_ROWS_COMPRESSED_EVENT_V1 = 166, |
708 | UPDATE_ROWS_COMPRESSED_EVENT_V1 = 167, |
709 | DELETE_ROWS_COMPRESSED_EVENT_V1 = 168, |
710 | WRITE_ROWS_COMPRESSED_EVENT = 169, |
711 | UPDATE_ROWS_COMPRESSED_EVENT = 170, |
712 | DELETE_ROWS_COMPRESSED_EVENT = 171, |
713 | |
714 | /* Add new MariaDB events here - right above this comment! */ |
715 | |
716 | ENUM_END_EVENT /* end marker */ |
717 | }; |
718 | |
719 | |
720 | /* |
721 | Bit flags for what has been writting to cache. Used to |
722 | discard logs with table map events but not row events and |
723 | nothing else important. This is stored by cache. |
724 | */ |
725 | |
726 | enum enum_logged_status |
727 | { |
728 | LOGGED_TABLE_MAP= 1, |
729 | LOGGED_ROW_EVENT= 2, |
730 | LOGGED_NO_DATA= 4, |
731 | LOGGED_CRITICAL= 8 |
732 | }; |
733 | |
734 | static inline bool LOG_EVENT_IS_QUERY(enum Log_event_type type) |
735 | { |
736 | return type == QUERY_EVENT || type == QUERY_COMPRESSED_EVENT; |
737 | } |
738 | |
739 | |
740 | static inline bool LOG_EVENT_IS_WRITE_ROW(enum Log_event_type type) |
741 | { |
742 | return type == WRITE_ROWS_EVENT || type == WRITE_ROWS_EVENT_V1 || |
743 | type == WRITE_ROWS_COMPRESSED_EVENT || |
744 | type == WRITE_ROWS_COMPRESSED_EVENT_V1; |
745 | } |
746 | |
747 | |
748 | static inline bool LOG_EVENT_IS_UPDATE_ROW(enum Log_event_type type) |
749 | { |
750 | return type == UPDATE_ROWS_EVENT || type == UPDATE_ROWS_EVENT_V1 || |
751 | type == UPDATE_ROWS_COMPRESSED_EVENT || |
752 | type == UPDATE_ROWS_COMPRESSED_EVENT_V1; |
753 | } |
754 | |
755 | |
756 | static inline bool LOG_EVENT_IS_DELETE_ROW(enum Log_event_type type) |
757 | { |
758 | return type == DELETE_ROWS_EVENT || type == DELETE_ROWS_EVENT_V1 || |
759 | type == DELETE_ROWS_COMPRESSED_EVENT || |
760 | type == DELETE_ROWS_COMPRESSED_EVENT_V1; |
761 | } |
762 | |
763 | |
764 | static inline bool LOG_EVENT_IS_ROW_COMPRESSED(enum Log_event_type type) |
765 | { |
766 | return type == WRITE_ROWS_COMPRESSED_EVENT || |
767 | type == WRITE_ROWS_COMPRESSED_EVENT_V1 || |
768 | type == UPDATE_ROWS_COMPRESSED_EVENT || |
769 | type == UPDATE_ROWS_COMPRESSED_EVENT_V1 || |
770 | type == DELETE_ROWS_COMPRESSED_EVENT || |
771 | type == DELETE_ROWS_COMPRESSED_EVENT_V1; |
772 | } |
773 | |
774 | |
775 | static inline bool LOG_EVENT_IS_ROW_V2(enum Log_event_type type) |
776 | { |
777 | return (type >= WRITE_ROWS_EVENT && type <= DELETE_ROWS_EVENT) || |
778 | (type >= WRITE_ROWS_COMPRESSED_EVENT && type <= DELETE_ROWS_COMPRESSED_EVENT); |
779 | } |
780 | |
781 | |
782 | /* |
783 | The number of types we handle in Format_description_log_event (UNKNOWN_EVENT |
784 | is not to be handled, it does not exist in binlogs, it does not have a |
785 | format). |
786 | */ |
787 | #define LOG_EVENT_TYPES (ENUM_END_EVENT-1) |
788 | |
789 | enum Int_event_type |
790 | { |
791 | INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2 |
792 | }; |
793 | |
794 | |
795 | #ifdef MYSQL_SERVER |
796 | class String; |
797 | class MYSQL_BIN_LOG; |
798 | class THD; |
799 | #endif |
800 | |
801 | class Format_description_log_event; |
802 | class Relay_log_info; |
803 | class binlog_cache_data; |
804 | |
805 | bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, FILE *file); |
806 | |
807 | #ifdef MYSQL_CLIENT |
808 | enum enum_base64_output_mode { |
809 | BASE64_OUTPUT_NEVER= 0, |
810 | BASE64_OUTPUT_AUTO= 1, |
811 | BASE64_OUTPUT_ALWAYS= 2, |
812 | BASE64_OUTPUT_UNSPEC= 3, |
813 | BASE64_OUTPUT_DECODE_ROWS= 4, |
814 | /* insert new output modes here */ |
815 | BASE64_OUTPUT_MODE_COUNT |
816 | }; |
817 | |
818 | bool copy_event_cache_to_string_and_reinit(IO_CACHE *cache, LEX_STRING *to); |
819 | |
820 | /* |
821 | A structure for mysqlbinlog to know how to print events |
822 | |
823 | This structure is passed to the event's print() methods, |
824 | |
825 | There are two types of settings stored here: |
826 | 1. Last db, flags2, sql_mode etc comes from the last printed event. |
827 | They are stored so that only the necessary USE and SET commands |
828 | are printed. |
829 | 2. Other information on how to print the events, e.g. short_form, |
830 | hexdump_from. These are not dependent on the last event. |
831 | */ |
832 | typedef struct st_print_event_info |
833 | { |
834 | /* |
835 | Settings for database, sql_mode etc that comes from the last event |
836 | that was printed. We cache these so that we don't have to print |
837 | them if they are unchanged. |
838 | */ |
839 | char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is |
840 | char charset[6]; // 3 variables, each of them storable in 2 bytes |
841 | char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; |
842 | char delimiter[16]; |
843 | sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */ |
844 | my_thread_id thread_id; |
845 | ulonglong row_events; |
846 | ulong auto_increment_increment, auto_increment_offset; |
847 | uint lc_time_names_number; |
848 | uint charset_database_number; |
849 | uint verbose; |
850 | uint32 flags2; |
851 | uint32 server_id; |
852 | uint32 domain_id; |
853 | uint8 common_header_len; |
854 | enum_base64_output_mode base64_output_mode; |
855 | my_off_t hexdump_from; |
856 | |
857 | table_mapping m_table_map; |
858 | table_mapping m_table_map_ignored; |
859 | bool flags2_inited; |
860 | bool sql_mode_inited; |
861 | bool charset_inited; |
862 | bool thread_id_printed; |
863 | bool server_id_printed; |
864 | bool domain_id_printed; |
865 | bool allow_parallel; |
866 | bool allow_parallel_printed; |
867 | bool found_row_event; |
868 | bool print_row_count; |
869 | /* Settings on how to print the events */ |
870 | bool short_form; |
871 | /* |
872 | This is set whenever a Format_description_event is printed. |
873 | Later, when an event is printed in base64, this flag is tested: if |
874 | no Format_description_event has been seen, it is unsafe to print |
875 | the base64 event, so an error message is generated. |
876 | */ |
877 | bool printed_fd_event; |
878 | /* |
879 | Track when @@skip_replication changes so we need to output a SET |
880 | statement for it. |
881 | */ |
882 | bool skip_replication; |
883 | |
884 | /* |
885 | These two caches are used by the row-based replication events to |
886 | collect the header information and the main body of the events |
887 | making up a statement. |
888 | */ |
889 | IO_CACHE head_cache; |
890 | IO_CACHE body_cache; |
891 | #ifdef WHEN_FLASHBACK_REVIEW_READY |
892 | /* Storing the SQL for reviewing */ |
893 | IO_CACHE review_sql_cache; |
894 | #endif |
895 | FILE *file; |
896 | st_print_event_info(); |
897 | |
898 | ~st_print_event_info() { |
899 | close_cached_file(&head_cache); |
900 | close_cached_file(&body_cache); |
901 | #ifdef WHEN_FLASHBACK_REVIEW_READY |
902 | close_cached_file(&review_sql_cache); |
903 | #endif |
904 | } |
905 | bool init_ok() /* tells if construction was successful */ |
906 | { return my_b_inited(&head_cache) && my_b_inited(&body_cache) |
907 | #ifdef WHEN_FLASHBACK_REVIEW_READY |
908 | && my_b_inited(&review_sql_cache) |
909 | #endif |
910 | ; } |
911 | void flush_for_error() |
912 | { |
913 | if (!copy_event_cache_to_file_and_reinit(&head_cache, file)) |
914 | copy_event_cache_to_file_and_reinit(&body_cache, file); |
915 | fflush(file); |
916 | } |
917 | } PRINT_EVENT_INFO; |
918 | #endif |
919 | |
920 | /** |
921 | This class encapsulates writing of Log_event objects to IO_CACHE. |
922 | Automatically calculates the checksum and encrypts the data, if necessary. |
923 | */ |
924 | |
925 | class Log_event_writer |
926 | { |
927 | public: |
928 | ulonglong bytes_written; |
929 | void *ctx; ///< Encryption context or 0 if no encryption is needed |
930 | uint checksum_len; |
931 | int write(Log_event *ev); |
932 | int (uchar *pos, size_t len); |
933 | int write_data(const uchar *pos, size_t len); |
934 | int (); |
935 | my_off_t pos() { return my_b_safe_tell(file); } |
936 | void add_status(enum_logged_status status); |
937 | |
938 | Log_event_writer(IO_CACHE *file_arg, binlog_cache_data *cache_data_arg, |
939 | Binlog_crypt_data *cr= 0) |
940 | : bytes_written(0), ctx(0), |
941 | file(file_arg), cache_data(cache_data_arg), crypto(cr) { } |
942 | |
943 | private: |
944 | IO_CACHE *file; |
945 | binlog_cache_data *cache_data; |
946 | /** |
947 | Placeholder for event checksum while writing to binlog. |
948 | */ |
949 | ha_checksum crc; |
950 | /** |
951 | Encryption data (key, nonce). Only used if ctx != 0. |
952 | */ |
953 | Binlog_crypt_data *crypto; |
954 | /** |
955 | Event length to be written into the next encrypted block |
956 | */ |
957 | uint event_len; |
958 | int write_internal(const uchar *pos, size_t len); |
959 | int encrypt_and_write(const uchar *pos, size_t len); |
960 | int maybe_write_event_len(uchar *pos, size_t len); |
961 | }; |
962 | |
963 | /** |
964 | the struct aggregates two paramenters that identify an event |
965 | uniquely in scope of communication of a particular master and slave couple. |
966 | I.e there can not be 2 events from the same staying connected master which |
967 | have the same coordinates. |
968 | @note |
969 | Such identifier is not yet unique generally as the event originating master |
970 | is resetable. Also the crashed master can be replaced with some other. |
971 | */ |
972 | typedef struct event_coordinates |
973 | { |
974 | char * file_name; // binlog file name (directories stripped) |
975 | my_off_t pos; // event's position in the binlog file |
976 | } LOG_POS_COORD; |
977 | |
978 | /** |
979 | @class Log_event |
980 | |
981 | This is the abstract base class for binary log events. |
982 | |
983 | @section Log_event_binary_format Binary Format |
984 | |
985 | Any @c Log_event saved on disk consists of the following three |
986 | components. |
987 | |
988 | - Common-Header |
989 | - Post-Header |
990 | - Body |
991 | |
992 | The Common-Header, documented in the table @ref Table_common_header |
993 | "below", always has the same form and length within one version of |
994 | MySQL. Each event type specifies a format and length of the |
995 | Post-Header. The length of the Common-Header is the same for all |
996 | events of the same type. The Body may be of different format and |
997 | length even for different events of the same type. The binary |
998 | formats of Post-Header and Body are documented separately in each |
999 | subclass. The binary format of Common-Header is as follows. |
1000 | |
1001 | <table> |
1002 | <caption>Common-Header</caption> |
1003 | |
1004 | <tr> |
1005 | <th>Name</th> |
1006 | <th>Format</th> |
1007 | <th>Description</th> |
1008 | </tr> |
1009 | |
1010 | <tr> |
1011 | <td>timestamp</td> |
1012 | <td>4 byte unsigned integer</td> |
1013 | <td>The time when the query started, in seconds since 1970. |
1014 | </td> |
1015 | </tr> |
1016 | |
1017 | <tr> |
1018 | <td>type</td> |
1019 | <td>1 byte enumeration</td> |
1020 | <td>See enum #Log_event_type.</td> |
1021 | </tr> |
1022 | |
1023 | <tr> |
1024 | <td>server_id</td> |
1025 | <td>4 byte unsigned integer</td> |
1026 | <td>Server ID of the server that created the event.</td> |
1027 | </tr> |
1028 | |
1029 | <tr> |
1030 | <td>total_size</td> |
1031 | <td>4 byte unsigned integer</td> |
1032 | <td>The total size of this event, in bytes. In other words, this |
1033 | is the sum of the sizes of Common-Header, Post-Header, and Body. |
1034 | </td> |
1035 | </tr> |
1036 | |
1037 | <tr> |
1038 | <td>master_position</td> |
1039 | <td>4 byte unsigned integer</td> |
1040 | <td>The position of the next event in the master binary log, in |
1041 | bytes from the beginning of the file. In a binlog that is not a |
1042 | relay log, this is just the position of the next event, in bytes |
1043 | from the beginning of the file. In a relay log, this is |
1044 | the position of the next event in the master's binlog. |
1045 | </td> |
1046 | </tr> |
1047 | |
1048 | <tr> |
1049 | <td>flags</td> |
1050 | <td>2 byte bitfield</td> |
1051 | <td>See Log_event::flags.</td> |
1052 | </tr> |
1053 | </table> |
1054 | |
1055 | Summing up the numbers above, we see that the total size of the |
1056 | common header is 19 bytes. |
1057 | |
1058 | @subsection Log_event_format_of_atomic_primitives Format of Atomic Primitives |
1059 | |
1060 | - All numbers, whether they are 16-, 24-, 32-, or 64-bit numbers, |
1061 | are stored in little endian, i.e., the least significant byte first, |
1062 | unless otherwise specified. |
1063 | |
1064 | @anchor packed_integer |
1065 | - Some events use a special format for efficient representation of |
1066 | unsigned integers, called Packed Integer. A Packed Integer has the |
1067 | capacity of storing up to 8-byte integers, while small integers |
1068 | still can use 1, 3, or 4 bytes. The value of the first byte |
1069 | determines how to read the number, according to the following table: |
1070 | |
1071 | <table> |
1072 | <caption>Format of Packed Integer</caption> |
1073 | |
1074 | <tr> |
1075 | <th>First byte</th> |
1076 | <th>Format</th> |
1077 | </tr> |
1078 | |
1079 | <tr> |
1080 | <td>0-250</td> |
1081 | <td>The first byte is the number (in the range 0-250), and no more |
1082 | bytes are used.</td> |
1083 | </tr> |
1084 | |
1085 | <tr> |
1086 | <td>252</td> |
1087 | <td>Two more bytes are used. The number is in the range |
1088 | 251-0xffff.</td> |
1089 | </tr> |
1090 | |
1091 | <tr> |
1092 | <td>253</td> |
1093 | <td>Three more bytes are used. The number is in the range |
1094 | 0xffff-0xffffff.</td> |
1095 | </tr> |
1096 | |
1097 | <tr> |
1098 | <td>254</td> |
1099 | <td>Eight more bytes are used. The number is in the range |
1100 | 0xffffff-0xffffffffffffffff.</td> |
1101 | </tr> |
1102 | |
1103 | </table> |
1104 | |
1105 | - Strings are stored in various formats. The format of each string |
1106 | is documented separately. |
1107 | */ |
1108 | class Log_event |
1109 | { |
1110 | public: |
1111 | /** |
1112 | Enumeration of what kinds of skipping (and non-skipping) that can |
1113 | occur when the slave executes an event. |
1114 | |
1115 | @see shall_skip |
1116 | @see do_shall_skip |
1117 | */ |
1118 | enum enum_skip_reason { |
1119 | /** |
1120 | Don't skip event. |
1121 | */ |
1122 | EVENT_SKIP_NOT, |
1123 | |
1124 | /** |
1125 | Skip event by ignoring it. |
1126 | |
1127 | This means that the slave skip counter will not be changed. |
1128 | */ |
1129 | EVENT_SKIP_IGNORE, |
1130 | |
1131 | /** |
1132 | Skip event and decrease skip counter. |
1133 | */ |
1134 | EVENT_SKIP_COUNT |
1135 | }; |
1136 | |
1137 | enum enum_event_cache_type |
1138 | { |
1139 | EVENT_INVALID_CACHE, |
1140 | /* |
1141 | If possible the event should use a non-transactional cache before |
1142 | being flushed to the binary log. This means that it must be flushed |
1143 | right after its correspondent statement is completed. |
1144 | */ |
1145 | EVENT_STMT_CACHE, |
1146 | /* |
1147 | The event should use a transactional cache before being flushed to |
1148 | the binary log. This means that it must be flushed upon commit or |
1149 | rollback. |
1150 | */ |
1151 | EVENT_TRANSACTIONAL_CACHE, |
1152 | /* |
1153 | The event must be written directly to the binary log without going |
1154 | through a cache. |
1155 | */ |
1156 | EVENT_NO_CACHE, |
1157 | /** |
1158 | If there is a need for different types, introduce them before this. |
1159 | */ |
1160 | EVENT_CACHE_COUNT |
1161 | }; |
1162 | |
1163 | /* |
1164 | The following type definition is to be used whenever data is placed |
1165 | and manipulated in a common buffer. Use this typedef for buffers |
1166 | that contain data containing binary and character data. |
1167 | */ |
1168 | typedef unsigned char Byte; |
1169 | |
1170 | /* |
1171 | The offset in the log where this event originally appeared (it is |
1172 | preserved in relay logs, making SHOW SLAVE STATUS able to print |
1173 | coordinates of the event in the master's binlog). Note: when a |
1174 | transaction is written by the master to its binlog (wrapped in |
1175 | BEGIN/COMMIT) the log_pos of all the queries it contains is the |
1176 | one of the BEGIN (this way, when one does SHOW SLAVE STATUS it |
1177 | sees the offset of the BEGIN, which is logical as rollback may |
1178 | occur), except the COMMIT query which has its real offset. |
1179 | */ |
1180 | my_off_t log_pos; |
1181 | /* |
1182 | A temp buffer for read_log_event; it is later analysed according to the |
1183 | event's type, and its content is distributed in the event-specific fields. |
1184 | */ |
1185 | char *temp_buf; |
1186 | |
1187 | /* |
1188 | TRUE <=> this event 'owns' temp_buf and should call my_free() when done |
1189 | with it |
1190 | */ |
1191 | bool event_owns_temp_buf; |
1192 | |
1193 | /* |
1194 | Timestamp on the master(for debugging and replication of |
1195 | NOW()/TIMESTAMP). It is important for queries and LOAD DATA |
1196 | INFILE. This is set at the event's creation time, except for Query |
1197 | and Load (et al.) events where this is set at the query's |
1198 | execution time, which guarantees good replication (otherwise, we |
1199 | could have a query and its event with different timestamps). |
1200 | */ |
1201 | my_time_t when; |
1202 | ulong when_sec_part; |
1203 | /* The number of seconds the query took to run on the master. */ |
1204 | ulong exec_time; |
1205 | /* Number of bytes written by write() function */ |
1206 | size_t data_written; |
1207 | |
1208 | /* |
1209 | The master's server id (is preserved in the relay log; used to |
1210 | prevent from infinite loops in circular replication). |
1211 | */ |
1212 | uint32 server_id; |
1213 | |
1214 | /** |
1215 | Some 16 flags. See the definitions above for LOG_EVENT_TIME_F, |
1216 | LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F, |
1217 | LOG_EVENT_SUPPRESS_USE_F, and LOG_EVENT_SKIP_REPLICATION_F for notes. |
1218 | */ |
1219 | uint16 flags; |
1220 | |
1221 | uint16 cache_type; |
1222 | |
1223 | /** |
1224 | A storage to cache the global system variable's value. |
1225 | Handling of a separate event will be governed its member. |
1226 | */ |
1227 | ulong slave_exec_mode; |
1228 | |
1229 | Log_event_writer *writer; |
1230 | |
1231 | #ifdef MYSQL_SERVER |
1232 | THD* thd; |
1233 | |
1234 | Log_event(); |
1235 | Log_event(THD* thd_arg, uint16 flags_arg, bool is_transactional); |
1236 | |
1237 | /* |
1238 | init_show_field_list() prepares the column names and types for the |
1239 | output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG |
1240 | EVENTS. |
1241 | */ |
1242 | static void init_show_field_list(THD *thd, List<Item>* field_list); |
1243 | #ifdef HAVE_REPLICATION |
1244 | int net_send(Protocol *protocol, const char* log_name, my_off_t pos); |
1245 | |
1246 | /* |
1247 | pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends |
1248 | a string to display to the user, so it resembles print(). |
1249 | */ |
1250 | |
1251 | virtual void pack_info(Protocol *protocol); |
1252 | |
1253 | #endif /* HAVE_REPLICATION */ |
1254 | virtual const char* get_db() |
1255 | { |
1256 | return thd ? thd->db.str : 0; |
1257 | } |
1258 | #else |
1259 | Log_event() : temp_buf(0), when(0), flags(0) {} |
1260 | ha_checksum crc; |
1261 | /* print*() functions are used by mysqlbinlog */ |
1262 | virtual bool print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0; |
1263 | bool print_timestamp(IO_CACHE* file, time_t *ts = 0); |
1264 | bool print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, |
1265 | bool is_more); |
1266 | bool print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, |
1267 | bool is_more); |
1268 | #endif /* MYSQL_SERVER */ |
1269 | |
1270 | /* The following code used for Flashback */ |
1271 | #ifdef MYSQL_CLIENT |
1272 | my_bool is_flashback; |
1273 | my_bool need_flashback_review; |
1274 | String output_buf; // Storing the event output |
1275 | #ifdef WHEN_FLASHBACK_REVIEW_READY |
1276 | String m_review_dbname; |
1277 | String m_review_tablename; |
1278 | |
1279 | void set_review_dbname(const char *name) |
1280 | { |
1281 | if (name) |
1282 | { |
1283 | m_review_dbname.free(); |
1284 | m_review_dbname.append(name); |
1285 | } |
1286 | } |
1287 | void set_review_tablename(const char *name) |
1288 | { |
1289 | if (name) |
1290 | { |
1291 | m_review_tablename.free(); |
1292 | m_review_tablename.append(name); |
1293 | } |
1294 | } |
1295 | const char *get_review_dbname() const { return m_review_dbname.ptr(); } |
1296 | const char *get_review_tablename() const { return m_review_tablename.ptr(); } |
1297 | #endif |
1298 | #endif |
1299 | |
1300 | /* |
1301 | read_log_event() functions read an event from a binlog or relay |
1302 | log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the |
1303 | master (reads master's binlog), the slave IO thread (reads the |
1304 | event sent by binlog_dump), the slave SQL thread (reads the event |
1305 | from the relay log). If mutex is 0, the read will proceed without |
1306 | mutex. We need the description_event to be able to parse the |
1307 | event (to know the post-header's size); in fact in read_log_event |
1308 | we detect the event's type, then call the specific event's |
1309 | constructor and pass description_event as an argument. |
1310 | */ |
1311 | static Log_event* read_log_event(IO_CACHE* file, |
1312 | const Format_description_log_event |
1313 | *description_event, |
1314 | my_bool crc_check); |
1315 | |
1316 | /** |
1317 | Reads an event from a binlog or relay log. Used by the dump thread |
1318 | this method reads the event into a raw buffer without parsing it. |
1319 | |
1320 | @Note If mutex is 0, the read will proceed without mutex. |
1321 | |
1322 | @Note If a log name is given than the method will check if the |
1323 | given binlog is still active. |
1324 | |
1325 | @param[in] file log file to be read |
1326 | @param[out] packet packet to hold the event |
1327 | @param[in] checksum_alg_arg verify the event checksum using this |
1328 | algorithm (or don't if it's |
1329 | use BINLOG_CHECKSUM_ALG_OFF) |
1330 | |
1331 | @retval 0 success |
1332 | @retval LOG_READ_EOF end of file, nothing was read |
1333 | @retval LOG_READ_BOGUS malformed event |
1334 | @retval LOG_READ_IO io error while reading |
1335 | @retval LOG_READ_MEM packet memory allocation failed |
1336 | @retval LOG_READ_TRUNC only a partial event could be read |
1337 | @retval LOG_READ_TOO_LARGE event too large |
1338 | */ |
1339 | static int read_log_event(IO_CACHE* file, String* packet, |
1340 | const Format_description_log_event *fdle, |
1341 | enum enum_binlog_checksum_alg checksum_alg_arg); |
1342 | /* |
1343 | The value is set by caller of FD constructor and |
1344 | Log_event::write_header() for the rest. |
1345 | In the FD case it's propagated into the last byte |
1346 | of post_header_len[] at FD::write(). |
1347 | On the slave side the value is assigned from post_header_len[last] |
1348 | of the last seen FD event. |
1349 | */ |
1350 | enum enum_binlog_checksum_alg checksum_alg; |
1351 | |
1352 | static void *operator new(size_t size) |
1353 | { |
1354 | return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE)); |
1355 | } |
1356 | |
1357 | static void operator delete(void *ptr, size_t) |
1358 | { |
1359 | my_free(ptr); |
1360 | } |
1361 | |
1362 | /* Placement version of the above operators */ |
1363 | static void *operator new(size_t, void* ptr) { return ptr; } |
1364 | static void operator delete(void*, void*) { } |
1365 | |
1366 | #ifdef MYSQL_SERVER |
1367 | bool (size_t event_data_length); |
1368 | bool write_data(const uchar *buf, size_t data_length) |
1369 | { return writer->write_data(buf, data_length); } |
1370 | bool write_data(const char *buf, size_t data_length) |
1371 | { return write_data((uchar*)buf, data_length); } |
1372 | bool () |
1373 | { return writer->write_footer(); } |
1374 | |
1375 | my_bool need_checksum(); |
1376 | |
1377 | virtual bool write() |
1378 | { |
1379 | return write_header(get_data_size()) || write_data_header() || |
1380 | write_data_body() || write_footer(); |
1381 | } |
1382 | virtual bool () |
1383 | { return 0; } |
1384 | virtual bool write_data_body() |
1385 | { return 0; } |
1386 | |
1387 | /* Return start of query time or current time */ |
1388 | inline my_time_t get_time() |
1389 | { |
1390 | THD *tmp_thd; |
1391 | if (when) |
1392 | return when; |
1393 | if (thd) |
1394 | { |
1395 | when= thd->start_time; |
1396 | when_sec_part= thd->start_time_sec_part; |
1397 | return when; |
1398 | } |
1399 | /* thd will only be 0 here at time of log creation */ |
1400 | if ((tmp_thd= current_thd)) |
1401 | { |
1402 | when= tmp_thd->start_time; |
1403 | when_sec_part= tmp_thd->start_time_sec_part; |
1404 | return when; |
1405 | } |
1406 | my_hrtime_t hrtime= my_hrtime(); |
1407 | when= hrtime_to_my_time(hrtime); |
1408 | when_sec_part= hrtime_sec_part(hrtime); |
1409 | return when; |
1410 | } |
1411 | #endif |
1412 | virtual Log_event_type get_type_code() = 0; |
1413 | virtual enum_logged_status logged_status() { return LOGGED_CRITICAL; } |
1414 | virtual bool is_valid() const = 0; |
1415 | virtual my_off_t (my_off_t len) { return len; } |
1416 | void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; } |
1417 | void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; } |
1418 | bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; } |
1419 | bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; } |
1420 | inline bool use_trans_cache() const |
1421 | { |
1422 | return (cache_type == Log_event::EVENT_TRANSACTIONAL_CACHE); |
1423 | } |
1424 | inline void set_direct_logging() |
1425 | { |
1426 | cache_type = Log_event::EVENT_NO_CACHE; |
1427 | } |
1428 | inline bool use_direct_logging() |
1429 | { |
1430 | return (cache_type == Log_event::EVENT_NO_CACHE); |
1431 | } |
1432 | Log_event(const char* buf, const Format_description_log_event |
1433 | *description_event); |
1434 | virtual ~Log_event() { free_temp_buf();} |
1435 | void register_temp_buf(char* buf, bool must_free) |
1436 | { |
1437 | temp_buf= buf; |
1438 | event_owns_temp_buf= must_free; |
1439 | } |
1440 | void free_temp_buf() |
1441 | { |
1442 | if (temp_buf) |
1443 | { |
1444 | if (event_owns_temp_buf) |
1445 | my_free(temp_buf); |
1446 | temp_buf = 0; |
1447 | } |
1448 | } |
1449 | /* |
1450 | Get event length for simple events. For complicated events the length |
1451 | is calculated during write() |
1452 | */ |
1453 | virtual int get_data_size() { return 0;} |
1454 | static Log_event* read_log_event(const char* buf, uint event_len, |
1455 | const char **error, |
1456 | const Format_description_log_event |
1457 | *description_event, my_bool crc_check); |
1458 | /** |
1459 | Returns the human readable name of the given event type. |
1460 | */ |
1461 | static const char* get_type_str(Log_event_type type); |
1462 | /** |
1463 | Returns the human readable name of this event's type. |
1464 | */ |
1465 | const char* get_type_str(); |
1466 | |
1467 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
1468 | |
1469 | /** |
1470 | Apply the event to the database. |
1471 | |
1472 | This function represents the public interface for applying an |
1473 | event. |
1474 | |
1475 | @see do_apply_event |
1476 | */ |
1477 | int apply_event(rpl_group_info *rgi) |
1478 | { |
1479 | int res; |
1480 | THD_STAGE_INFO(thd, stage_apply_event); |
1481 | res= do_apply_event(rgi); |
1482 | THD_STAGE_INFO(thd, stage_after_apply_event); |
1483 | return res; |
1484 | } |
1485 | |
1486 | |
1487 | /** |
1488 | Update the relay log position. |
1489 | |
1490 | This function represents the public interface for "stepping over" |
1491 | the event and will update the relay log information. |
1492 | |
1493 | @see do_update_pos |
1494 | */ |
1495 | int update_pos(rpl_group_info *rgi) |
1496 | { |
1497 | return do_update_pos(rgi); |
1498 | } |
1499 | |
1500 | /** |
1501 | Decide if the event shall be skipped, and the reason for skipping |
1502 | it. |
1503 | |
1504 | @see do_shall_skip |
1505 | */ |
1506 | enum_skip_reason shall_skip(rpl_group_info *rgi) |
1507 | { |
1508 | return do_shall_skip(rgi); |
1509 | } |
1510 | |
1511 | |
1512 | /* |
1513 | Check if an event is non-final part of a stand-alone event group, |
1514 | such as Intvar_log_event (such events should be processed as part |
1515 | of the following event group, not individually). |
1516 | See also is_part_of_group() |
1517 | */ |
1518 | static bool is_part_of_group(enum Log_event_type ev_type) |
1519 | { |
1520 | switch (ev_type) |
1521 | { |
1522 | case GTID_EVENT: |
1523 | case INTVAR_EVENT: |
1524 | case RAND_EVENT: |
1525 | case USER_VAR_EVENT: |
1526 | case TABLE_MAP_EVENT: |
1527 | case ANNOTATE_ROWS_EVENT: |
1528 | return true; |
1529 | case DELETE_ROWS_EVENT: |
1530 | case UPDATE_ROWS_EVENT: |
1531 | case WRITE_ROWS_EVENT: |
1532 | /* |
1533 | ToDo: also check for non-final Rows_log_event (though such events |
1534 | are usually in a BEGIN-COMMIT group). |
1535 | */ |
1536 | default: |
1537 | return false; |
1538 | } |
1539 | } |
1540 | /* |
1541 | Same as above, but works on the object. In addition this is true for all |
1542 | rows event except the last one. |
1543 | */ |
1544 | virtual bool is_part_of_group() { return 0; } |
1545 | |
1546 | static bool is_group_event(enum Log_event_type ev_type) |
1547 | { |
1548 | switch (ev_type) |
1549 | { |
1550 | case START_EVENT_V3: |
1551 | case STOP_EVENT: |
1552 | case ROTATE_EVENT: |
1553 | case SLAVE_EVENT: |
1554 | case FORMAT_DESCRIPTION_EVENT: |
1555 | case INCIDENT_EVENT: |
1556 | case HEARTBEAT_LOG_EVENT: |
1557 | case BINLOG_CHECKPOINT_EVENT: |
1558 | case GTID_LIST_EVENT: |
1559 | case START_ENCRYPTION_EVENT: |
1560 | return false; |
1561 | |
1562 | default: |
1563 | return true; |
1564 | } |
1565 | } |
1566 | |
1567 | protected: |
1568 | |
1569 | /** |
1570 | Helper function to ignore an event w.r.t. the slave skip counter. |
1571 | |
1572 | This function can be used inside do_shall_skip() for functions |
1573 | that cannot end a group. If the slave skip counter is 1 when |
1574 | seeing such an event, the event shall be ignored, the counter |
1575 | left intact, and processing continue with the next event. |
1576 | |
1577 | A typical usage is: |
1578 | @code |
1579 | enum_skip_reason do_shall_skip(rpl_group_info *rgi) { |
1580 | return continue_group(rgi); |
1581 | } |
1582 | @endcode |
1583 | |
1584 | @return Skip reason |
1585 | */ |
1586 | enum_skip_reason continue_group(rpl_group_info *rgi); |
1587 | |
1588 | /** |
1589 | Primitive to apply an event to the database. |
1590 | |
1591 | This is where the change to the database is made. |
1592 | |
1593 | @note The primitive is protected instead of private, since there |
1594 | is a hierarchy of actions to be performed in some cases. |
1595 | |
1596 | @see Format_description_log_event::do_apply_event() |
1597 | |
1598 | @param rli Pointer to relay log info structure |
1599 | |
1600 | @retval 0 Event applied successfully |
1601 | @retval errno Error code if event application failed |
1602 | */ |
1603 | virtual int do_apply_event(rpl_group_info *rgi) |
1604 | { |
1605 | return 0; /* Default implementation does nothing */ |
1606 | } |
1607 | |
1608 | |
1609 | /** |
1610 | Advance relay log coordinates. |
1611 | |
1612 | This function is called to advance the relay log coordinates to |
1613 | just after the event. It is essential that both the relay log |
1614 | coordinate and the group log position is updated correctly, since |
1615 | this function is used also for skipping events. |
1616 | |
1617 | Normally, each implementation of do_update_pos() shall: |
1618 | |
1619 | - Update the event position to refer to the position just after |
1620 | the event. |
1621 | |
1622 | - Update the group log position to refer to the position just |
1623 | after the event <em>if the event is last in a group</em> |
1624 | |
1625 | @param rli Pointer to relay log info structure |
1626 | |
1627 | @retval 0 Coordinates changed successfully |
1628 | @retval errno Error code if advancing failed (usually just |
1629 | 1). Observe that handler errors are returned by the |
1630 | do_apply_event() function, and not by this one. |
1631 | */ |
1632 | virtual int do_update_pos(rpl_group_info *rgi); |
1633 | |
1634 | |
1635 | /** |
1636 | Decide if this event shall be skipped or not and the reason for |
1637 | skipping it. |
1638 | |
1639 | The default implementation decide that the event shall be skipped |
1640 | if either: |
1641 | |
1642 | - the server id of the event is the same as the server id of the |
1643 | server and <code>rli->replicate_same_server_id</code> is true, |
1644 | or |
1645 | |
1646 | - if <code>rli->slave_skip_counter</code> is greater than zero. |
1647 | |
1648 | @see do_apply_event |
1649 | @see do_update_pos |
1650 | |
1651 | @retval Log_event::EVENT_SKIP_NOT |
1652 | The event shall not be skipped and should be applied. |
1653 | |
1654 | @retval Log_event::EVENT_SKIP_IGNORE |
1655 | The event shall be skipped by just ignoring it, i.e., the slave |
1656 | skip counter shall not be changed. This happends if, for example, |
1657 | the originating server id of the event is the same as the server |
1658 | id of the slave. |
1659 | |
1660 | @retval Log_event::EVENT_SKIP_COUNT |
1661 | The event shall be skipped because the slave skip counter was |
1662 | non-zero. The caller shall decrease the counter by one. |
1663 | */ |
1664 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
1665 | #endif |
1666 | }; |
1667 | |
1668 | |
1669 | /* |
1670 | One class for each type of event. |
1671 | Two constructors for each class: |
1672 | - one to create the event for logging (when the server acts as a master), |
1673 | called after an update to the database is done, |
1674 | which accepts parameters like the query, the database, the options for LOAD |
1675 | DATA INFILE... |
1676 | - one to create the event from a packet (when the server acts as a slave), |
1677 | called before reproducing the update, which accepts parameters (like a |
1678 | buffer). Used to read from the master, from the relay log, and in |
1679 | mysqlbinlog. This constructor must be format-tolerant. |
1680 | */ |
1681 | |
1682 | /** |
1683 | @class Query_log_event |
1684 | |
1685 | A @c Query_log_event is created for each query that modifies the |
1686 | database, unless the query is logged row-based. |
1687 | |
1688 | @section Query_log_event_binary_format Binary format |
1689 | |
1690 | See @ref Log_event_binary_format "Binary format for log events" for |
1691 | a general discussion and introduction to the binary format of binlog |
1692 | events. |
1693 | |
1694 | The Post-Header has five components: |
1695 | |
1696 | <table> |
1697 | <caption>Post-Header for Query_log_event</caption> |
1698 | |
1699 | <tr> |
1700 | <th>Name</th> |
1701 | <th>Format</th> |
1702 | <th>Description</th> |
1703 | </tr> |
1704 | |
1705 | <tr> |
1706 | <td>slave_proxy_id</td> |
1707 | <td>4 byte unsigned integer</td> |
1708 | <td>An integer identifying the client thread that issued the |
1709 | query. The id is unique per server. (Note, however, that two |
1710 | threads on different servers may have the same slave_proxy_id.) |
1711 | This is used when a client thread creates a temporary table local |
1712 | to the client. The slave_proxy_id is used to distinguish |
1713 | temporary tables that belong to different clients. |
1714 | </td> |
1715 | </tr> |
1716 | |
1717 | <tr> |
1718 | <td>exec_time</td> |
1719 | <td>4 byte unsigned integer</td> |
1720 | <td>The time from when the query started to when it was logged in |
1721 | the binlog, in seconds.</td> |
1722 | </tr> |
1723 | |
1724 | <tr> |
1725 | <td>db_len</td> |
1726 | <td>1 byte integer</td> |
1727 | <td>The length of the name of the currently selected database.</td> |
1728 | </tr> |
1729 | |
1730 | <tr> |
1731 | <td>error_code</td> |
1732 | <td>2 byte unsigned integer</td> |
1733 | <td>Error code generated by the master. If the master fails, the |
1734 | slave will fail with the same error code, except for the error |
1735 | codes ER_DB_CREATE_EXISTS == 1007 and ER_DB_DROP_EXISTS == 1008. |
1736 | </td> |
1737 | </tr> |
1738 | |
1739 | <tr> |
1740 | <td>status_vars_len</td> |
1741 | <td>2 byte unsigned integer</td> |
1742 | <td>The length of the status_vars block of the Body, in bytes. See |
1743 | @ref query_log_event_status_vars "below". |
1744 | </td> |
1745 | </tr> |
1746 | </table> |
1747 | |
1748 | The Body has the following components: |
1749 | |
1750 | <table> |
1751 | <caption>Body for Query_log_event</caption> |
1752 | |
1753 | <tr> |
1754 | <th>Name</th> |
1755 | <th>Format</th> |
1756 | <th>Description</th> |
1757 | </tr> |
1758 | |
1759 | <tr> |
1760 | <td>@anchor query_log_event_status_vars status_vars</td> |
1761 | <td>status_vars_len bytes</td> |
1762 | <td>Zero or more status variables. Each status variable consists |
1763 | of one byte identifying the variable stored, followed by the value |
1764 | of the variable. The possible variables are listed separately in |
1765 | the table @ref Table_query_log_event_status_vars "below". MySQL |
1766 | always writes events in the order defined below; however, it is |
1767 | capable of reading them in any order. </td> |
1768 | </tr> |
1769 | |
1770 | <tr> |
1771 | <td>db</td> |
1772 | <td>db_len+1</td> |
1773 | <td>The currently selected database, as a null-terminated string. |
1774 | |
1775 | (The trailing zero is redundant since the length is already known; |
1776 | it is db_len from Post-Header.) |
1777 | </td> |
1778 | </tr> |
1779 | |
1780 | <tr> |
1781 | <td>query</td> |
1782 | <td>variable length string without trailing zero, extending to the |
1783 | end of the event (determined by the length field of the |
1784 | Common-Header) |
1785 | </td> |
1786 | <td>The SQL query.</td> |
1787 | </tr> |
1788 | </table> |
1789 | |
1790 | The following table lists the status variables that may appear in |
1791 | the status_vars field. |
1792 | |
1793 | @anchor Table_query_log_event_status_vars |
1794 | <table> |
1795 | <caption>Status variables for Query_log_event</caption> |
1796 | |
1797 | <tr> |
1798 | <th>Status variable</th> |
1799 | <th>1 byte identifier</th> |
1800 | <th>Format</th> |
1801 | <th>Description</th> |
1802 | </tr> |
1803 | |
1804 | <tr> |
1805 | <td>flags2</td> |
1806 | <td>Q_FLAGS2_CODE == 0</td> |
1807 | <td>4 byte bitfield</td> |
1808 | <td>The flags in @c thd->options, binary AND-ed with @c |
1809 | OPTIONS_WRITTEN_TO_BIN_LOG. The @c thd->options bitfield contains |
1810 | options for "SELECT". @c OPTIONS_WRITTEN identifies those options |
1811 | that need to be written to the binlog (not all do). Specifically, |
1812 | @c OPTIONS_WRITTEN_TO_BIN_LOG equals (@c OPTION_AUTO_IS_NULL | @c |
1813 | OPTION_NO_FOREIGN_KEY_CHECKS | @c OPTION_RELAXED_UNIQUE_CHECKS | |
1814 | @c OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex. |
1815 | |
1816 | These flags correspond to the SQL variables SQL_AUTO_IS_NULL, |
1817 | FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, and AUTOCOMMIT, documented in |
1818 | the "SET Syntax" section of the MySQL Manual. |
1819 | |
1820 | This field is always written to the binlog in version >= 5.0, and |
1821 | never written in version < 5.0. |
1822 | </td> |
1823 | </tr> |
1824 | |
1825 | <tr> |
1826 | <td>sql_mode</td> |
1827 | <td>Q_SQL_MODE_CODE == 1</td> |
1828 | <td>8 byte bitfield</td> |
1829 | <td>The @c sql_mode variable. See the section "SQL Modes" in the |
1830 | MySQL manual, and see sql_priv.h for a list of the possible |
1831 | flags. Currently (2007-10-04), the following flags are available: |
1832 | <pre> |
1833 | MODE_REAL_AS_FLOAT==0x1 |
1834 | MODE_PIPES_AS_CONCAT==0x2 |
1835 | MODE_ANSI_QUOTES==0x4 |
1836 | MODE_IGNORE_SPACE==0x8 |
1837 | MODE_IGNORE_BAD_TABLE_OPTIONS==0x10 |
1838 | MODE_ONLY_FULL_GROUP_BY==0x20 |
1839 | MODE_NO_UNSIGNED_SUBTRACTION==0x40 |
1840 | MODE_NO_DIR_IN_CREATE==0x80 |
1841 | MODE_POSTGRESQL==0x100 |
1842 | MODE_ORACLE==0x200 |
1843 | MODE_MSSQL==0x400 |
1844 | MODE_DB2==0x800 |
1845 | MODE_MAXDB==0x1000 |
1846 | MODE_NO_KEY_OPTIONS==0x2000 |
1847 | MODE_NO_TABLE_OPTIONS==0x4000 |
1848 | MODE_NO_FIELD_OPTIONS==0x8000 |
1849 | MODE_MYSQL323==0x10000 |
1850 | MODE_MYSQL323==0x20000 |
1851 | MODE_MYSQL40==0x40000 |
1852 | MODE_ANSI==0x80000 |
1853 | MODE_NO_AUTO_VALUE_ON_ZERO==0x100000 |
1854 | MODE_NO_BACKSLASH_ESCAPES==0x200000 |
1855 | MODE_STRICT_TRANS_TABLES==0x400000 |
1856 | MODE_STRICT_ALL_TABLES==0x800000 |
1857 | MODE_NO_ZERO_IN_DATE==0x1000000 |
1858 | MODE_NO_ZERO_DATE==0x2000000 |
1859 | MODE_INVALID_DATES==0x4000000 |
1860 | MODE_ERROR_FOR_DIVISION_BY_ZERO==0x8000000 |
1861 | MODE_TRADITIONAL==0x10000000 |
1862 | MODE_NO_AUTO_CREATE_USER==0x20000000 |
1863 | MODE_HIGH_NOT_PRECEDENCE==0x40000000 |
1864 | MODE_PAD_CHAR_TO_FULL_LENGTH==0x80000000 |
1865 | </pre> |
1866 | All these flags are replicated from the server. However, all |
1867 | flags except @c MODE_NO_DIR_IN_CREATE are honored by the slave; |
1868 | the slave always preserves its old value of @c |
1869 | MODE_NO_DIR_IN_CREATE. For a rationale, see comment in |
1870 | @c Query_log_event::do_apply_event in @c log_event.cc. |
1871 | |
1872 | This field is always written to the binlog. |
1873 | </td> |
1874 | </tr> |
1875 | |
1876 | <tr> |
1877 | <td>catalog</td> |
1878 | <td>Q_CATALOG_NZ_CODE == 6</td> |
1879 | <td>Variable-length string: the length in bytes (1 byte) followed |
1880 | by the characters (at most 255 bytes) |
1881 | </td> |
1882 | <td>Stores the client's current catalog. Every database belongs |
1883 | to a catalog, the same way that every table belongs to a |
1884 | database. Currently, there is only one catalog, "std". |
1885 | |
1886 | This field is written if the length of the catalog is > 0; |
1887 | otherwise it is not written. |
1888 | </td> |
1889 | </tr> |
1890 | |
1891 | <tr> |
1892 | <td>auto_increment</td> |
1893 | <td>Q_AUTO_INCREMENT == 3</td> |
1894 | <td>two 2 byte unsigned integers, totally 2+2=4 bytes</td> |
1895 | |
1896 | <td>The two variables auto_increment_increment and |
1897 | auto_increment_offset, in that order. For more information, see |
1898 | "System variables" in the MySQL manual. |
1899 | |
1900 | This field is written if auto_increment > 1. Otherwise, it is not |
1901 | written. |
1902 | </td> |
1903 | </tr> |
1904 | |
1905 | <tr> |
1906 | <td>charset</td> |
1907 | <td>Q_CHARSET_CODE == 4</td> |
1908 | <td>three 2 byte unsigned integers, totally 2+2+2=6 bytes</td> |
1909 | <td>The three variables character_set_client, |
1910 | collation_connection, and collation_server, in that order. |
1911 | character_set_client is a code identifying the character set and |
1912 | collation used by the client to encode the query. |
1913 | collation_connection identifies the character set and collation |
1914 | that the master converts the query to when it receives it; this is |
1915 | useful when comparing literal strings. collation_server is the |
1916 | default character set and collation used when a new database is |
1917 | created. |
1918 | |
1919 | See also "Connection Character Sets and Collations" in the MySQL |
1920 | 5.1 manual. |
1921 | |
1922 | All three variables are codes identifying a (character set, |
1923 | collation) pair. To see which codes map to which pairs, run the |
1924 | query "SELECT id, character_set_name, collation_name FROM |
1925 | COLLATIONS". |
1926 | |
1927 | Cf. Q_CHARSET_DATABASE_CODE below. |
1928 | |
1929 | This field is always written. |
1930 | </td> |
1931 | </tr> |
1932 | |
1933 | <tr> |
1934 | <td>time_zone</td> |
1935 | <td>Q_TIME_ZONE_CODE == 5</td> |
1936 | <td>Variable-length string: the length in bytes (1 byte) followed |
1937 | by the characters (at most 255 bytes). |
1938 | <td>The time_zone of the master. |
1939 | |
1940 | See also "System Variables" and "MySQL Server Time Zone Support" |
1941 | in the MySQL manual. |
1942 | |
1943 | This field is written if the length of the time zone string is > |
1944 | 0; otherwise, it is not written. |
1945 | </td> |
1946 | </tr> |
1947 | |
1948 | <tr> |
1949 | <td>lc_time_names_number</td> |
1950 | <td>Q_LC_TIME_NAMES_CODE == 7</td> |
1951 | <td>2 byte integer</td> |
1952 | <td>A code identifying a table of month and day names. The |
1953 | mapping from codes to languages is defined in @c sql_locale.cc. |
1954 | |
1955 | This field is written if it is not 0, i.e., if the locale is not |
1956 | en_US. |
1957 | </td> |
1958 | </tr> |
1959 | |
1960 | <tr> |
1961 | <td>charset_database_number</td> |
1962 | <td>Q_CHARSET_DATABASE_CODE == 8</td> |
1963 | <td>2 byte integer</td> |
1964 | |
1965 | <td>The value of the collation_database system variable (in the |
1966 | source code stored in @c thd->variables.collation_database), which |
1967 | holds the code for a (character set, collation) pair as described |
1968 | above (see Q_CHARSET_CODE). |
1969 | |
1970 | collation_database was used in old versions (???WHEN). Its value |
1971 | was loaded when issuing a "use db" query and could be changed by |
1972 | issuing a "SET collation_database=xxx" query. It used to affect |
1973 | the "LOAD DATA INFILE" and "CREATE TABLE" commands. |
1974 | |
1975 | In newer versions, "CREATE TABLE" has been changed to take the |
1976 | character set from the database of the created table, rather than |
1977 | the character set of the current database. This makes a |
1978 | difference when creating a table in another database than the |
1979 | current one. "LOAD DATA INFILE" has not yet changed to do this, |
1980 | but there are plans to eventually do it, and to make |
1981 | collation_database read-only. |
1982 | |
1983 | This field is written if it is not 0. |
1984 | </td> |
1985 | </tr> |
1986 | <tr> |
1987 | <td>table_map_for_update</td> |
1988 | <td>Q_TABLE_MAP_FOR_UPDATE_CODE == 9</td> |
1989 | <td>8 byte integer</td> |
1990 | |
1991 | <td>The value of the table map that is to be updated by the |
1992 | multi-table update query statement. Every bit of this variable |
1993 | represents a table, and is set to 1 if the corresponding table is |
1994 | to be updated by this statement. |
1995 | |
1996 | The value of this variable is set when executing a multi-table update |
1997 | statement and used by slave to apply filter rules without opening |
1998 | all the tables on slave. This is required because some tables may |
1999 | not exist on slave because of the filter rules. |
2000 | </td> |
2001 | </tr> |
2002 | </table> |
2003 | |
2004 | @subsection Query_log_event_notes_on_previous_versions Notes on Previous Versions |
2005 | |
2006 | * Status vars were introduced in version 5.0. To read earlier |
2007 | versions correctly, check the length of the Post-Header. |
2008 | |
2009 | * The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x, |
2010 | where 0<=x<=3. It was identical to Q_CATALOG_CODE, except that the |
2011 | string had a trailing '\0'. The '\0' was removed in 5.0.4 since it |
2012 | was redundant (the string length is stored before the string). The |
2013 | Q_CATALOG_CODE will never be written by a new master, but can still |
2014 | be understood by a new slave. |
2015 | |
2016 | * See Q_CHARSET_DATABASE_CODE in the table above. |
2017 | |
2018 | * When adding new status vars, please don't forget to update the |
2019 | MAX_SIZE_LOG_EVENT_STATUS, and update function code_name |
2020 | |
2021 | */ |
2022 | class Query_log_event: public Log_event |
2023 | { |
2024 | LEX_CSTRING user; |
2025 | LEX_CSTRING host; |
2026 | protected: |
2027 | Log_event::Byte* data_buf; |
2028 | public: |
2029 | const char* query; |
2030 | const char* catalog; |
2031 | const char* db; |
2032 | /* |
2033 | If we already know the length of the query string |
2034 | we pass it with q_len, so we would not have to call strlen() |
2035 | otherwise, set it to 0, in which case, we compute it with strlen() |
2036 | */ |
2037 | uint32 q_len; |
2038 | uint32 db_len; |
2039 | uint16 error_code; |
2040 | my_thread_id thread_id; |
2041 | /* |
2042 | For events created by Query_log_event::do_apply_event (and |
2043 | Load_log_event::do_apply_event()) we need the *original* thread |
2044 | id, to be able to log the event with the original (=master's) |
2045 | thread id (fix for BUG#1686). |
2046 | */ |
2047 | ulong slave_proxy_id; |
2048 | |
2049 | /* |
2050 | Binlog format 3 and 4 start to differ (as far as class members are |
2051 | concerned) from here. |
2052 | */ |
2053 | |
2054 | uint catalog_len; // <= 255 char; 0 means uninited |
2055 | |
2056 | /* |
2057 | We want to be able to store a variable number of N-bit status vars: |
2058 | (generally N=32; but N=64 for SQL_MODE) a user may want to log the number |
2059 | of affected rows (for debugging) while another does not want to lose 4 |
2060 | bytes in this. |
2061 | The storage on disk is the following: |
2062 | status_vars_len is part of the post-header, |
2063 | status_vars are in the variable-length part, after the post-header, before |
2064 | the db & query. |
2065 | status_vars on disk is a sequence of pairs (code, value) where 'code' means |
2066 | 'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so |
2067 | its first byte is its length. For now the order of status vars is: |
2068 | flags2 - sql_mode - catalog - autoinc - charset |
2069 | We should add the same thing to Load_log_event, but in fact |
2070 | LOAD DATA INFILE is going to be logged with a new type of event (logging of |
2071 | the plain text query), so Load_log_event would be frozen, so no need. The |
2072 | new way of logging LOAD DATA INFILE would use a derived class of |
2073 | Query_log_event, so automatically benefit from the work already done for |
2074 | status variables in Query_log_event. |
2075 | */ |
2076 | uint16 status_vars_len; |
2077 | |
2078 | /* |
2079 | 'flags2' is a second set of flags (on top of those in Log_event), for |
2080 | session variables. These are thd->options which is & against a mask |
2081 | (OPTIONS_WRITTEN_TO_BIN_LOG). |
2082 | flags2_inited helps make a difference between flags2==0 (3.23 or 4.x |
2083 | master, we don't know flags2, so use the slave server's global options) and |
2084 | flags2==0 (5.0 master, we know this has a meaning of flags all down which |
2085 | must influence the query). |
2086 | */ |
2087 | bool flags2_inited; |
2088 | bool sql_mode_inited; |
2089 | bool charset_inited; |
2090 | |
2091 | uint32 flags2; |
2092 | sql_mode_t sql_mode; |
2093 | ulong auto_increment_increment, auto_increment_offset; |
2094 | char charset[6]; |
2095 | uint time_zone_len; /* 0 means uninited */ |
2096 | const char *time_zone_str; |
2097 | uint lc_time_names_number; /* 0 means en_US */ |
2098 | uint charset_database_number; |
2099 | /* |
2100 | map for tables that will be updated for a multi-table update query |
2101 | statement, for other query statements, this will be zero. |
2102 | */ |
2103 | ulonglong table_map_for_update; |
2104 | /* |
2105 | Holds the original length of a Query_log_event that comes from a |
2106 | master of version < 5.0 (i.e., binlog_version < 4). When the IO |
2107 | thread writes the relay log, it augments the Query_log_event with a |
2108 | Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event |
2109 | length. This field is initialized to non-zero in the SQL thread when |
2110 | it reads this augmented event. SQL thread does not write |
2111 | Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog. |
2112 | */ |
2113 | uint32 master_data_written; |
2114 | |
2115 | #ifdef MYSQL_SERVER |
2116 | |
2117 | Query_log_event(THD* thd_arg, const char* query_arg, size_t query_length, |
2118 | bool using_trans, bool direct, bool suppress_use, int error); |
2119 | const char* get_db() { return db; } |
2120 | #ifdef HAVE_REPLICATION |
2121 | void pack_info(Protocol* protocol); |
2122 | #endif /* HAVE_REPLICATION */ |
2123 | #else |
2124 | bool print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info); |
2125 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2126 | #endif |
2127 | |
2128 | Query_log_event(); |
2129 | Query_log_event(const char* buf, uint event_len, |
2130 | const Format_description_log_event *description_event, |
2131 | Log_event_type event_type); |
2132 | ~Query_log_event() |
2133 | { |
2134 | if (data_buf) |
2135 | my_free(data_buf); |
2136 | } |
2137 | Log_event_type get_type_code() { return QUERY_EVENT; } |
2138 | static int dummy_event(String *packet, ulong ev_offset, enum enum_binlog_checksum_alg checksum_alg); |
2139 | static int begin_event(String *packet, ulong ev_offset, enum enum_binlog_checksum_alg checksum_alg); |
2140 | #ifdef MYSQL_SERVER |
2141 | bool write(); |
2142 | virtual bool () { return FALSE; } |
2143 | #endif |
2144 | bool is_valid() const { return query != 0; } |
2145 | |
2146 | /* |
2147 | Returns number of bytes additionally written to post header by derived |
2148 | events (so far it is only Execute_load_query event). |
2149 | */ |
2150 | virtual ulong () { return 0; } |
2151 | /* Writes derived event-specific part of post header. */ |
2152 | |
2153 | public: /* !!! Public in this patch to allow old usage */ |
2154 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2155 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
2156 | virtual int do_apply_event(rpl_group_info *rgi); |
2157 | |
2158 | int do_apply_event(rpl_group_info *rgi, |
2159 | const char *query_arg, |
2160 | uint32 q_len_arg); |
2161 | static bool peek_is_commit_rollback(const char *event_start, |
2162 | size_t event_len, enum enum_binlog_checksum_alg checksum_alg); |
2163 | #endif /* HAVE_REPLICATION */ |
2164 | /* |
2165 | If true, the event always be applied by slave SQL thread or be printed by |
2166 | mysqlbinlog |
2167 | */ |
2168 | bool is_trans_keyword() |
2169 | { |
2170 | /* |
2171 | Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO' |
2172 | queries input by user was written into log events directly. |
2173 | So the keywords can be written in both upper case and lower case |
2174 | together, strncasecmp is used to check both cases. they also could be |
2175 | binlogged with comments in the front of these keywords. for examples: |
2176 | / * bla bla * / SAVEPOINT a; |
2177 | / * bla bla * / ROLLBACK TO a; |
2178 | but we don't handle these cases and after the patch, both quiries are |
2179 | binlogged in upper case with no comments. |
2180 | */ |
2181 | return !strncmp(query, "BEGIN" , q_len) || |
2182 | !strncmp(query, "COMMIT" , q_len) || |
2183 | !strncasecmp(query, "SAVEPOINT" , 9) || |
2184 | !strncasecmp(query, "ROLLBACK" , 8); |
2185 | } |
2186 | virtual bool is_begin() { return !strcmp(query, "BEGIN" ); } |
2187 | virtual bool is_commit() { return !strcmp(query, "COMMIT" ); } |
2188 | virtual bool is_rollback() { return !strcmp(query, "ROLLBACK" ); } |
2189 | }; |
2190 | |
2191 | class Query_compressed_log_event:public Query_log_event{ |
2192 | protected: |
2193 | Log_event::Byte* query_buf; // point to the uncompressed query |
2194 | public: |
2195 | Query_compressed_log_event(const char* buf, uint event_len, |
2196 | const Format_description_log_event *description_event, |
2197 | Log_event_type event_type); |
2198 | ~Query_compressed_log_event() |
2199 | { |
2200 | if (query_buf) |
2201 | my_free(query_buf); |
2202 | } |
2203 | Log_event_type get_type_code() { return QUERY_COMPRESSED_EVENT; } |
2204 | |
2205 | /* |
2206 | the min length of log_bin_compress_min_len is 10, |
2207 | means that Begin/Commit/Rollback would never be compressed! |
2208 | */ |
2209 | virtual bool is_begin() { return false; } |
2210 | virtual bool is_commit() { return false; } |
2211 | virtual bool is_rollback() { return false; } |
2212 | #ifdef MYSQL_SERVER |
2213 | Query_compressed_log_event(THD* thd_arg, const char* query_arg, ulong query_length, |
2214 | bool using_trans, bool direct, bool suppress_use, int error); |
2215 | virtual bool write(); |
2216 | #endif |
2217 | }; |
2218 | |
2219 | |
2220 | /***************************************************************************** |
2221 | sql_ex_info struct |
2222 | ****************************************************************************/ |
2223 | struct sql_ex_info |
2224 | { |
2225 | sql_ex_info() {} /* Remove gcc warning */ |
2226 | const char* field_term; |
2227 | const char* enclosed; |
2228 | const char* line_term; |
2229 | const char* line_start; |
2230 | const char* escaped; |
2231 | int cached_new_format; |
2232 | uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len; |
2233 | char opt_flags; |
2234 | char empty_flags; |
2235 | |
2236 | // store in new format even if old is possible |
2237 | void force_new_format() { cached_new_format = 1;} |
2238 | int data_size() |
2239 | { |
2240 | return (new_format() ? |
2241 | field_term_len + enclosed_len + line_term_len + |
2242 | line_start_len + escaped_len + 6 : 7); |
2243 | } |
2244 | bool write_data(Log_event_writer *writer); |
2245 | const char* init(const char* buf, const char* buf_end, bool use_new_format); |
2246 | bool new_format() |
2247 | { |
2248 | return ((cached_new_format != -1) ? cached_new_format : |
2249 | (cached_new_format=(field_term_len > 1 || |
2250 | enclosed_len > 1 || |
2251 | line_term_len > 1 || line_start_len > 1 || |
2252 | escaped_len > 1))); |
2253 | } |
2254 | }; |
2255 | |
2256 | /** |
2257 | @class Load_log_event |
2258 | |
2259 | This log event corresponds to a "LOAD DATA INFILE" SQL query on the |
2260 | following form: |
2261 | |
2262 | @verbatim |
2263 | (1) USE db; |
2264 | (2) LOAD DATA [CONCURRENT] [LOCAL] INFILE 'file_name' |
2265 | (3) [REPLACE | IGNORE] |
2266 | (4) INTO TABLE 'table_name' |
2267 | (5) [FIELDS |
2268 | (6) [TERMINATED BY 'field_term'] |
2269 | (7) [[OPTIONALLY] ENCLOSED BY 'enclosed'] |
2270 | (8) [ESCAPED BY 'escaped'] |
2271 | (9) ] |
2272 | (10) [LINES |
2273 | (11) [TERMINATED BY 'line_term'] |
2274 | (12) [LINES STARTING BY 'line_start'] |
2275 | (13) ] |
2276 | (14) [IGNORE skip_lines LINES] |
2277 | (15) (field_1, field_2, ..., field_n)@endverbatim |
2278 | |
2279 | @section Load_log_event_binary_format Binary Format |
2280 | |
2281 | The Post-Header consists of the following six components. |
2282 | |
2283 | <table> |
2284 | <caption>Post-Header for Load_log_event</caption> |
2285 | |
2286 | <tr> |
2287 | <th>Name</th> |
2288 | <th>Format</th> |
2289 | <th>Description</th> |
2290 | </tr> |
2291 | |
2292 | <tr> |
2293 | <td>slave_proxy_id</td> |
2294 | <td>4 byte unsigned integer</td> |
2295 | <td>An integer identifying the client thread that issued the |
2296 | query. The id is unique per server. (Note, however, that two |
2297 | threads on different servers may have the same slave_proxy_id.) |
2298 | This is used when a client thread creates a temporary table local |
2299 | to the client. The slave_proxy_id is used to distinguish |
2300 | temporary tables that belong to different clients. |
2301 | </td> |
2302 | </tr> |
2303 | |
2304 | <tr> |
2305 | <td>exec_time</td> |
2306 | <td>4 byte unsigned integer</td> |
2307 | <td>The time from when the query started to when it was logged in |
2308 | the binlog, in seconds.</td> |
2309 | </tr> |
2310 | |
2311 | <tr> |
2312 | <td>skip_lines</td> |
2313 | <td>4 byte unsigned integer</td> |
2314 | <td>The number on line (14) above, if present, or 0 if line (14) |
2315 | is left out. |
2316 | </td> |
2317 | </tr> |
2318 | |
2319 | <tr> |
2320 | <td>table_name_len</td> |
2321 | <td>1 byte unsigned integer</td> |
2322 | <td>The length of 'table_name' on line (4) above.</td> |
2323 | </tr> |
2324 | |
2325 | <tr> |
2326 | <td>db_len</td> |
2327 | <td>1 byte unsigned integer</td> |
2328 | <td>The length of 'db' on line (1) above.</td> |
2329 | </tr> |
2330 | |
2331 | <tr> |
2332 | <td>num_fields</td> |
2333 | <td>4 byte unsigned integer</td> |
2334 | <td>The number n of fields on line (15) above.</td> |
2335 | </tr> |
2336 | </table> |
2337 | |
2338 | The Body contains the following components. |
2339 | |
2340 | <table> |
2341 | <caption>Body of Load_log_event</caption> |
2342 | |
2343 | <tr> |
2344 | <th>Name</th> |
2345 | <th>Format</th> |
2346 | <th>Description</th> |
2347 | </tr> |
2348 | |
2349 | <tr> |
2350 | <td>sql_ex</td> |
2351 | <td>variable length</td> |
2352 | |
2353 | <td>Describes the part of the query on lines (3) and |
2354 | (5)–(13) above. More precisely, it stores the five strings |
2355 | (on lines) field_term (6), enclosed (7), escaped (8), line_term |
2356 | (11), and line_start (12); as well as a bitfield indicating the |
2357 | presence of the keywords REPLACE (3), IGNORE (3), and OPTIONALLY |
2358 | (7). |
2359 | |
2360 | The data is stored in one of two formats, called "old" and "new". |
2361 | The type field of Common-Header determines which of these two |
2362 | formats is used: type LOAD_EVENT means that the old format is |
2363 | used, and type NEW_LOAD_EVENT means that the new format is used. |
2364 | When MySQL writes a Load_log_event, it uses the new format if at |
2365 | least one of the five strings is two or more bytes long. |
2366 | Otherwise (i.e., if all strings are 0 or 1 bytes long), the old |
2367 | format is used. |
2368 | |
2369 | The new and old format differ in the way the five strings are |
2370 | stored. |
2371 | |
2372 | <ul> |
2373 | <li> In the new format, the strings are stored in the order |
2374 | field_term, enclosed, escaped, line_term, line_start. Each string |
2375 | consists of a length (1 byte), followed by a sequence of |
2376 | characters (0-255 bytes). Finally, a boolean combination of the |
2377 | following flags is stored in 1 byte: REPLACE_FLAG==0x4, |
2378 | IGNORE_FLAG==0x8, and OPT_ENCLOSED_FLAG==0x2. If a flag is set, |
2379 | it indicates the presence of the corresponding keyword in the SQL |
2380 | query. |
2381 | |
2382 | <li> In the old format, we know that each string has length 0 or |
2383 | 1. Therefore, only the first byte of each string is stored. The |
2384 | order of the strings is the same as in the new format. These five |
2385 | bytes are followed by the same 1 byte bitfield as in the new |
2386 | format. Finally, a 1 byte bitfield called empty_flags is stored. |
2387 | The low 5 bits of empty_flags indicate which of the five strings |
2388 | have length 0. For each of the following flags that is set, the |
2389 | corresponding string has length 0; for the flags that are not set, |
2390 | the string has length 1: FIELD_TERM_EMPTY==0x1, |
2391 | ENCLOSED_EMPTY==0x2, LINE_TERM_EMPTY==0x4, LINE_START_EMPTY==0x8, |
2392 | ESCAPED_EMPTY==0x10. |
2393 | </ul> |
2394 | |
2395 | Thus, the size of the new format is 6 bytes + the sum of the sizes |
2396 | of the five strings. The size of the old format is always 7 |
2397 | bytes. |
2398 | </td> |
2399 | </tr> |
2400 | |
2401 | <tr> |
2402 | <td>field_lens</td> |
2403 | <td>num_fields 1 byte unsigned integers</td> |
2404 | <td>An array of num_fields integers representing the length of |
2405 | each field in the query. (num_fields is from the Post-Header). |
2406 | </td> |
2407 | </tr> |
2408 | |
2409 | <tr> |
2410 | <td>fields</td> |
2411 | <td>num_fields null-terminated strings</td> |
2412 | <td>An array of num_fields null-terminated strings, each |
2413 | representing a field in the query. (The trailing zero is |
2414 | redundant, since the length are stored in the num_fields array.) |
2415 | The total length of all strings equals to the sum of all |
2416 | field_lens, plus num_fields bytes for all the trailing zeros. |
2417 | </td> |
2418 | </tr> |
2419 | |
2420 | <tr> |
2421 | <td>table_name</td> |
2422 | <td>null-terminated string of length table_len+1 bytes</td> |
2423 | <td>The 'table_name' from the query, as a null-terminated string. |
2424 | (The trailing zero is actually redundant since the table_len is |
2425 | known from Post-Header.) |
2426 | </td> |
2427 | </tr> |
2428 | |
2429 | <tr> |
2430 | <td>db</td> |
2431 | <td>null-terminated string of length db_len+1 bytes</td> |
2432 | <td>The 'db' from the query, as a null-terminated string. |
2433 | (The trailing zero is actually redundant since the db_len is known |
2434 | from Post-Header.) |
2435 | </td> |
2436 | </tr> |
2437 | |
2438 | <tr> |
2439 | <td>file_name</td> |
2440 | <td>variable length string without trailing zero, extending to the |
2441 | end of the event (determined by the length field of the |
2442 | Common-Header) |
2443 | </td> |
2444 | <td>The 'file_name' from the query. |
2445 | </td> |
2446 | </tr> |
2447 | |
2448 | </table> |
2449 | |
2450 | @subsection Load_log_event_notes_on_previous_versions Notes on Previous Versions |
2451 | |
2452 | This event type is understood by current versions, but only |
2453 | generated by MySQL 3.23 and earlier. |
2454 | */ |
2455 | class Load_log_event: public Log_event |
2456 | { |
2457 | private: |
2458 | protected: |
2459 | int copy_log_event(const char *buf, ulong event_len, |
2460 | int body_offset, |
2461 | const Format_description_log_event* description_event); |
2462 | |
2463 | public: |
2464 | bool print_query(THD *thd, bool need_db, const char *cs, String *buf, |
2465 | my_off_t *fn_start, my_off_t *fn_end, |
2466 | const char *qualify_db); |
2467 | my_thread_id thread_id; |
2468 | ulong slave_proxy_id; |
2469 | uint32 table_name_len; |
2470 | /* |
2471 | No need to have a catalog, as these events can only come from 4.x. |
2472 | TODO: this may become false if Dmitri pushes his new LOAD DATA INFILE in |
2473 | 5.0 only (not in 4.x). |
2474 | */ |
2475 | uint32 db_len; |
2476 | uint32 fname_len; |
2477 | uint32 num_fields; |
2478 | const char* fields; |
2479 | const uchar* field_lens; |
2480 | uint32 field_block_len; |
2481 | |
2482 | const char* table_name; |
2483 | const char* db; |
2484 | const char* fname; |
2485 | uint32 skip_lines; |
2486 | sql_ex_info sql_ex; |
2487 | bool local_fname; |
2488 | /** |
2489 | Indicates that this event corresponds to LOAD DATA CONCURRENT, |
2490 | |
2491 | @note Since Load_log_event event coming from the binary log |
2492 | lacks information whether LOAD DATA on master was concurrent |
2493 | or not, this flag is only set to TRUE for an auxiliary |
2494 | Load_log_event object which is used in mysql_load() to |
2495 | re-construct LOAD DATA statement from function parameters, |
2496 | for logging. |
2497 | */ |
2498 | bool is_concurrent; |
2499 | |
2500 | /* fname doesn't point to memory inside Log_event::temp_buf */ |
2501 | void set_fname_outside_temp_buf(const char *afname, size_t alen) |
2502 | { |
2503 | fname= afname; |
2504 | fname_len= (uint)alen; |
2505 | local_fname= TRUE; |
2506 | } |
2507 | /* fname doesn't point to memory inside Log_event::temp_buf */ |
2508 | int check_fname_outside_temp_buf() |
2509 | { |
2510 | return local_fname; |
2511 | } |
2512 | |
2513 | #ifdef MYSQL_SERVER |
2514 | String field_lens_buf; |
2515 | String fields_buf; |
2516 | |
2517 | Load_log_event(THD* thd, const sql_exchange* ex, const char* db_arg, |
2518 | const char* table_name_arg, |
2519 | List<Item>& fields_arg, |
2520 | bool is_concurrent_arg, |
2521 | enum enum_duplicates handle_dup, bool ignore, |
2522 | bool using_trans); |
2523 | void set_fields(const char* db, List<Item> &fields_arg, |
2524 | Name_resolution_context *context); |
2525 | const char* get_db() { return db; } |
2526 | #ifdef HAVE_REPLICATION |
2527 | void pack_info(Protocol* protocol); |
2528 | #endif /* HAVE_REPLICATION */ |
2529 | #else |
2530 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2531 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented); |
2532 | #endif |
2533 | |
2534 | /* |
2535 | Note that for all the events related to LOAD DATA (Load_log_event, |
2536 | Create_file/Append/Exec/Delete, we pass description_event; however as |
2537 | logging of LOAD DATA is going to be changed in 4.1 or 5.0, this is only used |
2538 | for the common_header_len (post_header_len will not be changed). |
2539 | */ |
2540 | Load_log_event(const char* buf, uint event_len, |
2541 | const Format_description_log_event* description_event); |
2542 | ~Load_log_event() |
2543 | {} |
2544 | Log_event_type get_type_code() |
2545 | { |
2546 | return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT; |
2547 | } |
2548 | #ifdef MYSQL_SERVER |
2549 | bool (); |
2550 | bool write_data_body(); |
2551 | #endif |
2552 | bool is_valid() const { return table_name != 0; } |
2553 | int get_data_size() |
2554 | { |
2555 | return (table_name_len + db_len + 2 + fname_len |
2556 | + LOAD_HEADER_LEN |
2557 | + sql_ex.data_size() + field_block_len + num_fields); |
2558 | } |
2559 | |
2560 | public: /* !!! Public in this patch to allow old usage */ |
2561 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2562 | virtual int do_apply_event(rpl_group_info *rgi) |
2563 | { |
2564 | return do_apply_event(thd->slave_net,rgi,0); |
2565 | } |
2566 | |
2567 | int do_apply_event(NET *net, rpl_group_info *rgi, |
2568 | bool use_rli_only_for_errors); |
2569 | #endif |
2570 | }; |
2571 | |
2572 | /** |
2573 | @class Start_log_event_v3 |
2574 | |
2575 | Start_log_event_v3 is the Start_log_event of binlog format 3 (MySQL 3.23 and |
2576 | 4.x). |
2577 | |
2578 | Format_description_log_event derives from Start_log_event_v3; it is |
2579 | the Start_log_event of binlog format 4 (MySQL 5.0), that is, the |
2580 | event that describes the other events' Common-Header/Post-Header |
2581 | lengths. This event is sent by MySQL 5.0 whenever it starts sending |
2582 | a new binlog if the requested position is >4 (otherwise if ==4 the |
2583 | event will be sent naturally). |
2584 | |
2585 | @section Start_log_event_v3_binary_format Binary Format |
2586 | */ |
2587 | class Start_log_event_v3: public Log_event |
2588 | { |
2589 | public: |
2590 | /* |
2591 | If this event is at the start of the first binary log since server |
2592 | startup 'created' should be the timestamp when the event (and the |
2593 | binary log) was created. In the other case (i.e. this event is at |
2594 | the start of a binary log created by FLUSH LOGS or automatic |
2595 | rotation), 'created' should be 0. This "trick" is used by MySQL |
2596 | >=4.0.14 slaves to know whether they must drop stale temporary |
2597 | tables and whether they should abort unfinished transaction. |
2598 | |
2599 | Note that when 'created'!=0, it is always equal to the event's |
2600 | timestamp; indeed Start_log_event is written only in log.cc where |
2601 | the first constructor below is called, in which 'created' is set |
2602 | to 'when'. So in fact 'created' is a useless variable. When it is |
2603 | 0 we can read the actual value from timestamp ('when') and when it |
2604 | is non-zero we can read the same value from timestamp |
2605 | ('when'). Conclusion: |
2606 | - we use timestamp to print when the binlog was created. |
2607 | - we use 'created' only to know if this is a first binlog or not. |
2608 | In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in |
2609 | 3.23.57 does not print 'created the_date' if created was zero. This is now |
2610 | fixed. |
2611 | */ |
2612 | time_t created; |
2613 | uint16 binlog_version; |
2614 | char server_version[ST_SERVER_VER_LEN]; |
2615 | /* |
2616 | We set this to 1 if we don't want to have the created time in the log, |
2617 | which is the case when we rollover to a new log. |
2618 | */ |
2619 | bool dont_set_created; |
2620 | |
2621 | #ifdef MYSQL_SERVER |
2622 | Start_log_event_v3(); |
2623 | #ifdef HAVE_REPLICATION |
2624 | void pack_info(Protocol* protocol); |
2625 | #endif /* HAVE_REPLICATION */ |
2626 | #else |
2627 | Start_log_event_v3() {} |
2628 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2629 | #endif |
2630 | |
2631 | Start_log_event_v3(const char* buf, uint event_len, |
2632 | const Format_description_log_event* description_event); |
2633 | ~Start_log_event_v3() {} |
2634 | Log_event_type get_type_code() { return START_EVENT_V3;} |
2635 | my_off_t (my_off_t l __attribute__((unused))) |
2636 | { return LOG_EVENT_MINIMAL_HEADER_LEN; } |
2637 | #ifdef MYSQL_SERVER |
2638 | bool write(); |
2639 | #endif |
2640 | bool is_valid() const { return server_version[0] != 0; } |
2641 | int get_data_size() |
2642 | { |
2643 | return START_V3_HEADER_LEN; //no variable-sized part |
2644 | } |
2645 | |
2646 | protected: |
2647 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2648 | virtual int do_apply_event(rpl_group_info *rgi); |
2649 | virtual enum_skip_reason do_shall_skip(rpl_group_info*) |
2650 | { |
2651 | /* |
2652 | Events from ourself should be skipped, but they should not |
2653 | decrease the slave skip counter. |
2654 | */ |
2655 | if (this->server_id == global_system_variables.server_id) |
2656 | return Log_event::EVENT_SKIP_IGNORE; |
2657 | else |
2658 | return Log_event::EVENT_SKIP_NOT; |
2659 | } |
2660 | #endif |
2661 | }; |
2662 | |
2663 | /** |
2664 | @class Start_encryption_log_event |
2665 | |
2666 | Start_encryption_log_event marks the beginning of encrypted data (all events |
2667 | after this event are encrypted). |
2668 | |
2669 | It contains the cryptographic scheme used for the encryption as well as any |
2670 | data required to decrypt (except the actual key). |
2671 | |
2672 | For binlog cryptoscheme 1: key version, and nonce for iv generation. |
2673 | */ |
2674 | class Start_encryption_log_event : public Log_event |
2675 | { |
2676 | public: |
2677 | #ifdef MYSQL_SERVER |
2678 | Start_encryption_log_event(uint crypto_scheme_arg, uint key_version_arg, |
2679 | const uchar* nonce_arg) |
2680 | : crypto_scheme(crypto_scheme_arg), key_version(key_version_arg) |
2681 | { |
2682 | cache_type = EVENT_NO_CACHE; |
2683 | DBUG_ASSERT(crypto_scheme == 1); |
2684 | memcpy(nonce, nonce_arg, BINLOG_NONCE_LENGTH); |
2685 | } |
2686 | |
2687 | bool write_data_body() |
2688 | { |
2689 | uchar scheme_buf= crypto_scheme; |
2690 | uchar key_version_buf[BINLOG_KEY_VERSION_LENGTH]; |
2691 | int4store(key_version_buf, key_version); |
2692 | return write_data(&scheme_buf, sizeof(scheme_buf)) || |
2693 | write_data(key_version_buf, sizeof(key_version_buf)) || |
2694 | write_data(nonce, BINLOG_NONCE_LENGTH); |
2695 | } |
2696 | #else |
2697 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2698 | #endif |
2699 | |
2700 | Start_encryption_log_event( |
2701 | const char* buf, uint event_len, |
2702 | const Format_description_log_event* description_event); |
2703 | |
2704 | bool is_valid() const { return crypto_scheme == 1; } |
2705 | |
2706 | Log_event_type get_type_code() { return START_ENCRYPTION_EVENT; } |
2707 | |
2708 | int get_data_size() |
2709 | { |
2710 | return BINLOG_CRYPTO_SCHEME_LENGTH + BINLOG_KEY_VERSION_LENGTH + |
2711 | BINLOG_NONCE_LENGTH; |
2712 | } |
2713 | |
2714 | uint crypto_scheme; |
2715 | uint key_version; |
2716 | uchar nonce[BINLOG_NONCE_LENGTH]; |
2717 | |
2718 | protected: |
2719 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2720 | virtual int do_apply_event(rpl_group_info* rgi); |
2721 | virtual int do_update_pos(rpl_group_info *rgi); |
2722 | virtual enum_skip_reason do_shall_skip(rpl_group_info* rgi) |
2723 | { |
2724 | return Log_event::EVENT_SKIP_NOT; |
2725 | } |
2726 | #endif |
2727 | |
2728 | }; |
2729 | |
2730 | |
2731 | /** |
2732 | @class Format_description_log_event |
2733 | |
2734 | For binlog version 4. |
2735 | This event is saved by threads which read it, as they need it for future |
2736 | use (to decode the ordinary events). |
2737 | |
2738 | @section Format_description_log_event_binary_format Binary Format |
2739 | */ |
2740 | |
2741 | class Format_description_log_event: public Start_log_event_v3 |
2742 | { |
2743 | public: |
2744 | /* |
2745 | The size of the fixed header which _all_ events have |
2746 | (for binlogs written by this version, this is equal to |
2747 | LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT |
2748 | (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN). |
2749 | */ |
2750 | uint8 ; |
2751 | uint8 number_of_event_types; |
2752 | /* |
2753 | The list of post-headers' lengths followed |
2754 | by the checksum alg decription byte |
2755 | */ |
2756 | uint8 *; |
2757 | struct master_version_split { |
2758 | enum {KIND_MYSQL, KIND_MARIADB}; |
2759 | int kind; |
2760 | uchar ver[3]; |
2761 | }; |
2762 | master_version_split server_version_split; |
2763 | const uint8 *event_type_permutation; |
2764 | |
2765 | Format_description_log_event(uint8 binlog_ver, const char* server_ver=0); |
2766 | Format_description_log_event(const char* buf, uint event_len, |
2767 | const Format_description_log_event |
2768 | *description_event); |
2769 | ~Format_description_log_event() |
2770 | { |
2771 | my_free(post_header_len); |
2772 | } |
2773 | Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;} |
2774 | #ifdef MYSQL_SERVER |
2775 | bool write(); |
2776 | #endif |
2777 | bool () const |
2778 | { |
2779 | return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN : |
2780 | LOG_EVENT_MINIMAL_HEADER_LEN)) && |
2781 | (post_header_len != NULL)); |
2782 | } |
2783 | |
2784 | bool version_is_valid() const |
2785 | { |
2786 | /* It is invalid only when all version numbers are 0 */ |
2787 | return !(server_version_split.ver[0] == 0 && |
2788 | server_version_split.ver[1] == 0 && |
2789 | server_version_split.ver[2] == 0); |
2790 | } |
2791 | |
2792 | bool is_valid() const |
2793 | { |
2794 | return header_is_valid() && version_is_valid(); |
2795 | } |
2796 | |
2797 | int get_data_size() |
2798 | { |
2799 | /* |
2800 | The vector of post-header lengths is considered as part of the |
2801 | post-header, because in a given version it never changes (contrary to the |
2802 | query in a Query_log_event). |
2803 | */ |
2804 | return FORMAT_DESCRIPTION_HEADER_LEN; |
2805 | } |
2806 | |
2807 | Binlog_crypt_data crypto_data; |
2808 | bool start_decryption(Start_encryption_log_event* sele); |
2809 | void copy_crypto_data(const Format_description_log_event* o) |
2810 | { |
2811 | crypto_data= o->crypto_data; |
2812 | } |
2813 | void reset_crypto() |
2814 | { |
2815 | crypto_data.scheme= 0; |
2816 | } |
2817 | |
2818 | void calc_server_version_split(); |
2819 | static bool is_version_before_checksum(const master_version_split *version_split); |
2820 | protected: |
2821 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2822 | virtual int do_apply_event(rpl_group_info *rgi); |
2823 | virtual int do_update_pos(rpl_group_info *rgi); |
2824 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
2825 | #endif |
2826 | }; |
2827 | |
2828 | |
2829 | /** |
2830 | @class Intvar_log_event |
2831 | |
2832 | An Intvar_log_event will be created just before a Query_log_event, |
2833 | if the query uses one of the variables LAST_INSERT_ID or INSERT_ID. |
2834 | Each Intvar_log_event holds the value of one of these variables. |
2835 | |
2836 | @section Intvar_log_event_binary_format Binary Format |
2837 | |
2838 | The Post-Header for this event type is empty. The Body has two |
2839 | components: |
2840 | |
2841 | <table> |
2842 | <caption>Body for Intvar_log_event</caption> |
2843 | |
2844 | <tr> |
2845 | <th>Name</th> |
2846 | <th>Format</th> |
2847 | <th>Description</th> |
2848 | </tr> |
2849 | |
2850 | <tr> |
2851 | <td>type</td> |
2852 | <td>1 byte enumeration</td> |
2853 | <td>One byte identifying the type of variable stored. Currently, |
2854 | two identifiers are supported: LAST_INSERT_ID_EVENT==1 and |
2855 | INSERT_ID_EVENT==2. |
2856 | </td> |
2857 | </tr> |
2858 | |
2859 | <tr> |
2860 | <td>value</td> |
2861 | <td>8 byte unsigned integer</td> |
2862 | <td>The value of the variable.</td> |
2863 | </tr> |
2864 | |
2865 | </table> |
2866 | */ |
2867 | class Intvar_log_event: public Log_event |
2868 | { |
2869 | public: |
2870 | ulonglong val; |
2871 | uchar type; |
2872 | |
2873 | #ifdef MYSQL_SERVER |
2874 | Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg, |
2875 | bool using_trans, bool direct) |
2876 | :Log_event(thd_arg,0,using_trans),val(val_arg),type(type_arg) |
2877 | { |
2878 | if (direct) |
2879 | cache_type= Log_event::EVENT_NO_CACHE; |
2880 | } |
2881 | #ifdef HAVE_REPLICATION |
2882 | void pack_info(Protocol* protocol); |
2883 | #endif /* HAVE_REPLICATION */ |
2884 | #else |
2885 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2886 | #endif |
2887 | |
2888 | Intvar_log_event(const char* buf, |
2889 | const Format_description_log_event *description_event); |
2890 | ~Intvar_log_event() {} |
2891 | Log_event_type get_type_code() { return INTVAR_EVENT;} |
2892 | const char* get_var_type_name(); |
2893 | int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;} |
2894 | #ifdef MYSQL_SERVER |
2895 | bool write(); |
2896 | #endif |
2897 | bool is_valid() const { return 1; } |
2898 | bool is_part_of_group() { return 1; } |
2899 | |
2900 | private: |
2901 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2902 | virtual int do_apply_event(rpl_group_info *rgi); |
2903 | virtual int do_update_pos(rpl_group_info *rgi); |
2904 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
2905 | #endif |
2906 | }; |
2907 | |
2908 | |
2909 | /** |
2910 | @class Rand_log_event |
2911 | |
2912 | Logs random seed used by the next RAND(), and by PASSWORD() in 4.1.0. |
2913 | 4.1.1 does not need it (it's repeatable again) so this event needn't be |
2914 | written in 4.1.1 for PASSWORD() (but the fact that it is written is just a |
2915 | waste, it does not cause bugs). |
2916 | |
2917 | The state of the random number generation consists of 128 bits, |
2918 | which are stored internally as two 64-bit numbers. |
2919 | |
2920 | @section Rand_log_event_binary_format Binary Format |
2921 | |
2922 | The Post-Header for this event type is empty. The Body has two |
2923 | components: |
2924 | |
2925 | <table> |
2926 | <caption>Body for Rand_log_event</caption> |
2927 | |
2928 | <tr> |
2929 | <th>Name</th> |
2930 | <th>Format</th> |
2931 | <th>Description</th> |
2932 | </tr> |
2933 | |
2934 | <tr> |
2935 | <td>seed1</td> |
2936 | <td>8 byte unsigned integer</td> |
2937 | <td>64 bit random seed1.</td> |
2938 | </tr> |
2939 | |
2940 | <tr> |
2941 | <td>seed2</td> |
2942 | <td>8 byte unsigned integer</td> |
2943 | <td>64 bit random seed2.</td> |
2944 | </tr> |
2945 | </table> |
2946 | */ |
2947 | |
2948 | class Rand_log_event: public Log_event |
2949 | { |
2950 | public: |
2951 | ulonglong seed1; |
2952 | ulonglong seed2; |
2953 | |
2954 | #ifdef MYSQL_SERVER |
2955 | Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg, |
2956 | bool using_trans, bool direct) |
2957 | :Log_event(thd_arg,0,using_trans),seed1(seed1_arg),seed2(seed2_arg) |
2958 | { |
2959 | if (direct) |
2960 | cache_type= Log_event::EVENT_NO_CACHE; |
2961 | } |
2962 | #ifdef HAVE_REPLICATION |
2963 | void pack_info(Protocol* protocol); |
2964 | #endif /* HAVE_REPLICATION */ |
2965 | #else |
2966 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
2967 | #endif |
2968 | |
2969 | Rand_log_event(const char* buf, |
2970 | const Format_description_log_event *description_event); |
2971 | ~Rand_log_event() {} |
2972 | Log_event_type get_type_code() { return RAND_EVENT;} |
2973 | int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ } |
2974 | #ifdef MYSQL_SERVER |
2975 | bool write(); |
2976 | #endif |
2977 | bool is_valid() const { return 1; } |
2978 | bool is_part_of_group() { return 1; } |
2979 | |
2980 | private: |
2981 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
2982 | virtual int do_apply_event(rpl_group_info *rgi); |
2983 | virtual int do_update_pos(rpl_group_info *rgi); |
2984 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
2985 | #endif |
2986 | }; |
2987 | |
2988 | /** |
2989 | @class Xid_log_event |
2990 | |
2991 | Logs xid of the transaction-to-be-committed in the 2pc protocol. |
2992 | Has no meaning in replication, slaves ignore it. |
2993 | |
2994 | @section Xid_log_event_binary_format Binary Format |
2995 | */ |
2996 | #ifdef MYSQL_CLIENT |
2997 | typedef ulonglong my_xid; // this line is the same as in handler.h |
2998 | #endif |
2999 | |
3000 | class Xid_log_event: public Log_event |
3001 | { |
3002 | public: |
3003 | my_xid xid; |
3004 | |
3005 | #ifdef MYSQL_SERVER |
3006 | Xid_log_event(THD* thd_arg, my_xid x, bool direct): |
3007 | Log_event(thd_arg, 0, TRUE), xid(x) |
3008 | { |
3009 | if (direct) |
3010 | cache_type= Log_event::EVENT_NO_CACHE; |
3011 | } |
3012 | #ifdef HAVE_REPLICATION |
3013 | void pack_info(Protocol* protocol); |
3014 | #endif /* HAVE_REPLICATION */ |
3015 | #else |
3016 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3017 | #endif |
3018 | |
3019 | Xid_log_event(const char* buf, |
3020 | const Format_description_log_event *description_event); |
3021 | ~Xid_log_event() {} |
3022 | Log_event_type get_type_code() { return XID_EVENT;} |
3023 | int get_data_size() { return sizeof(xid); } |
3024 | #ifdef MYSQL_SERVER |
3025 | bool write(); |
3026 | #endif |
3027 | bool is_valid() const { return 1; } |
3028 | |
3029 | private: |
3030 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3031 | virtual int do_apply_event(rpl_group_info *rgi); |
3032 | enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3033 | #endif |
3034 | }; |
3035 | |
3036 | /** |
3037 | @class User_var_log_event |
3038 | |
3039 | Every time a query uses the value of a user variable, a User_var_log_event is |
3040 | written before the Query_log_event, to set the user variable. |
3041 | |
3042 | @section User_var_log_event_binary_format Binary Format |
3043 | */ |
3044 | |
3045 | class User_var_log_event: public Log_event |
3046 | { |
3047 | public: |
3048 | enum { |
3049 | UNDEF_F= 0, |
3050 | UNSIGNED_F= 1 |
3051 | }; |
3052 | const char *name; |
3053 | size_t name_len; |
3054 | const char *val; |
3055 | size_t val_len; |
3056 | Item_result type; |
3057 | uint charset_number; |
3058 | bool is_null; |
3059 | uchar flags; |
3060 | #ifdef MYSQL_SERVER |
3061 | bool deferred; |
3062 | query_id_t query_id; |
3063 | User_var_log_event(THD* thd_arg, const char *name_arg, size_t name_len_arg, |
3064 | const char *val_arg, size_t val_len_arg, Item_result type_arg, |
3065 | uint charset_number_arg, uchar flags_arg, |
3066 | bool using_trans, bool direct) |
3067 | :Log_event(thd_arg, 0, using_trans), |
3068 | name(name_arg), name_len(name_len_arg), val(val_arg), |
3069 | val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg), |
3070 | flags(flags_arg), deferred(false) |
3071 | { |
3072 | is_null= !val; |
3073 | if (direct) |
3074 | cache_type= Log_event::EVENT_NO_CACHE; |
3075 | } |
3076 | void pack_info(Protocol* protocol); |
3077 | #else |
3078 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3079 | #endif |
3080 | |
3081 | User_var_log_event(const char* buf, uint event_len, |
3082 | const Format_description_log_event *description_event); |
3083 | ~User_var_log_event() {} |
3084 | Log_event_type get_type_code() { return USER_VAR_EVENT;} |
3085 | #ifdef MYSQL_SERVER |
3086 | bool write(); |
3087 | /* |
3088 | Getter and setter for deferred User-event. |
3089 | Returns true if the event is not applied directly |
3090 | and which case the applier adjusts execution path. |
3091 | */ |
3092 | bool is_deferred() { return deferred; } |
3093 | /* |
3094 | In case of the deffered applying the variable instance is flagged |
3095 | and the parsing time query id is stored to be used at applying time. |
3096 | */ |
3097 | void set_deferred(query_id_t qid) { deferred= true; query_id= qid; } |
3098 | #endif |
3099 | bool is_valid() const { return name != 0; } |
3100 | bool is_part_of_group() { return 1; } |
3101 | |
3102 | private: |
3103 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3104 | virtual int do_apply_event(rpl_group_info *rgi); |
3105 | virtual int do_update_pos(rpl_group_info *rgi); |
3106 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3107 | #endif |
3108 | }; |
3109 | |
3110 | |
3111 | /** |
3112 | @class Stop_log_event |
3113 | |
3114 | @section Stop_log_event_binary_format Binary Format |
3115 | |
3116 | The Post-Header and Body for this event type are empty; it only has |
3117 | the Common-Header. |
3118 | */ |
3119 | class Stop_log_event: public Log_event |
3120 | { |
3121 | public: |
3122 | #ifdef MYSQL_SERVER |
3123 | Stop_log_event() :Log_event() |
3124 | {} |
3125 | #else |
3126 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3127 | #endif |
3128 | |
3129 | Stop_log_event(const char* buf, |
3130 | const Format_description_log_event *description_event): |
3131 | Log_event(buf, description_event) |
3132 | {} |
3133 | ~Stop_log_event() {} |
3134 | Log_event_type get_type_code() { return STOP_EVENT;} |
3135 | bool is_valid() const { return 1; } |
3136 | |
3137 | private: |
3138 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3139 | virtual int do_update_pos(rpl_group_info *rgi); |
3140 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi) |
3141 | { |
3142 | /* |
3143 | Events from ourself should be skipped, but they should not |
3144 | decrease the slave skip counter. |
3145 | */ |
3146 | if (this->server_id == global_system_variables.server_id) |
3147 | return Log_event::EVENT_SKIP_IGNORE; |
3148 | else |
3149 | return Log_event::EVENT_SKIP_NOT; |
3150 | } |
3151 | #endif |
3152 | }; |
3153 | |
3154 | /** |
3155 | @class Rotate_log_event |
3156 | |
3157 | This will be deprecated when we move to using sequence ids. |
3158 | |
3159 | @section Rotate_log_event_binary_format Binary Format |
3160 | |
3161 | The Post-Header has one component: |
3162 | |
3163 | <table> |
3164 | <caption>Post-Header for Rotate_log_event</caption> |
3165 | |
3166 | <tr> |
3167 | <th>Name</th> |
3168 | <th>Format</th> |
3169 | <th>Description</th> |
3170 | </tr> |
3171 | |
3172 | <tr> |
3173 | <td>position</td> |
3174 | <td>8 byte integer</td> |
3175 | <td>The position within the binlog to rotate to.</td> |
3176 | </tr> |
3177 | |
3178 | </table> |
3179 | |
3180 | The Body has one component: |
3181 | |
3182 | <table> |
3183 | <caption>Body for Rotate_log_event</caption> |
3184 | |
3185 | <tr> |
3186 | <th>Name</th> |
3187 | <th>Format</th> |
3188 | <th>Description</th> |
3189 | </tr> |
3190 | |
3191 | <tr> |
3192 | <td>new_log</td> |
3193 | <td>variable length string without trailing zero, extending to the |
3194 | end of the event (determined by the length field of the |
3195 | Common-Header) |
3196 | </td> |
3197 | <td>Name of the binlog to rotate to.</td> |
3198 | </tr> |
3199 | |
3200 | </table> |
3201 | */ |
3202 | |
3203 | class Rotate_log_event: public Log_event |
3204 | { |
3205 | public: |
3206 | enum { |
3207 | DUP_NAME= 2, // if constructor should dup the string argument |
3208 | RELAY_LOG=4 // rotate event for relay log |
3209 | }; |
3210 | const char* new_log_ident; |
3211 | ulonglong pos; |
3212 | uint ident_len; |
3213 | uint flags; |
3214 | #ifdef MYSQL_SERVER |
3215 | Rotate_log_event(const char* new_log_ident_arg, |
3216 | uint ident_len_arg, |
3217 | ulonglong pos_arg, uint flags); |
3218 | #ifdef HAVE_REPLICATION |
3219 | void pack_info(Protocol* protocol); |
3220 | #endif /* HAVE_REPLICATION */ |
3221 | #else |
3222 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3223 | #endif |
3224 | |
3225 | Rotate_log_event(const char* buf, uint event_len, |
3226 | const Format_description_log_event* description_event); |
3227 | ~Rotate_log_event() |
3228 | { |
3229 | if (flags & DUP_NAME) |
3230 | my_free((void*) new_log_ident); |
3231 | } |
3232 | Log_event_type get_type_code() { return ROTATE_EVENT;} |
3233 | my_off_t (my_off_t l __attribute__((unused))) |
3234 | { return LOG_EVENT_MINIMAL_HEADER_LEN; } |
3235 | int get_data_size() { return ident_len + ROTATE_HEADER_LEN;} |
3236 | bool is_valid() const { return new_log_ident != 0; } |
3237 | #ifdef MYSQL_SERVER |
3238 | bool write(); |
3239 | #endif |
3240 | |
3241 | private: |
3242 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3243 | virtual int do_update_pos(rpl_group_info *rgi); |
3244 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3245 | #endif |
3246 | }; |
3247 | |
3248 | |
3249 | class Binlog_checkpoint_log_event: public Log_event |
3250 | { |
3251 | public: |
3252 | char *binlog_file_name; |
3253 | uint binlog_file_len; |
3254 | |
3255 | #ifdef MYSQL_SERVER |
3256 | Binlog_checkpoint_log_event(const char *binlog_file_name_arg, |
3257 | uint binlog_file_len_arg); |
3258 | #ifdef HAVE_REPLICATION |
3259 | void pack_info(Protocol *protocol); |
3260 | #endif |
3261 | #else |
3262 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
3263 | #endif |
3264 | Binlog_checkpoint_log_event(const char *buf, uint event_len, |
3265 | const Format_description_log_event *description_event); |
3266 | ~Binlog_checkpoint_log_event() { my_free(binlog_file_name); } |
3267 | Log_event_type get_type_code() { return BINLOG_CHECKPOINT_EVENT;} |
3268 | int get_data_size() { return binlog_file_len + BINLOG_CHECKPOINT_HEADER_LEN;} |
3269 | bool is_valid() const { return binlog_file_name != 0; } |
3270 | #ifdef MYSQL_SERVER |
3271 | bool write(); |
3272 | enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3273 | #endif |
3274 | }; |
3275 | |
3276 | |
3277 | /** |
3278 | @class Gtid_log_event |
3279 | |
3280 | This event is logged as part of every event group to give the global |
3281 | transaction id (GTID) of that group. |
3282 | |
3283 | It replaces the BEGIN query event used in earlier versions to begin most |
3284 | event groups, but is also used for events that used to be stand-alone. |
3285 | |
3286 | @section Gtid_log_event_binary_format Binary Format |
3287 | |
3288 | The binary format for Gtid_log_event has 6 extra reserved bytes to make the |
3289 | length a total of 19 byte (+ 19 bytes of header in common with all events). |
3290 | This is just the minimal size for a BEGIN query event, which makes it easy |
3291 | to replace this event with such BEGIN event to remain compatible with old |
3292 | slave servers. |
3293 | |
3294 | <table> |
3295 | <caption>Post-Header</caption> |
3296 | |
3297 | <tr> |
3298 | <th>Name</th> |
3299 | <th>Format</th> |
3300 | <th>Description</th> |
3301 | </tr> |
3302 | |
3303 | <tr> |
3304 | <td>seq_no</td> |
3305 | <td>8 byte unsigned integer</td> |
3306 | <td>increasing id within one server_id. Starts at 1, holes in the sequence |
3307 | may occur</td> |
3308 | </tr> |
3309 | |
3310 | <tr> |
3311 | <td>domain_id</td> |
3312 | <td>4 byte unsigned integer</td> |
3313 | <td>Replication domain id, identifying independent replication streams></td> |
3314 | </tr> |
3315 | |
3316 | <tr> |
3317 | <td>flags</td> |
3318 | <td>1 byte bitfield</td> |
3319 | <td>Bit 0 set indicates stand-alone event (no terminating COMMIT)</td> |
3320 | <td>Bit 1 set indicates group commit, and that commit id exists</td> |
3321 | <td>Bit 2 set indicates a transactional event group (can be safely rolled |
3322 | back).</td> |
3323 | <td>Bit 3 set indicates that user allowed optimistic parallel apply (the |
3324 | @@SESSION.replicate_allow_parallel value was true at commit).</td> |
3325 | <td>Bit 4 set indicates that this transaction encountered a row (or other) |
3326 | lock wait during execution.</td> |
3327 | </tr> |
3328 | |
3329 | <tr> |
3330 | <td>Reserved (no group commit) / commit id (group commit) (see flags bit 1)</td> |
3331 | <td>6 bytes / 8 bytes</td> |
3332 | <td>Reserved bytes, set to 0. Maybe be used for future expansion (no |
3333 | group commit). OR commit id, same for all GTIDs in the same group |
3334 | commit (see flags bit 1).</td> |
3335 | </tr> |
3336 | </table> |
3337 | |
3338 | The Body of Gtid_log_event is empty. The total event size is 19 bytes + |
3339 | the normal 19 bytes common-header. |
3340 | */ |
3341 | |
3342 | class Gtid_log_event: public Log_event |
3343 | { |
3344 | public: |
3345 | uint64 seq_no; |
3346 | uint64 commit_id; |
3347 | uint32 domain_id; |
3348 | uchar flags2; |
3349 | |
3350 | /* Flags2. */ |
3351 | |
3352 | /* FL_STANDALONE is set when there is no terminating COMMIT event. */ |
3353 | static const uchar FL_STANDALONE= 1; |
3354 | /* |
3355 | FL_GROUP_COMMIT_ID is set when event group is part of a group commit on the |
3356 | master. Groups with same commit_id are part of the same group commit. |
3357 | */ |
3358 | static const uchar FL_GROUP_COMMIT_ID= 2; |
3359 | /* |
3360 | FL_TRANSACTIONAL is set for an event group that can be safely rolled back |
3361 | (no MyISAM, eg.). |
3362 | */ |
3363 | static const uchar FL_TRANSACTIONAL= 4; |
3364 | /* |
3365 | FL_ALLOW_PARALLEL reflects the (negation of the) value of |
3366 | @@SESSION.skip_parallel_replication at the time of commit. |
3367 | */ |
3368 | static const uchar FL_ALLOW_PARALLEL= 8; |
3369 | /* |
3370 | FL_WAITED is set if a row lock wait (or other wait) is detected during the |
3371 | execution of the transaction. |
3372 | */ |
3373 | static const uchar FL_WAITED= 16; |
3374 | /* FL_DDL is set for event group containing DDL. */ |
3375 | static const uchar FL_DDL= 32; |
3376 | |
3377 | #ifdef MYSQL_SERVER |
3378 | Gtid_log_event(THD *thd_arg, uint64 seq_no, uint32 domain_id, bool standalone, |
3379 | uint16 flags, bool is_transactional, uint64 commit_id); |
3380 | #ifdef HAVE_REPLICATION |
3381 | void pack_info(Protocol *protocol); |
3382 | virtual int do_apply_event(rpl_group_info *rgi); |
3383 | virtual int do_update_pos(rpl_group_info *rgi); |
3384 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3385 | #endif |
3386 | #else |
3387 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
3388 | #endif |
3389 | Gtid_log_event(const char *buf, uint event_len, |
3390 | const Format_description_log_event *description_event); |
3391 | ~Gtid_log_event() { } |
3392 | Log_event_type get_type_code() { return GTID_EVENT; } |
3393 | enum_logged_status logged_status() { return LOGGED_NO_DATA; } |
3394 | int get_data_size() |
3395 | { |
3396 | return GTID_HEADER_LEN + ((flags2 & FL_GROUP_COMMIT_ID) ? 2 : 0); |
3397 | } |
3398 | bool is_valid() const { return seq_no != 0; } |
3399 | #ifdef MYSQL_SERVER |
3400 | bool write(); |
3401 | static int make_compatible_event(String *packet, bool *need_dummy_event, |
3402 | ulong ev_offset, enum enum_binlog_checksum_alg checksum_alg); |
3403 | static bool peek(const char *event_start, size_t event_len, |
3404 | enum enum_binlog_checksum_alg checksum_alg, |
3405 | uint32 *domain_id, uint32 *server_id, uint64 *seq_no, |
3406 | uchar *flags2, const Format_description_log_event *fdev); |
3407 | #endif |
3408 | }; |
3409 | |
3410 | |
3411 | /** |
3412 | @class Gtid_list_log_event |
3413 | |
3414 | This event is logged at the start of every binlog file to record the |
3415 | current replication state: the last global transaction id (GTID) applied |
3416 | on the server within each replication domain. |
3417 | |
3418 | It consists of a list of GTIDs, one for each replication domain ever seen |
3419 | on the server. |
3420 | |
3421 | @section Gtid_list_log_event_binary_format Binary Format |
3422 | |
3423 | <table> |
3424 | <caption>Post-Header</caption> |
3425 | |
3426 | <tr> |
3427 | <th>Name</th> |
3428 | <th>Format</th> |
3429 | <th>Description</th> |
3430 | </tr> |
3431 | |
3432 | <tr> |
3433 | <td>count</td> |
3434 | <td>4 byte unsigned integer</td> |
3435 | <td>The lower 28 bits are the number of GTIDs. The upper 4 bits are |
3436 | flags bits.</td> |
3437 | </tr> |
3438 | </table> |
3439 | |
3440 | <table> |
3441 | <caption>Body</caption> |
3442 | |
3443 | <tr> |
3444 | <th>Name</th> |
3445 | <th>Format</th> |
3446 | <th>Description</th> |
3447 | </tr> |
3448 | |
3449 | <tr> |
3450 | <td>domain_id</td> |
3451 | <td>4 byte unsigned integer</td> |
3452 | <td>Replication domain id of one GTID</td> |
3453 | </tr> |
3454 | |
3455 | <tr> |
3456 | <td>server_id</td> |
3457 | <td>4 byte unsigned integer</td> |
3458 | <td>Server id of one GTID</td> |
3459 | </tr> |
3460 | |
3461 | <tr> |
3462 | <td>seq_no</td> |
3463 | <td>8 byte unsigned integer</td> |
3464 | <td>sequence number of one GTID</td> |
3465 | </tr> |
3466 | </table> |
3467 | |
3468 | The three elements in the body repeat COUNT times to form the GTID list. |
3469 | |
3470 | At the time of writing, only two flag bit are in use. |
3471 | |
3472 | Bit 28 of `count' is used for flag FLAG_UNTIL_REACHED, which is sent in a |
3473 | Gtid_list event from the master to the slave to indicate that the START |
3474 | SLAVE UNTIL master_gtid_pos=xxx condition has been reached. (This flag is |
3475 | only sent in "fake" events generated on the fly, it is not written into |
3476 | the binlog). |
3477 | */ |
3478 | |
3479 | class Gtid_list_log_event: public Log_event |
3480 | { |
3481 | public: |
3482 | uint32 count; |
3483 | uint32 gl_flags; |
3484 | struct rpl_gtid *list; |
3485 | uint64 *sub_id_list; |
3486 | |
3487 | static const uint element_size= 4+4+8; |
3488 | /* Upper bits stored in 'count'. See comment above */ |
3489 | enum gtid_flags |
3490 | { |
3491 | FLAG_UNTIL_REACHED= (1<<28), |
3492 | FLAG_IGN_GTIDS= (1<<29), |
3493 | }; |
3494 | #ifdef MYSQL_SERVER |
3495 | Gtid_list_log_event(rpl_binlog_state *gtid_set, uint32 gl_flags); |
3496 | Gtid_list_log_event(slave_connection_state *gtid_set, uint32 gl_flags); |
3497 | #ifdef HAVE_REPLICATION |
3498 | void pack_info(Protocol *protocol); |
3499 | #endif |
3500 | #else |
3501 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
3502 | #endif |
3503 | Gtid_list_log_event(const char *buf, uint event_len, |
3504 | const Format_description_log_event *description_event); |
3505 | ~Gtid_list_log_event() { my_free(list); my_free(sub_id_list); } |
3506 | Log_event_type get_type_code() { return GTID_LIST_EVENT; } |
3507 | int get_data_size() { |
3508 | /* |
3509 | Replacing with dummy event, needed for older slaves, requires a minimum |
3510 | of 6 bytes in the body. |
3511 | */ |
3512 | return (count==0 ? |
3513 | GTID_LIST_HEADER_LEN+2 : GTID_LIST_HEADER_LEN+count*element_size); |
3514 | } |
3515 | bool is_valid() const { return list != NULL; } |
3516 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3517 | bool to_packet(String *packet); |
3518 | bool write(); |
3519 | virtual int do_apply_event(rpl_group_info *rgi); |
3520 | enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3521 | #endif |
3522 | static bool peek(const char *event_start, size_t event_len, |
3523 | enum enum_binlog_checksum_alg checksum_alg, |
3524 | rpl_gtid **out_gtid_list, uint32 *out_list_len, |
3525 | const Format_description_log_event *fdev); |
3526 | }; |
3527 | |
3528 | |
3529 | /* the classes below are for the new LOAD DATA INFILE logging */ |
3530 | |
3531 | /** |
3532 | @class Create_file_log_event |
3533 | |
3534 | @section Create_file_log_event_binary_format Binary Format |
3535 | */ |
3536 | |
3537 | class Create_file_log_event: public Load_log_event |
3538 | { |
3539 | protected: |
3540 | /* |
3541 | Pretend we are Load event, so we can write out just |
3542 | our Load part - used on the slave when writing event out to |
3543 | SQL_LOAD-*.info file |
3544 | */ |
3545 | bool fake_base; |
3546 | public: |
3547 | uchar* block; |
3548 | const char *event_buf; |
3549 | uint block_len; |
3550 | uint file_id; |
3551 | bool inited_from_old; |
3552 | |
3553 | #ifdef MYSQL_SERVER |
3554 | Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, |
3555 | const char* table_name_arg, |
3556 | List<Item>& fields_arg, |
3557 | bool is_concurrent_arg, |
3558 | enum enum_duplicates handle_dup, bool ignore, |
3559 | uchar* block_arg, uint block_len_arg, |
3560 | bool using_trans); |
3561 | #ifdef HAVE_REPLICATION |
3562 | void pack_info(Protocol* protocol); |
3563 | #endif /* HAVE_REPLICATION */ |
3564 | #else |
3565 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3566 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, |
3567 | bool enable_local); |
3568 | #endif |
3569 | |
3570 | Create_file_log_event(const char* buf, uint event_len, |
3571 | const Format_description_log_event* description_event); |
3572 | ~Create_file_log_event() |
3573 | { |
3574 | my_free((void*) event_buf); |
3575 | } |
3576 | |
3577 | Log_event_type get_type_code() |
3578 | { |
3579 | return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT; |
3580 | } |
3581 | int get_data_size() |
3582 | { |
3583 | return (fake_base ? Load_log_event::get_data_size() : |
3584 | Load_log_event::get_data_size() + |
3585 | 4 + 1 + block_len); |
3586 | } |
3587 | bool is_valid() const { return inited_from_old || block != 0; } |
3588 | #ifdef MYSQL_SERVER |
3589 | bool (); |
3590 | bool write_data_body(); |
3591 | /* |
3592 | Cut out Create_file extentions and |
3593 | write it as Load event - used on the slave |
3594 | */ |
3595 | bool write_base(); |
3596 | #endif |
3597 | |
3598 | private: |
3599 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3600 | virtual int do_apply_event(rpl_group_info *rgi); |
3601 | #endif |
3602 | }; |
3603 | |
3604 | |
3605 | /** |
3606 | @class Append_block_log_event |
3607 | |
3608 | @section Append_block_log_event_binary_format Binary Format |
3609 | */ |
3610 | |
3611 | class Append_block_log_event: public Log_event |
3612 | { |
3613 | public: |
3614 | uchar* block; |
3615 | uint block_len; |
3616 | uint file_id; |
3617 | /* |
3618 | 'db' is filled when the event is created in mysql_load() (the |
3619 | event needs to have a 'db' member to be well filtered by |
3620 | binlog-*-db rules). 'db' is not written to the binlog (it's not |
3621 | used by Append_block_log_event::write()), so it can't be read in |
3622 | the Append_block_log_event(const char* buf, int event_len) |
3623 | constructor. In other words, 'db' is used only for filtering by |
3624 | binlog-*-db rules. Create_file_log_event is different: it's 'db' |
3625 | (which is inherited from Load_log_event) is written to the binlog |
3626 | and can be re-read. |
3627 | */ |
3628 | const char* db; |
3629 | |
3630 | #ifdef MYSQL_SERVER |
3631 | Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg, |
3632 | uint block_len_arg, bool using_trans); |
3633 | #ifdef HAVE_REPLICATION |
3634 | void pack_info(Protocol* protocol); |
3635 | virtual int get_create_or_append() const; |
3636 | #endif /* HAVE_REPLICATION */ |
3637 | #else |
3638 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3639 | #endif |
3640 | |
3641 | Append_block_log_event(const char* buf, uint event_len, |
3642 | const Format_description_log_event |
3643 | *description_event); |
3644 | ~Append_block_log_event() {} |
3645 | Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;} |
3646 | int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} |
3647 | bool is_valid() const { return block != 0; } |
3648 | #ifdef MYSQL_SERVER |
3649 | bool write(); |
3650 | const char* get_db() { return db; } |
3651 | #endif |
3652 | |
3653 | private: |
3654 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3655 | virtual int do_apply_event(rpl_group_info *rgi); |
3656 | #endif |
3657 | }; |
3658 | |
3659 | |
3660 | /** |
3661 | @class Delete_file_log_event |
3662 | |
3663 | @section Delete_file_log_event_binary_format Binary Format |
3664 | */ |
3665 | |
3666 | class Delete_file_log_event: public Log_event |
3667 | { |
3668 | public: |
3669 | uint file_id; |
3670 | const char* db; /* see comment in Append_block_log_event */ |
3671 | |
3672 | #ifdef MYSQL_SERVER |
3673 | Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); |
3674 | #ifdef HAVE_REPLICATION |
3675 | void pack_info(Protocol* protocol); |
3676 | #endif /* HAVE_REPLICATION */ |
3677 | #else |
3678 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3679 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, |
3680 | bool enable_local); |
3681 | #endif |
3682 | |
3683 | Delete_file_log_event(const char* buf, uint event_len, |
3684 | const Format_description_log_event* description_event); |
3685 | ~Delete_file_log_event() {} |
3686 | Log_event_type get_type_code() { return DELETE_FILE_EVENT;} |
3687 | int get_data_size() { return DELETE_FILE_HEADER_LEN ;} |
3688 | bool is_valid() const { return file_id != 0; } |
3689 | #ifdef MYSQL_SERVER |
3690 | bool write(); |
3691 | const char* get_db() { return db; } |
3692 | #endif |
3693 | |
3694 | private: |
3695 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3696 | virtual int do_apply_event(rpl_group_info *rgi); |
3697 | #endif |
3698 | }; |
3699 | |
3700 | |
3701 | /** |
3702 | @class Execute_load_log_event |
3703 | |
3704 | @section Delete_file_log_event_binary_format Binary Format |
3705 | */ |
3706 | |
3707 | class Execute_load_log_event: public Log_event |
3708 | { |
3709 | public: |
3710 | uint file_id; |
3711 | const char* db; /* see comment in Append_block_log_event */ |
3712 | |
3713 | #ifdef MYSQL_SERVER |
3714 | Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); |
3715 | #ifdef HAVE_REPLICATION |
3716 | void pack_info(Protocol* protocol); |
3717 | #endif /* HAVE_REPLICATION */ |
3718 | #else |
3719 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3720 | #endif |
3721 | |
3722 | Execute_load_log_event(const char* buf, uint event_len, |
3723 | const Format_description_log_event |
3724 | *description_event); |
3725 | ~Execute_load_log_event() {} |
3726 | Log_event_type get_type_code() { return EXEC_LOAD_EVENT;} |
3727 | int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} |
3728 | bool is_valid() const { return file_id != 0; } |
3729 | #ifdef MYSQL_SERVER |
3730 | bool write(); |
3731 | const char* get_db() { return db; } |
3732 | #endif |
3733 | |
3734 | private: |
3735 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3736 | virtual int do_apply_event(rpl_group_info *rgi); |
3737 | #endif |
3738 | }; |
3739 | |
3740 | |
3741 | /** |
3742 | @class Begin_load_query_log_event |
3743 | |
3744 | Event for the first block of file to be loaded, its only difference from |
3745 | Append_block event is that this event creates or truncates existing file |
3746 | before writing data. |
3747 | |
3748 | @section Begin_load_query_log_event_binary_format Binary Format |
3749 | */ |
3750 | class Begin_load_query_log_event: public Append_block_log_event |
3751 | { |
3752 | public: |
3753 | #ifdef MYSQL_SERVER |
3754 | Begin_load_query_log_event(THD* thd_arg, const char *db_arg, |
3755 | uchar* block_arg, uint block_len_arg, |
3756 | bool using_trans); |
3757 | #ifdef HAVE_REPLICATION |
3758 | Begin_load_query_log_event(THD* thd); |
3759 | int get_create_or_append() const; |
3760 | #endif /* HAVE_REPLICATION */ |
3761 | #endif |
3762 | Begin_load_query_log_event(const char* buf, uint event_len, |
3763 | const Format_description_log_event |
3764 | *description_event); |
3765 | ~Begin_load_query_log_event() {} |
3766 | Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; } |
3767 | private: |
3768 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3769 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
3770 | #endif |
3771 | }; |
3772 | |
3773 | |
3774 | /* |
3775 | Elements of this enum describe how LOAD DATA handles duplicates. |
3776 | */ |
3777 | enum enum_load_dup_handling { LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE, |
3778 | LOAD_DUP_REPLACE }; |
3779 | |
3780 | /** |
3781 | @class Execute_load_query_log_event |
3782 | |
3783 | Event responsible for LOAD DATA execution, it similar to Query_log_event |
3784 | but before executing the query it substitutes original filename in LOAD DATA |
3785 | query with name of temporary file. |
3786 | |
3787 | @section Execute_load_query_log_event_binary_format Binary Format |
3788 | */ |
3789 | class Execute_load_query_log_event: public Query_log_event |
3790 | { |
3791 | public: |
3792 | uint file_id; // file_id of temporary file |
3793 | uint fn_pos_start; // pointer to the part of the query that should |
3794 | // be substituted |
3795 | uint fn_pos_end; // pointer to the end of this part of query |
3796 | /* |
3797 | We have to store type of duplicate handling explicitly, because |
3798 | for LOAD DATA it also depends on LOCAL option. And this part |
3799 | of query will be rewritten during replication so this information |
3800 | may be lost... |
3801 | */ |
3802 | enum_load_dup_handling dup_handling; |
3803 | |
3804 | #ifdef MYSQL_SERVER |
3805 | Execute_load_query_log_event(THD* thd, const char* query_arg, |
3806 | ulong query_length, uint fn_pos_start_arg, |
3807 | uint fn_pos_end_arg, |
3808 | enum_load_dup_handling dup_handling_arg, |
3809 | bool using_trans, bool direct, |
3810 | bool suppress_use, int errcode); |
3811 | #ifdef HAVE_REPLICATION |
3812 | void pack_info(Protocol* protocol); |
3813 | #endif /* HAVE_REPLICATION */ |
3814 | #else |
3815 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3816 | /* Prints the query as LOAD DATA LOCAL and with rewritten filename */ |
3817 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info, |
3818 | const char *local_fname); |
3819 | #endif |
3820 | Execute_load_query_log_event(const char* buf, uint event_len, |
3821 | const Format_description_log_event |
3822 | *description_event); |
3823 | ~Execute_load_query_log_event() {} |
3824 | |
3825 | Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; } |
3826 | bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; } |
3827 | |
3828 | ulong (); |
3829 | #ifdef MYSQL_SERVER |
3830 | bool (); |
3831 | #endif |
3832 | |
3833 | private: |
3834 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
3835 | virtual int do_apply_event(rpl_group_info *rgi); |
3836 | #endif |
3837 | }; |
3838 | |
3839 | |
3840 | #ifdef MYSQL_CLIENT |
3841 | /** |
3842 | @class Unknown_log_event |
3843 | |
3844 | @section Unknown_log_event_binary_format Binary Format |
3845 | */ |
3846 | class Unknown_log_event: public Log_event |
3847 | { |
3848 | public: |
3849 | enum { UNKNOWN, ENCRYPTED } what; |
3850 | /* |
3851 | Even if this is an unknown event, we still pass description_event to |
3852 | Log_event's ctor, this way we can extract maximum information from the |
3853 | event's header (the unique ID for example). |
3854 | */ |
3855 | Unknown_log_event(const char* buf, |
3856 | const Format_description_log_event *description_event): |
3857 | Log_event(buf, description_event), what(UNKNOWN) |
3858 | {} |
3859 | /* constructor for hopelessly corrupted events */ |
3860 | Unknown_log_event(): Log_event(), what(ENCRYPTED) {} |
3861 | ~Unknown_log_event() {} |
3862 | bool print(FILE* file, PRINT_EVENT_INFO* print_event_info); |
3863 | Log_event_type get_type_code() { return UNKNOWN_EVENT;} |
3864 | bool is_valid() const { return 1; } |
3865 | }; |
3866 | #endif |
3867 | char *str_to_hex(char *to, const char *from, size_t len); |
3868 | |
3869 | /** |
3870 | @class Annotate_rows_log_event |
3871 | |
3872 | In row-based mode, if binlog_annotate_row_events = ON, each group of |
3873 | Table_map_log_events is preceded by an Annotate_rows_log_event which |
3874 | contains the query which caused the subsequent rows operations. |
3875 | |
3876 | The Annotate_rows_log_event has no post-header and its body contains |
3877 | the corresponding query (without trailing zero). Note. The query length |
3878 | is to be calculated as a difference between the whole event length and |
3879 | the common header length. |
3880 | */ |
3881 | class Annotate_rows_log_event: public Log_event |
3882 | { |
3883 | public: |
3884 | #ifndef MYSQL_CLIENT |
3885 | Annotate_rows_log_event(THD*, bool using_trans, bool direct); |
3886 | #endif |
3887 | Annotate_rows_log_event(const char *buf, uint event_len, |
3888 | const Format_description_log_event*); |
3889 | ~Annotate_rows_log_event(); |
3890 | |
3891 | virtual int get_data_size(); |
3892 | virtual Log_event_type get_type_code(); |
3893 | enum_logged_status logged_status() { return LOGGED_NO_DATA; } |
3894 | virtual bool is_valid() const; |
3895 | virtual bool is_part_of_group() { return 1; } |
3896 | |
3897 | #ifndef MYSQL_CLIENT |
3898 | virtual bool (); |
3899 | virtual bool write_data_body(); |
3900 | #endif |
3901 | |
3902 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
3903 | virtual void pack_info(Protocol*); |
3904 | #endif |
3905 | |
3906 | #ifdef MYSQL_CLIENT |
3907 | virtual bool print(FILE*, PRINT_EVENT_INFO*); |
3908 | #endif |
3909 | |
3910 | #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) |
3911 | private: |
3912 | virtual int do_apply_event(rpl_group_info *rgi); |
3913 | virtual int do_update_pos(rpl_group_info *rgi); |
3914 | virtual enum_skip_reason do_shall_skip(rpl_group_info*); |
3915 | #endif |
3916 | |
3917 | private: |
3918 | char *m_query_txt; |
3919 | uint m_query_len; |
3920 | char *m_save_thd_query_txt; |
3921 | uint m_save_thd_query_len; |
3922 | bool m_saved_thd_query; |
3923 | bool m_used_query_txt; |
3924 | }; |
3925 | |
3926 | /** |
3927 | @class Table_map_log_event |
3928 | |
3929 | In row-based mode, every row operation event is preceded by a |
3930 | Table_map_log_event which maps a table definition to a number. The |
3931 | table definition consists of database name, table name, and column |
3932 | definitions. |
3933 | |
3934 | @section Table_map_log_event_binary_format Binary Format |
3935 | |
3936 | The Post-Header has the following components: |
3937 | |
3938 | <table> |
3939 | <caption>Post-Header for Table_map_log_event</caption> |
3940 | |
3941 | <tr> |
3942 | <th>Name</th> |
3943 | <th>Format</th> |
3944 | <th>Description</th> |
3945 | </tr> |
3946 | |
3947 | <tr> |
3948 | <td>table_id</td> |
3949 | <td>6 bytes unsigned integer</td> |
3950 | <td>The number that identifies the table.</td> |
3951 | </tr> |
3952 | |
3953 | <tr> |
3954 | <td>flags</td> |
3955 | <td>2 byte bitfield</td> |
3956 | <td>Reserved for future use; currently always 0.</td> |
3957 | </tr> |
3958 | |
3959 | </table> |
3960 | |
3961 | The Body has the following components: |
3962 | |
3963 | <table> |
3964 | <caption>Body for Table_map_log_event</caption> |
3965 | |
3966 | <tr> |
3967 | <th>Name</th> |
3968 | <th>Format</th> |
3969 | <th>Description</th> |
3970 | </tr> |
3971 | |
3972 | <tr> |
3973 | <td>database_name</td> |
3974 | <td>one byte string length, followed by null-terminated string</td> |
3975 | <td>The name of the database in which the table resides. The name |
3976 | is represented as a one byte unsigned integer representing the |
3977 | number of bytes in the name, followed by length bytes containing |
3978 | the database name, followed by a terminating 0 byte. (Note the |
3979 | redundancy in the representation of the length.) </td> |
3980 | </tr> |
3981 | |
3982 | <tr> |
3983 | <td>table_name</td> |
3984 | <td>one byte string length, followed by null-terminated string</td> |
3985 | <td>The name of the table, encoded the same way as the database |
3986 | name above.</td> |
3987 | </tr> |
3988 | |
3989 | <tr> |
3990 | <td>column_count</td> |
3991 | <td>@ref packed_integer "Packed Integer"</td> |
3992 | <td>The number of columns in the table, represented as a packed |
3993 | variable-length integer.</td> |
3994 | </tr> |
3995 | |
3996 | <tr> |
3997 | <td>column_type</td> |
3998 | <td>List of column_count 1 byte enumeration values</td> |
3999 | <td>The type of each column in the table, listed from left to |
4000 | right. Each byte is mapped to a column type according to the |
4001 | enumeration type enum_field_types defined in mysql_com.h. The |
4002 | mapping of types to numbers is listed in the table @ref |
4003 | Table_table_map_log_event_column_types "below" (along with |
4004 | description of the associated metadata field). </td> |
4005 | </tr> |
4006 | |
4007 | <tr> |
4008 | <td>metadata_length</td> |
4009 | <td>@ref packed_integer "Packed Integer"</td> |
4010 | <td>The length of the following metadata block</td> |
4011 | </tr> |
4012 | |
4013 | <tr> |
4014 | <td>metadata</td> |
4015 | <td>list of metadata for each column</td> |
4016 | <td>For each column from left to right, a chunk of data who's |
4017 | length and semantics depends on the type of the column. The |
4018 | length and semantics for the metadata for each column are listed |
4019 | in the table @ref Table_table_map_log_event_column_types |
4020 | "below".</td> |
4021 | </tr> |
4022 | |
4023 | <tr> |
4024 | <td>null_bits</td> |
4025 | <td>column_count bits, rounded up to nearest byte</td> |
4026 | <td>For each column, a bit indicating whether data in the column |
4027 | can be NULL or not. The number of bytes needed for this is |
4028 | int((column_count+7)/8). The flag for the first column from the |
4029 | left is in the least-significant bit of the first byte, the second |
4030 | is in the second least significant bit of the first byte, the |
4031 | ninth is in the least significant bit of the second byte, and so |
4032 | on. </td> |
4033 | </tr> |
4034 | |
4035 | </table> |
4036 | |
4037 | The table below lists all column types, along with the numerical |
4038 | identifier for it and the size and interpretation of meta-data used |
4039 | to describe the type. |
4040 | |
4041 | @anchor Table_table_map_log_event_column_types |
4042 | <table> |
4043 | <caption>Table_map_log_event column types: numerical identifier and |
4044 | metadata</caption> |
4045 | <tr> |
4046 | <th>Name</th> |
4047 | <th>Identifier</th> |
4048 | <th>Size of metadata in bytes</th> |
4049 | <th>Description of metadata</th> |
4050 | </tr> |
4051 | |
4052 | <tr> |
4053 | <td>MYSQL_TYPE_DECIMAL</td><td>0</td> |
4054 | <td>0</td> |
4055 | <td>No column metadata.</td> |
4056 | </tr> |
4057 | |
4058 | <tr> |
4059 | <td>MYSQL_TYPE_TINY</td><td>1</td> |
4060 | <td>0</td> |
4061 | <td>No column metadata.</td> |
4062 | </tr> |
4063 | |
4064 | <tr> |
4065 | <td>MYSQL_TYPE_SHORT</td><td>2</td> |
4066 | <td>0</td> |
4067 | <td>No column metadata.</td> |
4068 | </tr> |
4069 | |
4070 | <tr> |
4071 | <td>MYSQL_TYPE_LONG</td><td>3</td> |
4072 | <td>0</td> |
4073 | <td>No column metadata.</td> |
4074 | </tr> |
4075 | |
4076 | <tr> |
4077 | <td>MYSQL_TYPE_FLOAT</td><td>4</td> |
4078 | <td>1 byte</td> |
4079 | <td>1 byte unsigned integer, representing the "pack_length", which |
4080 | is equal to sizeof(float) on the server from which the event |
4081 | originates.</td> |
4082 | </tr> |
4083 | |
4084 | <tr> |
4085 | <td>MYSQL_TYPE_DOUBLE</td><td>5</td> |
4086 | <td>1 byte</td> |
4087 | <td>1 byte unsigned integer, representing the "pack_length", which |
4088 | is equal to sizeof(double) on the server from which the event |
4089 | originates.</td> |
4090 | </tr> |
4091 | |
4092 | <tr> |
4093 | <td>MYSQL_TYPE_NULL</td><td>6</td> |
4094 | <td>0</td> |
4095 | <td>No column metadata.</td> |
4096 | </tr> |
4097 | |
4098 | <tr> |
4099 | <td>MYSQL_TYPE_TIMESTAMP</td><td>7</td> |
4100 | <td>0</td> |
4101 | <td>No column metadata.</td> |
4102 | </tr> |
4103 | |
4104 | <tr> |
4105 | <td>MYSQL_TYPE_LONGLONG</td><td>8</td> |
4106 | <td>0</td> |
4107 | <td>No column metadata.</td> |
4108 | </tr> |
4109 | |
4110 | <tr> |
4111 | <td>MYSQL_TYPE_INT24</td><td>9</td> |
4112 | <td>0</td> |
4113 | <td>No column metadata.</td> |
4114 | </tr> |
4115 | |
4116 | <tr> |
4117 | <td>MYSQL_TYPE_DATE</td><td>10</td> |
4118 | <td>0</td> |
4119 | <td>No column metadata.</td> |
4120 | </tr> |
4121 | |
4122 | <tr> |
4123 | <td>MYSQL_TYPE_TIME</td><td>11</td> |
4124 | <td>0</td> |
4125 | <td>No column metadata.</td> |
4126 | </tr> |
4127 | |
4128 | <tr> |
4129 | <td>MYSQL_TYPE_DATETIME</td><td>12</td> |
4130 | <td>0</td> |
4131 | <td>No column metadata.</td> |
4132 | </tr> |
4133 | |
4134 | <tr> |
4135 | <td>MYSQL_TYPE_YEAR</td><td>13</td> |
4136 | <td>0</td> |
4137 | <td>No column metadata.</td> |
4138 | </tr> |
4139 | |
4140 | <tr> |
4141 | <td><i>MYSQL_TYPE_NEWDATE</i></td><td><i>14</i></td> |
4142 | <td>–</td> |
4143 | <td><i>This enumeration value is only used internally and cannot |
4144 | exist in a binlog.</i></td> |
4145 | </tr> |
4146 | |
4147 | <tr> |
4148 | <td>MYSQL_TYPE_VARCHAR</td><td>15</td> |
4149 | <td>2 bytes</td> |
4150 | <td>2 byte unsigned integer representing the maximum length of |
4151 | the string.</td> |
4152 | </tr> |
4153 | |
4154 | <tr> |
4155 | <td>MYSQL_TYPE_BIT</td><td>16</td> |
4156 | <td>2 bytes</td> |
4157 | <td>A 1 byte unsigned int representing the length in bits of the |
4158 | bitfield (0 to 64), followed by a 1 byte unsigned int |
4159 | representing the number of bytes occupied by the bitfield. The |
4160 | number of bytes is either int((length+7)/8) or int(length/8).</td> |
4161 | </tr> |
4162 | |
4163 | <tr> |
4164 | <td>MYSQL_TYPE_NEWDECIMAL</td><td>246</td> |
4165 | <td>2 bytes</td> |
4166 | <td>A 1 byte unsigned int representing the precision, followed |
4167 | by a 1 byte unsigned int representing the number of decimals.</td> |
4168 | </tr> |
4169 | |
4170 | <tr> |
4171 | <td><i>MYSQL_TYPE_ENUM</i></td><td><i>247</i></td> |
4172 | <td>–</td> |
4173 | <td><i>This enumeration value is only used internally and cannot |
4174 | exist in a binlog.</i></td> |
4175 | </tr> |
4176 | |
4177 | <tr> |
4178 | <td><i>MYSQL_TYPE_SET</i></td><td><i>248</i></td> |
4179 | <td>–</td> |
4180 | <td><i>This enumeration value is only used internally and cannot |
4181 | exist in a binlog.</i></td> |
4182 | </tr> |
4183 | |
4184 | <tr> |
4185 | <td>MYSQL_TYPE_TINY_BLOB</td><td>249</td> |
4186 | <td>–</td> |
4187 | <td><i>This enumeration value is only used internally and cannot |
4188 | exist in a binlog.</i></td> |
4189 | </tr> |
4190 | |
4191 | <tr> |
4192 | <td><i>MYSQL_TYPE_MEDIUM_BLOB</i></td><td><i>250</i></td> |
4193 | <td>–</td> |
4194 | <td><i>This enumeration value is only used internally and cannot |
4195 | exist in a binlog.</i></td> |
4196 | </tr> |
4197 | |
4198 | <tr> |
4199 | <td><i>MYSQL_TYPE_LONG_BLOB</i></td><td><i>251</i></td> |
4200 | <td>–</td> |
4201 | <td><i>This enumeration value is only used internally and cannot |
4202 | exist in a binlog.</i></td> |
4203 | </tr> |
4204 | |
4205 | <tr> |
4206 | <td>MYSQL_TYPE_BLOB</td><td>252</td> |
4207 | <td>1 byte</td> |
4208 | <td>The pack length, i.e., the number of bytes needed to represent |
4209 | the length of the blob: 1, 2, 3, or 4.</td> |
4210 | </tr> |
4211 | |
4212 | <tr> |
4213 | <td>MYSQL_TYPE_VAR_STRING</td><td>253</td> |
4214 | <td>2 bytes</td> |
4215 | <td>This is used to store both strings and enumeration values. |
4216 | The first byte is a enumeration value storing the <i>real |
4217 | type</i>, which may be either MYSQL_TYPE_VAR_STRING or |
4218 | MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer |
4219 | representing the field size, i.e., the number of bytes needed to |
4220 | store the length of the string.</td> |
4221 | </tr> |
4222 | |
4223 | <tr> |
4224 | <td>MYSQL_TYPE_STRING</td><td>254</td> |
4225 | <td>2 bytes</td> |
4226 | <td>The first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253). |
4227 | The second byte is the field size, i.e., the number of bytes in |
4228 | the representation of size of the string: 3 or 4.</td> |
4229 | </tr> |
4230 | |
4231 | <tr> |
4232 | <td>MYSQL_TYPE_GEOMETRY</td><td>255</td> |
4233 | <td>1 byte</td> |
4234 | <td>The pack length, i.e., the number of bytes needed to represent |
4235 | the length of the geometry: 1, 2, 3, or 4.</td> |
4236 | </tr> |
4237 | |
4238 | </table> |
4239 | */ |
4240 | class Table_map_log_event : public Log_event |
4241 | { |
4242 | public: |
4243 | /* Constants */ |
4244 | enum |
4245 | { |
4246 | TYPE_CODE = TABLE_MAP_EVENT |
4247 | }; |
4248 | |
4249 | /** |
4250 | Enumeration of the errors that can be returned. |
4251 | */ |
4252 | enum enum_error |
4253 | { |
4254 | ERR_OPEN_FAILURE = -1, /**< Failure to open table */ |
4255 | ERR_OK = 0, /**< No error */ |
4256 | ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */ |
4257 | ERR_OUT_OF_MEM = 2, /**< Out of memory */ |
4258 | ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */ |
4259 | ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */ |
4260 | }; |
4261 | |
4262 | enum enum_flag |
4263 | { |
4264 | /* |
4265 | Nothing here right now, but the flags support is there in |
4266 | preparation for changes that are coming. Need to add a |
4267 | constant to make it compile under HP-UX: aCC does not like |
4268 | empty enumerations. |
4269 | */ |
4270 | ENUM_FLAG_COUNT |
4271 | }; |
4272 | |
4273 | typedef uint16 flag_set; |
4274 | |
4275 | /* Special constants representing sets of flags */ |
4276 | enum |
4277 | { |
4278 | TM_NO_FLAGS = 0U, |
4279 | TM_BIT_LEN_EXACT_F = (1U << 0), |
4280 | // MariaDB flags (we starts from the other end) |
4281 | TM_BIT_HAS_TRIGGERS_F= (1U << 14) |
4282 | }; |
4283 | |
4284 | flag_set get_flags(flag_set flag) const { return m_flags & flag; } |
4285 | |
4286 | #ifdef MYSQL_SERVER |
4287 | Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, bool is_transactional); |
4288 | #endif |
4289 | #ifdef HAVE_REPLICATION |
4290 | Table_map_log_event(const char *buf, uint event_len, |
4291 | const Format_description_log_event *description_event); |
4292 | #endif |
4293 | |
4294 | ~Table_map_log_event(); |
4295 | |
4296 | #ifdef MYSQL_CLIENT |
4297 | table_def *create_table_def() |
4298 | { |
4299 | return new table_def(m_coltype, m_colcnt, m_field_metadata, |
4300 | m_field_metadata_size, m_null_bits, m_flags); |
4301 | } |
4302 | int rewrite_db(const char* new_name, size_t new_name_len, |
4303 | const Format_description_log_event*); |
4304 | #endif |
4305 | ulong get_table_id() const { return m_table_id; } |
4306 | const char *get_table_name() const { return m_tblnam; } |
4307 | const char *get_db_name() const { return m_dbnam; } |
4308 | |
4309 | virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } |
4310 | virtual enum_logged_status logged_status() { return LOGGED_TABLE_MAP; } |
4311 | virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } |
4312 | virtual bool is_part_of_group() { return 1; } |
4313 | |
4314 | virtual int get_data_size() { return (uint) m_data_size; } |
4315 | #ifdef MYSQL_SERVER |
4316 | virtual int save_field_metadata(); |
4317 | virtual bool (); |
4318 | virtual bool write_data_body(); |
4319 | virtual const char *get_db() { return m_dbnam; } |
4320 | #endif |
4321 | |
4322 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4323 | virtual void pack_info(Protocol *protocol); |
4324 | #endif |
4325 | |
4326 | #ifdef MYSQL_CLIENT |
4327 | virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4328 | #endif |
4329 | |
4330 | |
4331 | private: |
4332 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4333 | virtual int do_apply_event(rpl_group_info *rgi); |
4334 | virtual int do_update_pos(rpl_group_info *rgi); |
4335 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
4336 | #endif |
4337 | |
4338 | #ifdef MYSQL_SERVER |
4339 | TABLE *m_table; |
4340 | #endif |
4341 | char const *m_dbnam; |
4342 | size_t m_dblen; |
4343 | char const *m_tblnam; |
4344 | size_t m_tbllen; |
4345 | ulong m_colcnt; |
4346 | uchar *m_coltype; |
4347 | |
4348 | uchar *m_memory; |
4349 | ulong m_table_id; |
4350 | flag_set m_flags; |
4351 | |
4352 | size_t m_data_size; |
4353 | |
4354 | uchar *m_field_metadata; // buffer for field metadata |
4355 | /* |
4356 | The size of field metadata buffer set by calling save_field_metadata() |
4357 | */ |
4358 | ulong m_field_metadata_size; |
4359 | uchar *m_null_bits; |
4360 | uchar *m_meta_memory; |
4361 | }; |
4362 | |
4363 | |
4364 | /** |
4365 | @class Rows_log_event |
4366 | |
4367 | Common base class for all row-containing log events. |
4368 | |
4369 | RESPONSIBILITIES |
4370 | |
4371 | Encode the common parts of all events containing rows, which are: |
4372 | - Write data header and data body to an IO_CACHE. |
4373 | - Provide an interface for adding an individual row to the event. |
4374 | |
4375 | @section Rows_log_event_binary_format Binary Format |
4376 | */ |
4377 | |
4378 | |
4379 | class Rows_log_event : public Log_event |
4380 | { |
4381 | public: |
4382 | /** |
4383 | Enumeration of the errors that can be returned. |
4384 | */ |
4385 | enum enum_error |
4386 | { |
4387 | ERR_OPEN_FAILURE = -1, /**< Failure to open table */ |
4388 | ERR_OK = 0, /**< No error */ |
4389 | ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */ |
4390 | ERR_OUT_OF_MEM = 2, /**< Out of memory */ |
4391 | ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */ |
4392 | ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */ |
4393 | }; |
4394 | |
4395 | /* |
4396 | These definitions allow you to combine the flags into an |
4397 | appropriate flag set using the normal bitwise operators. The |
4398 | implicit conversion from an enum-constant to an integer is |
4399 | accepted by the compiler, which is then used to set the real set |
4400 | of flags. |
4401 | */ |
4402 | enum enum_flag |
4403 | { |
4404 | /* Last event of a statement */ |
4405 | STMT_END_F = (1U << 0), |
4406 | |
4407 | /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */ |
4408 | NO_FOREIGN_KEY_CHECKS_F = (1U << 1), |
4409 | |
4410 | /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */ |
4411 | RELAXED_UNIQUE_CHECKS_F = (1U << 2), |
4412 | |
4413 | /** |
4414 | Indicates that rows in this event are complete, that is contain |
4415 | values for all columns of the table. |
4416 | */ |
4417 | COMPLETE_ROWS_F = (1U << 3), |
4418 | |
4419 | /* Value of the OPTION_NO_CHECK_CONSTRAINT_CHECKS flag in thd->options */ |
4420 | NO_CHECK_CONSTRAINT_CHECKS_F = (1U << 7) |
4421 | }; |
4422 | |
4423 | typedef uint16 flag_set; |
4424 | |
4425 | /* Special constants representing sets of flags */ |
4426 | enum |
4427 | { |
4428 | RLE_NO_FLAGS = 0U |
4429 | }; |
4430 | |
4431 | virtual ~Rows_log_event(); |
4432 | |
4433 | void set_flags(flag_set flags_arg) { m_flags |= flags_arg; } |
4434 | void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; } |
4435 | flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } |
4436 | void update_flags() { int2store(temp_buf + m_flags_pos, m_flags); } |
4437 | |
4438 | Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */ |
4439 | enum_logged_status logged_status() { return LOGGED_ROW_EVENT; } |
4440 | virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */ |
4441 | |
4442 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4443 | virtual void pack_info(Protocol *protocol); |
4444 | #endif |
4445 | |
4446 | #ifdef MYSQL_CLIENT |
4447 | /* not for direct call, each derived has its own ::print() */ |
4448 | virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0; |
4449 | void change_to_flashback_event(PRINT_EVENT_INFO *print_event_info, uchar *rows_buff, Log_event_type ev_type); |
4450 | bool print_verbose(IO_CACHE *file, |
4451 | PRINT_EVENT_INFO *print_event_info); |
4452 | size_t print_verbose_one_row(IO_CACHE *file, table_def *td, |
4453 | PRINT_EVENT_INFO *print_event_info, |
4454 | MY_BITMAP *cols_bitmap, |
4455 | const uchar *ptr, const uchar *prefix, |
4456 | const my_bool no_fill_output= 0); // if no_fill_output=1, then print result is unnecessary |
4457 | size_t calc_row_event_length(table_def *td, |
4458 | PRINT_EVENT_INFO *print_event_info, |
4459 | MY_BITMAP *cols_bitmap, |
4460 | const uchar *value); |
4461 | void count_row_events(PRINT_EVENT_INFO *print_event_info); |
4462 | |
4463 | #endif |
4464 | |
4465 | #ifdef MYSQL_SERVER |
4466 | int add_row_data(uchar *data, size_t length) |
4467 | { |
4468 | return do_add_row_data(data,length); |
4469 | } |
4470 | #endif |
4471 | |
4472 | /* Member functions to implement superclass interface */ |
4473 | virtual int get_data_size(); |
4474 | |
4475 | MY_BITMAP const *get_cols() const { return &m_cols; } |
4476 | MY_BITMAP const *get_cols_ai() const { return &m_cols_ai; } |
4477 | size_t get_width() const { return m_width; } |
4478 | ulong get_table_id() const { return m_table_id; } |
4479 | |
4480 | #if defined(MYSQL_SERVER) |
4481 | /* |
4482 | This member function compares the table's read/write_set |
4483 | with this event's m_cols and m_cols_ai. Comparison takes |
4484 | into account what type of rows event is this: Delete, Write or |
4485 | Update, therefore it uses the correct m_cols[_ai] according |
4486 | to the event type code. |
4487 | |
4488 | Note that this member function should only be called for the |
4489 | following events: |
4490 | - Delete_rows_log_event |
4491 | - Write_rows_log_event |
4492 | - Update_rows_log_event |
4493 | |
4494 | @param[IN] table The table to compare this events bitmaps |
4495 | against. |
4496 | |
4497 | @return TRUE if sets match, FALSE otherwise. (following |
4498 | bitmap_cmp return logic). |
4499 | |
4500 | */ |
4501 | bool read_write_bitmaps_cmp(TABLE *table) |
4502 | { |
4503 | bool res= FALSE; |
4504 | |
4505 | switch (get_general_type_code()) |
4506 | { |
4507 | case DELETE_ROWS_EVENT: |
4508 | res= bitmap_cmp(get_cols(), table->read_set); |
4509 | break; |
4510 | case UPDATE_ROWS_EVENT: |
4511 | res= (bitmap_cmp(get_cols(), table->read_set) && |
4512 | bitmap_cmp(get_cols_ai(), table->rpl_write_set)); |
4513 | break; |
4514 | case WRITE_ROWS_EVENT: |
4515 | res= bitmap_cmp(get_cols(), table->rpl_write_set); |
4516 | break; |
4517 | default: |
4518 | /* |
4519 | We should just compare bitmaps for Delete, Write |
4520 | or Update rows events. |
4521 | */ |
4522 | DBUG_ASSERT(0); |
4523 | } |
4524 | return res; |
4525 | } |
4526 | #endif |
4527 | |
4528 | #ifdef MYSQL_SERVER |
4529 | virtual bool (); |
4530 | virtual bool write_data_body(); |
4531 | virtual bool write_compressed(); |
4532 | virtual const char *get_db() { return m_table->s->db.str; } |
4533 | #endif |
4534 | /* |
4535 | Check that malloc() succeeded in allocating memory for the rows |
4536 | buffer and the COLS vector. Checking that an Update_rows_log_event |
4537 | is valid is done in the Update_rows_log_event::is_valid() |
4538 | function. |
4539 | */ |
4540 | virtual bool is_valid() const |
4541 | { |
4542 | return m_rows_buf && m_cols.bitmap; |
4543 | } |
4544 | bool is_part_of_group() { return get_flags(STMT_END_F) != 0; } |
4545 | |
4546 | uint m_row_count; /* The number of rows added to the event */ |
4547 | |
4548 | const uchar* () const { return m_extra_row_data; } |
4549 | |
4550 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4551 | virtual uint8 get_trg_event_map()= 0; |
4552 | #endif |
4553 | |
4554 | protected: |
4555 | /* |
4556 | The constructors are protected since you're supposed to inherit |
4557 | this class, not create instances of this class. |
4558 | */ |
4559 | #ifdef MYSQL_SERVER |
4560 | Rows_log_event(THD*, TABLE*, ulong table_id, |
4561 | MY_BITMAP const *cols, bool is_transactional, |
4562 | Log_event_type event_type); |
4563 | #endif |
4564 | Rows_log_event(const char *row_data, uint event_len, |
4565 | const Format_description_log_event *description_event); |
4566 | void uncompress_buf(); |
4567 | |
4568 | #ifdef MYSQL_CLIENT |
4569 | bool print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name); |
4570 | #endif |
4571 | |
4572 | #ifdef MYSQL_SERVER |
4573 | virtual int do_add_row_data(uchar *data, size_t length); |
4574 | #endif |
4575 | |
4576 | #ifdef MYSQL_SERVER |
4577 | TABLE *m_table; /* The table the rows belong to */ |
4578 | #endif |
4579 | ulong m_table_id; /* Table ID */ |
4580 | MY_BITMAP m_cols; /* Bitmap denoting columns available */ |
4581 | ulong m_width; /* The width of the columns bitmap */ |
4582 | /* |
4583 | Bitmap for columns available in the after image, if present. These |
4584 | fields are only available for Update_rows events. Observe that the |
4585 | width of both the before image COLS vector and the after image |
4586 | COLS vector is the same: the number of columns of the table on the |
4587 | master. |
4588 | */ |
4589 | MY_BITMAP m_cols_ai; |
4590 | |
4591 | ulong m_master_reclength; /* Length of record on master side */ |
4592 | |
4593 | /* Bit buffers in the same memory as the class */ |
4594 | uint32 m_bitbuf[128/(sizeof(uint32)*8)]; |
4595 | uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)]; |
4596 | |
4597 | uchar *m_rows_buf; /* The rows in packed format */ |
4598 | uchar *m_rows_cur; /* One-after the end of the data */ |
4599 | uchar *m_rows_end; /* One-after the end of the allocated space */ |
4600 | |
4601 | size_t m_rows_before_size; /* The length before m_rows_buf */ |
4602 | size_t m_flags_pos; /* The position of the m_flags */ |
4603 | |
4604 | flag_set m_flags; /* Flags for row-level events */ |
4605 | |
4606 | Log_event_type m_type; /* Actual event type */ |
4607 | |
4608 | uchar *; /* Pointer to extra row data if any */ |
4609 | /* If non null, first byte is length */ |
4610 | |
4611 | bool m_vers_from_plain; |
4612 | |
4613 | |
4614 | /* helper functions */ |
4615 | |
4616 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4617 | const uchar *m_curr_row; /* Start of the row being processed */ |
4618 | const uchar *m_curr_row_end; /* One-after the end of the current row */ |
4619 | uchar *m_key; /* Buffer to keep key value during searches */ |
4620 | KEY *m_key_info; /* Pointer to KEY info for m_key_nr */ |
4621 | uint m_key_nr; /* Key number */ |
4622 | bool master_had_triggers; /* set after tables opening */ |
4623 | |
4624 | int find_key(); // Find a best key to use in find_row() |
4625 | int find_row(rpl_group_info *); |
4626 | int write_row(rpl_group_info *, const bool); |
4627 | int update_sequence(); |
4628 | |
4629 | // Unpack the current row into m_table->record[0], but with |
4630 | // a different columns bitmap. |
4631 | int unpack_current_row(rpl_group_info *rgi, MY_BITMAP const *cols) |
4632 | { |
4633 | DBUG_ASSERT(m_table); |
4634 | |
4635 | ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT); |
4636 | return ::unpack_row(rgi, m_table, m_width, m_curr_row, cols, |
4637 | &m_curr_row_end, &m_master_reclength, m_rows_end); |
4638 | } |
4639 | |
4640 | // Unpack the current row into m_table->record[0] |
4641 | int unpack_current_row(rpl_group_info *rgi) |
4642 | { |
4643 | DBUG_ASSERT(m_table); |
4644 | |
4645 | ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT); |
4646 | return ::unpack_row(rgi, m_table, m_width, m_curr_row, &m_cols, |
4647 | &m_curr_row_end, &m_master_reclength, m_rows_end); |
4648 | } |
4649 | bool process_triggers(trg_event_type event, |
4650 | trg_action_time_type time_type, |
4651 | bool old_row_is_record1); |
4652 | |
4653 | /** |
4654 | Helper function to check whether there is an auto increment |
4655 | column on the table where the event is to be applied. |
4656 | |
4657 | @return true if there is an autoincrement field on the extra |
4658 | columns, false otherwise. |
4659 | */ |
4660 | inline bool is_auto_inc_in_extra_columns() |
4661 | { |
4662 | DBUG_ASSERT(m_table); |
4663 | return (m_table->next_number_field && |
4664 | m_table->next_number_field->field_index >= m_width); |
4665 | } |
4666 | #endif |
4667 | |
4668 | private: |
4669 | |
4670 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4671 | virtual int do_apply_event(rpl_group_info *rgi); |
4672 | virtual int do_update_pos(rpl_group_info *rgi); |
4673 | virtual enum_skip_reason do_shall_skip(rpl_group_info *rgi); |
4674 | |
4675 | /* |
4676 | Primitive to prepare for a sequence of row executions. |
4677 | |
4678 | DESCRIPTION |
4679 | |
4680 | Before doing a sequence of do_prepare_row() and do_exec_row() |
4681 | calls, this member function should be called to prepare for the |
4682 | entire sequence. Typically, this member function will allocate |
4683 | space for any buffers that are needed for the two member |
4684 | functions mentioned above. |
4685 | |
4686 | RETURN VALUE |
4687 | |
4688 | The member function will return 0 if all went OK, or a non-zero |
4689 | error code otherwise. |
4690 | */ |
4691 | virtual |
4692 | int do_before_row_operations(const Slave_reporting_capability *const log) = 0; |
4693 | |
4694 | /* |
4695 | Primitive to clean up after a sequence of row executions. |
4696 | |
4697 | DESCRIPTION |
4698 | |
4699 | After doing a sequence of do_prepare_row() and do_exec_row(), |
4700 | this member function should be called to clean up and release |
4701 | any allocated buffers. |
4702 | |
4703 | The error argument, if non-zero, indicates an error which happened during |
4704 | row processing before this function was called. In this case, even if |
4705 | function is successful, it should return the error code given in the argument. |
4706 | */ |
4707 | virtual |
4708 | int do_after_row_operations(const Slave_reporting_capability *const log, |
4709 | int error) = 0; |
4710 | |
4711 | /* |
4712 | Primitive to do the actual execution necessary for a row. |
4713 | |
4714 | DESCRIPTION |
4715 | The member function will do the actual execution needed to handle a row. |
4716 | The row is located at m_curr_row. When the function returns, |
4717 | m_curr_row_end should point at the next row (one byte after the end |
4718 | of the current row). |
4719 | |
4720 | RETURN VALUE |
4721 | 0 if execution succeeded, 1 if execution failed. |
4722 | |
4723 | */ |
4724 | virtual int do_exec_row(rpl_group_info *rli) = 0; |
4725 | #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */ |
4726 | |
4727 | friend class Old_rows_log_event; |
4728 | }; |
4729 | |
4730 | /** |
4731 | @class Write_rows_log_event |
4732 | |
4733 | Log row insertions and updates. The event contain several |
4734 | insert/update rows for a table. Note that each event contains only |
4735 | rows for one table. |
4736 | |
4737 | @section Write_rows_log_event_binary_format Binary Format |
4738 | */ |
4739 | class Write_rows_log_event : public Rows_log_event |
4740 | { |
4741 | public: |
4742 | enum |
4743 | { |
4744 | /* Support interface to THD::binlog_prepare_pending_rows_event */ |
4745 | TYPE_CODE = WRITE_ROWS_EVENT |
4746 | }; |
4747 | |
4748 | #if defined(MYSQL_SERVER) |
4749 | Write_rows_log_event(THD*, TABLE*, ulong table_id, |
4750 | bool is_transactional); |
4751 | #endif |
4752 | #ifdef HAVE_REPLICATION |
4753 | Write_rows_log_event(const char *buf, uint event_len, |
4754 | const Format_description_log_event *description_event); |
4755 | #endif |
4756 | #if defined(MYSQL_SERVER) |
4757 | static bool binlog_row_logging_function(THD *thd, TABLE *table, |
4758 | bool is_transactional, |
4759 | const uchar *before_record |
4760 | __attribute__((unused)), |
4761 | const uchar *after_record) |
4762 | { |
4763 | DBUG_ASSERT(!table->versioned(VERS_TRX_ID)); |
4764 | return thd->binlog_write_row(table, is_transactional, after_record); |
4765 | } |
4766 | #endif |
4767 | |
4768 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4769 | uint8 get_trg_event_map(); |
4770 | #endif |
4771 | |
4772 | private: |
4773 | virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } |
4774 | |
4775 | #ifdef MYSQL_CLIENT |
4776 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4777 | #endif |
4778 | |
4779 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4780 | virtual int do_before_row_operations(const Slave_reporting_capability *const); |
4781 | virtual int do_after_row_operations(const Slave_reporting_capability *const,int); |
4782 | virtual int do_exec_row(rpl_group_info *); |
4783 | #endif |
4784 | }; |
4785 | |
4786 | class Write_rows_compressed_log_event : public Write_rows_log_event |
4787 | { |
4788 | public: |
4789 | #if defined(MYSQL_SERVER) |
4790 | Write_rows_compressed_log_event(THD*, TABLE*, ulong table_id, |
4791 | bool is_transactional); |
4792 | virtual bool write(); |
4793 | #endif |
4794 | #ifdef HAVE_REPLICATION |
4795 | Write_rows_compressed_log_event(const char *buf, uint event_len, |
4796 | const Format_description_log_event *description_event); |
4797 | #endif |
4798 | private: |
4799 | #if defined(MYSQL_CLIENT) |
4800 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4801 | #endif |
4802 | }; |
4803 | |
4804 | /** |
4805 | @class Update_rows_log_event |
4806 | |
4807 | Log row updates with a before image. The event contain several |
4808 | update rows for a table. Note that each event contains only rows for |
4809 | one table. |
4810 | |
4811 | Also note that the row data consists of pairs of row data: one row |
4812 | for the old data and one row for the new data. |
4813 | |
4814 | @section Update_rows_log_event_binary_format Binary Format |
4815 | */ |
4816 | class Update_rows_log_event : public Rows_log_event |
4817 | { |
4818 | public: |
4819 | enum |
4820 | { |
4821 | /* Support interface to THD::binlog_prepare_pending_rows_event */ |
4822 | TYPE_CODE = UPDATE_ROWS_EVENT |
4823 | }; |
4824 | |
4825 | #ifdef MYSQL_SERVER |
4826 | Update_rows_log_event(THD*, TABLE*, ulong table_id, |
4827 | bool is_transactional); |
4828 | |
4829 | void init(MY_BITMAP const *cols); |
4830 | #endif |
4831 | |
4832 | virtual ~Update_rows_log_event(); |
4833 | |
4834 | #ifdef HAVE_REPLICATION |
4835 | Update_rows_log_event(const char *buf, uint event_len, |
4836 | const Format_description_log_event *description_event); |
4837 | #endif |
4838 | |
4839 | #ifdef MYSQL_SERVER |
4840 | static bool binlog_row_logging_function(THD *thd, TABLE *table, |
4841 | bool is_transactional, |
4842 | const uchar *before_record, |
4843 | const uchar *after_record) |
4844 | { |
4845 | DBUG_ASSERT(!table->versioned(VERS_TRX_ID)); |
4846 | return thd->binlog_update_row(table, is_transactional, |
4847 | before_record, after_record); |
4848 | } |
4849 | #endif |
4850 | |
4851 | virtual bool is_valid() const |
4852 | { |
4853 | return Rows_log_event::is_valid() && m_cols_ai.bitmap; |
4854 | } |
4855 | |
4856 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4857 | uint8 get_trg_event_map(); |
4858 | #endif |
4859 | |
4860 | protected: |
4861 | virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } |
4862 | |
4863 | #ifdef MYSQL_CLIENT |
4864 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4865 | #endif |
4866 | |
4867 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4868 | virtual int do_before_row_operations(const Slave_reporting_capability *const); |
4869 | virtual int do_after_row_operations(const Slave_reporting_capability *const,int); |
4870 | virtual int do_exec_row(rpl_group_info *); |
4871 | #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */ |
4872 | }; |
4873 | |
4874 | class Update_rows_compressed_log_event : public Update_rows_log_event |
4875 | { |
4876 | public: |
4877 | #if defined(MYSQL_SERVER) |
4878 | Update_rows_compressed_log_event(THD*, TABLE*, ulong table_id, |
4879 | bool is_transactional); |
4880 | virtual bool write(); |
4881 | #endif |
4882 | #ifdef HAVE_REPLICATION |
4883 | Update_rows_compressed_log_event(const char *buf, uint event_len, |
4884 | const Format_description_log_event *description_event); |
4885 | #endif |
4886 | private: |
4887 | #if defined(MYSQL_CLIENT) |
4888 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4889 | #endif |
4890 | }; |
4891 | |
4892 | /** |
4893 | @class Delete_rows_log_event |
4894 | |
4895 | Log row deletions. The event contain several delete rows for a |
4896 | table. Note that each event contains only rows for one table. |
4897 | |
4898 | RESPONSIBILITIES |
4899 | |
4900 | - Act as a container for rows that has been deleted on the master |
4901 | and should be deleted on the slave. |
4902 | |
4903 | COLLABORATION |
4904 | |
4905 | Row_writer |
4906 | Create the event and add rows to the event. |
4907 | Row_reader |
4908 | Extract the rows from the event. |
4909 | |
4910 | @section Delete_rows_log_event_binary_format Binary Format |
4911 | */ |
4912 | class Delete_rows_log_event : public Rows_log_event |
4913 | { |
4914 | public: |
4915 | enum |
4916 | { |
4917 | /* Support interface to THD::binlog_prepare_pending_rows_event */ |
4918 | TYPE_CODE = DELETE_ROWS_EVENT |
4919 | }; |
4920 | |
4921 | #ifdef MYSQL_SERVER |
4922 | Delete_rows_log_event(THD*, TABLE*, ulong, bool is_transactional); |
4923 | #endif |
4924 | #ifdef HAVE_REPLICATION |
4925 | Delete_rows_log_event(const char *buf, uint event_len, |
4926 | const Format_description_log_event *description_event); |
4927 | #endif |
4928 | #ifdef MYSQL_SERVER |
4929 | static bool binlog_row_logging_function(THD *thd, TABLE *table, |
4930 | bool is_transactional, |
4931 | const uchar *before_record, |
4932 | const uchar *after_record |
4933 | __attribute__((unused))) |
4934 | { |
4935 | DBUG_ASSERT(!table->versioned(VERS_TRX_ID)); |
4936 | return thd->binlog_delete_row(table, is_transactional, |
4937 | before_record); |
4938 | } |
4939 | #endif |
4940 | |
4941 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4942 | uint8 get_trg_event_map(); |
4943 | #endif |
4944 | |
4945 | protected: |
4946 | virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } |
4947 | |
4948 | #ifdef MYSQL_CLIENT |
4949 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4950 | #endif |
4951 | |
4952 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
4953 | virtual int do_before_row_operations(const Slave_reporting_capability *const); |
4954 | virtual int do_after_row_operations(const Slave_reporting_capability *const,int); |
4955 | virtual int do_exec_row(rpl_group_info *); |
4956 | #endif |
4957 | }; |
4958 | |
4959 | class Delete_rows_compressed_log_event : public Delete_rows_log_event |
4960 | { |
4961 | public: |
4962 | #if defined(MYSQL_SERVER) |
4963 | Delete_rows_compressed_log_event(THD*, TABLE*, ulong, bool is_transactional); |
4964 | virtual bool write(); |
4965 | #endif |
4966 | #ifdef HAVE_REPLICATION |
4967 | Delete_rows_compressed_log_event(const char *buf, uint event_len, |
4968 | const Format_description_log_event *description_event); |
4969 | #endif |
4970 | private: |
4971 | #if defined(MYSQL_CLIENT) |
4972 | bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
4973 | #endif |
4974 | }; |
4975 | |
4976 | |
4977 | #include "log_event_old.h" |
4978 | |
4979 | /** |
4980 | @class Incident_log_event |
4981 | |
4982 | Class representing an incident, an occurance out of the ordinary, |
4983 | that happened on the master. |
4984 | |
4985 | The event is used to inform the slave that something out of the |
4986 | ordinary happened on the master that might cause the database to be |
4987 | in an inconsistent state. |
4988 | |
4989 | <table id="IncidentFormat"> |
4990 | <caption>Incident event format</caption> |
4991 | <tr> |
4992 | <th>Symbol</th> |
4993 | <th>Format</th> |
4994 | <th>Description</th> |
4995 | </tr> |
4996 | <tr> |
4997 | <td>INCIDENT</td> |
4998 | <td align="right">2</td> |
4999 | <td>Incident number as an unsigned integer</td> |
5000 | </tr> |
5001 | <tr> |
5002 | <td>MSGLEN</td> |
5003 | <td align="right">1</td> |
5004 | <td>Message length as an unsigned integer</td> |
5005 | </tr> |
5006 | <tr> |
5007 | <td>MESSAGE</td> |
5008 | <td align="right">MSGLEN</td> |
5009 | <td>The message, if present. Not null terminated.</td> |
5010 | </tr> |
5011 | </table> |
5012 | |
5013 | @section Delete_rows_log_event_binary_format Binary Format |
5014 | */ |
5015 | class Incident_log_event : public Log_event { |
5016 | public: |
5017 | #ifdef MYSQL_SERVER |
5018 | Incident_log_event(THD *thd_arg, Incident incident) |
5019 | : Log_event(thd_arg, 0, FALSE), m_incident(incident) |
5020 | { |
5021 | DBUG_ENTER("Incident_log_event::Incident_log_event" ); |
5022 | DBUG_PRINT("enter" , ("m_incident: %d" , m_incident)); |
5023 | m_message.str= NULL; /* Just as a precaution */ |
5024 | m_message.length= 0; |
5025 | set_direct_logging(); |
5026 | /* Replicate the incident irregardless of @@skip_replication. */ |
5027 | flags&= ~LOG_EVENT_SKIP_REPLICATION_F; |
5028 | DBUG_VOID_RETURN; |
5029 | } |
5030 | |
5031 | Incident_log_event(THD *thd_arg, Incident incident, const LEX_CSTRING *msg) |
5032 | : Log_event(thd_arg, 0, FALSE), m_incident(incident) |
5033 | { |
5034 | DBUG_ENTER("Incident_log_event::Incident_log_event" ); |
5035 | DBUG_PRINT("enter" , ("m_incident: %d" , m_incident)); |
5036 | m_message.length= 0; |
5037 | if (unlikely(!(m_message.str= (char*) my_malloc(msg->length+1, |
5038 | MYF(MY_WME))))) |
5039 | { |
5040 | /* Mark this event invalid */ |
5041 | m_incident= INCIDENT_NONE; |
5042 | DBUG_VOID_RETURN; |
5043 | } |
5044 | strmake(m_message.str, msg->str, msg->length); |
5045 | m_message.length= msg->length; |
5046 | set_direct_logging(); |
5047 | /* Replicate the incident irregardless of @@skip_replication. */ |
5048 | flags&= ~LOG_EVENT_SKIP_REPLICATION_F; |
5049 | DBUG_VOID_RETURN; |
5050 | } |
5051 | #endif |
5052 | |
5053 | #ifdef MYSQL_SERVER |
5054 | void pack_info(Protocol*); |
5055 | |
5056 | virtual bool (); |
5057 | virtual bool write_data_body(); |
5058 | #endif |
5059 | |
5060 | Incident_log_event(const char *buf, uint event_len, |
5061 | const Format_description_log_event *descr_event); |
5062 | |
5063 | virtual ~Incident_log_event(); |
5064 | |
5065 | #ifdef MYSQL_CLIENT |
5066 | virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
5067 | #endif |
5068 | |
5069 | #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) |
5070 | virtual int do_apply_event(rpl_group_info *rgi); |
5071 | #endif |
5072 | |
5073 | virtual Log_event_type get_type_code() { return INCIDENT_EVENT; } |
5074 | |
5075 | virtual bool is_valid() const |
5076 | { |
5077 | return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT; |
5078 | } |
5079 | virtual int get_data_size() { |
5080 | return INCIDENT_HEADER_LEN + 1 + (uint) m_message.length; |
5081 | } |
5082 | |
5083 | private: |
5084 | const char *description() const; |
5085 | |
5086 | Incident m_incident; |
5087 | LEX_STRING m_message; |
5088 | }; |
5089 | |
5090 | /** |
5091 | @class Ignorable_log_event |
5092 | |
5093 | Base class for ignorable log events. Events deriving from |
5094 | this class can be safely ignored by slaves that cannot |
5095 | recognize them. Newer slaves, will be able to read and |
5096 | handle them. This has been designed to be an open-ended |
5097 | architecture, so adding new derived events shall not harm |
5098 | the old slaves that support ignorable log event mechanism |
5099 | (they will just ignore unrecognized ignorable events). |
5100 | |
5101 | @note The only thing that makes an event ignorable is that it has |
5102 | the LOG_EVENT_IGNORABLE_F flag set. It is not strictly necessary |
5103 | that ignorable event types derive from Ignorable_log_event; they may |
5104 | just as well derive from Log_event and pass LOG_EVENT_IGNORABLE_F as |
5105 | argument to the Log_event constructor. |
5106 | **/ |
5107 | |
5108 | class Ignorable_log_event : public Log_event { |
5109 | public: |
5110 | int number; |
5111 | const char *description; |
5112 | |
5113 | #ifndef MYSQL_CLIENT |
5114 | Ignorable_log_event(THD *thd_arg) |
5115 | :Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, FALSE), |
5116 | number(0), description("internal" ) |
5117 | { |
5118 | DBUG_ENTER("Ignorable_log_event::Ignorable_log_event" ); |
5119 | DBUG_VOID_RETURN; |
5120 | } |
5121 | #endif |
5122 | |
5123 | Ignorable_log_event(const char *buf, |
5124 | const Format_description_log_event *descr_event, |
5125 | const char *event_name); |
5126 | virtual ~Ignorable_log_event(); |
5127 | |
5128 | #ifndef MYSQL_CLIENT |
5129 | void pack_info(Protocol*); |
5130 | #endif |
5131 | |
5132 | #ifdef MYSQL_CLIENT |
5133 | virtual bool print(FILE *file, PRINT_EVENT_INFO *print_event_info); |
5134 | #endif |
5135 | |
5136 | virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; } |
5137 | |
5138 | virtual bool is_valid() const { return 1; } |
5139 | |
5140 | virtual int get_data_size() { return IGNORABLE_HEADER_LEN; } |
5141 | }; |
5142 | |
5143 | #ifdef MYSQL_SERVER |
5144 | /***************************************************************************** |
5145 | |
5146 | Heartbeat Log Event class |
5147 | |
5148 | Replication event to ensure to slave that master is alive. |
5149 | The event is originated by master's dump thread and sent straight to |
5150 | slave without being logged. Slave itself does not store it in relay log |
5151 | but rather uses a data for immediate checks and throws away the event. |
5152 | |
5153 | Two members of the class log_ident and Log_event::log_pos comprise |
5154 | @see the event_coordinates instance. The coordinates that a heartbeat |
5155 | instance carries correspond to the last event master has sent from |
5156 | its binlog. |
5157 | |
5158 | ****************************************************************************/ |
5159 | class Heartbeat_log_event: public Log_event |
5160 | { |
5161 | public: |
5162 | Heartbeat_log_event(const char* buf, uint event_len, |
5163 | const Format_description_log_event* description_event); |
5164 | Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; } |
5165 | bool is_valid() const |
5166 | { |
5167 | return (log_ident != NULL && |
5168 | log_pos >= BIN_LOG_HEADER_SIZE); |
5169 | } |
5170 | const char * get_log_ident() { return log_ident; } |
5171 | uint get_ident_len() { return ident_len; } |
5172 | |
5173 | private: |
5174 | const char* log_ident; |
5175 | uint ident_len; |
5176 | }; |
5177 | |
5178 | inline int Log_event_writer::write(Log_event *ev) |
5179 | { |
5180 | ev->writer= this; |
5181 | int res= ev->write(); |
5182 | IF_DBUG(ev->writer= 0,); // writer must be set before every Log_event::write |
5183 | add_status(ev->logged_status()); |
5184 | return res; |
5185 | } |
5186 | |
5187 | /** |
5188 | The function is called by slave applier in case there are |
5189 | active table filtering rules to force gathering events associated |
5190 | with Query-log-event into an array to execute |
5191 | them once the fate of the Query is determined for execution. |
5192 | */ |
5193 | bool slave_execute_deferred_events(THD *thd); |
5194 | #endif |
5195 | |
5196 | bool event_that_should_be_ignored(const char *buf); |
5197 | bool event_checksum_test(uchar *buf, ulong event_len, enum_binlog_checksum_alg alg); |
5198 | enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len); |
5199 | extern TYPELIB binlog_checksum_typelib; |
5200 | |
5201 | /** |
5202 | @} (end of group Replication) |
5203 | */ |
5204 | |
5205 | |
5206 | int binlog_buf_compress(const char *src, char *dst, uint32 len, uint32 *comlen); |
5207 | int binlog_buf_uncompress(const char *src, char *dst, uint32 len, uint32 *newlen); |
5208 | uint32 binlog_get_compress_len(uint32 len); |
5209 | uint32 binlog_get_uncompress_len(const char *buf); |
5210 | |
5211 | int query_event_uncompress(const Format_description_log_event *description_event, bool contain_checksum, |
5212 | const char *src, ulong src_len, char* buf, ulong buf_size, bool* is_malloc, |
5213 | char **dst, ulong *newlen); |
5214 | |
5215 | int row_log_event_uncompress(const Format_description_log_event *description_event, bool contain_checksum, |
5216 | const char *src, ulong src_len, char* buf, ulong buf_size, bool* is_malloc, |
5217 | char **dst, ulong *newlen); |
5218 | |
5219 | |
5220 | #endif /* _log_event_h */ |
5221 | |