My Project
|
00001 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software 00014 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 00015 00028 #ifndef _log_event_h 00029 #define _log_event_h 00030 00031 #include <my_bitmap.h> 00032 #include "rpl_constants.h" 00033 #include "table_id.h" 00034 #include <set> 00035 00036 #ifdef MYSQL_CLIENT 00037 #include "sql_const.h" 00038 #include "rpl_utility.h" 00039 #include "hash.h" 00040 #include "rpl_tblmap.h" 00041 #endif 00042 00043 #ifdef MYSQL_SERVER 00044 #include "rpl_record.h" 00045 #include "rpl_reporting.h" 00046 #include "sql_class.h" /* THD */ 00047 #include "rpl_utility.h" /* Hash_slave_rows */ 00048 #include "rpl_filter.h" 00049 #include "key.h" /* key_copy, compare_keys */ 00050 #endif 00051 00052 /* Forward declarations */ 00053 class String; 00054 typedef ulonglong sql_mode_t; 00055 typedef struct st_db_worker_hash_entry db_worker_hash_entry; 00056 00057 #define PREFIX_SQL_LOAD "SQL_LOAD-" 00058 00069 #define TEMP_FILE_MAX_LEN UUID_LENGTH+38 00070 00080 #ifdef DBUG_OFF 00081 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \ 00082 do { if (!(COND)) return ERRNO; } while (0) 00083 #else 00084 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \ 00085 DBUG_ASSERT(COND) 00086 #endif 00087 00088 #define LOG_READ_EOF -1 00089 #define LOG_READ_BOGUS -2 00090 #define LOG_READ_IO -3 00091 #define LOG_READ_MEM -5 00092 #define LOG_READ_TRUNC -6 00093 #define LOG_READ_TOO_LARGE -7 00094 #define LOG_READ_CHECKSUM_FAILURE -8 00095 00096 #define LOG_EVENT_OFFSET 4 00097 00098 /* 00099 3 is MySQL 4.x; 4 is MySQL 5.0.0. 00100 Compared to version 3, version 4 has: 00101 - a different Start_log_event, which includes info about the binary log 00102 (sizes of headers); this info is included for better compatibility if the 00103 master's MySQL version is different from the slave's. 00104 - all events have a unique ID (the triplet (server_id, timestamp at server 00105 start, other) to be sure an event is not executed more than once in a 00106 multimaster setup, example: 00107 M1 00108 / \ 00109 v v 00110 M2 M3 00111 \ / 00112 v v 00113 S 00114 if a query is run on M1, it will arrive twice on S, so we need that S 00115 remembers the last unique ID it has processed, to compare and know if the 00116 event should be skipped or not. Example of ID: we already have the server id 00117 (4 bytes), plus: 00118 timestamp_when_the_master_started (4 bytes), a counter (a sequence number 00119 which increments every time we write an event to the binlog) (3 bytes). 00120 Q: how do we handle when the counter is overflowed and restarts from 0 ? 00121 00122 - Query and Load (Create or Execute) events may have a more precise 00123 timestamp (with microseconds), number of matched/affected/warnings rows 00124 and fields of session variables: SQL_MODE, 00125 FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and 00126 charsets, the PASSWORD() version (old/new/...). 00127 */ 00128 #define BINLOG_VERSION 4 00129 00130 /* 00131 We could have used SERVER_VERSION_LENGTH, but this introduces an 00132 obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH 00133 this would break the replication protocol 00134 */ 00135 #define ST_SERVER_VER_LEN 50 00136 00137 /* 00138 These are flags and structs to handle all the LOAD DATA INFILE options (LINES 00139 TERMINATED etc). 00140 */ 00141 00142 /* 00143 These are flags and structs to handle all the LOAD DATA INFILE options (LINES 00144 TERMINATED etc). 00145 DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD 00146 DATA). 00147 */ 00148 #define DUMPFILE_FLAG 0x1 00149 #define OPT_ENCLOSED_FLAG 0x2 00150 #define REPLACE_FLAG 0x4 00151 #define IGNORE_FLAG 0x8 00152 00153 #define FIELD_TERM_EMPTY 0x1 00154 #define ENCLOSED_EMPTY 0x2 00155 #define LINE_TERM_EMPTY 0x4 00156 #define LINE_START_EMPTY 0x8 00157 #define ESCAPED_EMPTY 0x10 00158 00159 /***************************************************************************** 00160 00161 old_sql_ex struct 00162 00163 ****************************************************************************/ 00164 struct old_sql_ex 00165 { 00166 char field_term; 00167 char enclosed; 00168 char line_term; 00169 char line_start; 00170 char escaped; 00171 char opt_flags; 00172 char empty_flags; 00173 }; 00174 00175 #define NUM_LOAD_DELIM_STRS 5 00176 00177 /***************************************************************************** 00178 00179 sql_ex_info struct 00180 00181 ****************************************************************************/ 00182 struct sql_ex_info 00183 { 00184 sql_ex_info() {} /* Remove gcc warning */ 00185 const char* field_term; 00186 const char* enclosed; 00187 const char* line_term; 00188 const char* line_start; 00189 const char* escaped; 00190 int cached_new_format; 00191 uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len; 00192 char opt_flags; 00193 char empty_flags; 00194 00195 // store in new format even if old is possible 00196 void force_new_format() { cached_new_format = 1;} 00197 int data_size() 00198 { 00199 return (new_format() ? 00200 field_term_len + enclosed_len + line_term_len + 00201 line_start_len + escaped_len + 6 : 7); 00202 } 00203 bool write_data(IO_CACHE* file); 00204 const char* init(const char* buf, const char* buf_end, bool use_new_format); 00205 bool new_format() 00206 { 00207 return ((cached_new_format != -1) ? cached_new_format : 00208 (cached_new_format=(field_term_len > 1 || 00209 enclosed_len > 1 || 00210 line_term_len > 1 || line_start_len > 1 || 00211 escaped_len > 1))); 00212 } 00213 }; 00214 00215 /***************************************************************************** 00216 00217 MySQL Binary Log 00218 00219 This log consists of events. Each event has a fixed-length header, 00220 possibly followed by a variable length data body. 00221 00222 The data body consists of an optional fixed length segment (post-header) 00223 and an optional variable length segment. 00224 00225 See the #defines below for the format specifics. 00226 00227 The events which really update data are Query_log_event, 00228 Execute_load_query_log_event and old Load_log_event and 00229 Execute_load_log_event events (Execute_load_query is used together with 00230 Begin_load_query and Append_block events to replicate LOAD DATA INFILE. 00231 Create_file/Append_block/Execute_load (which includes Load_log_event) 00232 were used to replicate LOAD DATA before the 5.0.3). 00233 00234 ****************************************************************************/ 00235 00236 #define LOG_EVENT_HEADER_LEN 19U /* the fixed header length */ 00237 #define OLD_HEADER_LEN 13U /* the fixed header length in 3.23 */ 00238 /* 00239 Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer 00240 header (it will for sure when we have the unique event's ID), but at least 00241 the first 19 bytes are the same in 4.x and 5.0. So when we have the unique 00242 event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but 00243 LOG_EVENT_MINIMAL_HEADER_LEN will remain 19. 00244 */ 00245 #define LOG_EVENT_MINIMAL_HEADER_LEN 19U 00246 00247 /* event-specific post-header sizes */ 00248 // where 3.23, 4.x and 5.0 agree 00249 #define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2) 00250 // where 5.0 differs: 2 for len of N-bytes vars. 00251 #define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2) 00252 #define STOP_HEADER_LEN 0 00253 #define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4) 00254 #define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4) 00255 #define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen) 00256 #define INTVAR_HEADER_LEN 0 00257 #define CREATE_FILE_HEADER_LEN 4 00258 #define APPEND_BLOCK_HEADER_LEN 4 00259 #define EXEC_LOAD_HEADER_LEN 4 00260 #define DELETE_FILE_HEADER_LEN 4 00261 #define NEW_LOAD_HEADER_LEN LOAD_HEADER_LEN 00262 #define RAND_HEADER_LEN 0 00263 #define USER_VAR_HEADER_LEN 0 00264 #define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES) 00265 #define XID_HEADER_LEN 0 00266 #define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN 00267 #define ROWS_HEADER_LEN_V1 8 00268 #define TABLE_MAP_HEADER_LEN 8 00269 #define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1) 00270 #define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN) 00271 #define INCIDENT_HEADER_LEN 2 00272 #define HEARTBEAT_HEADER_LEN 0 00273 #define IGNORABLE_HEADER_LEN 0 00274 #define ROWS_HEADER_LEN_V2 10 00275 00276 /* 00277 The maximum number of updated databases that a status of 00278 Query-log-event can carry. It can redefined within a range 00279 [1.. OVER_MAX_DBS_IN_EVENT_MTS]. 00280 */ 00281 #define MAX_DBS_IN_EVENT_MTS 16 00282 00283 /* 00284 When the actual number of databases exceeds MAX_DBS_IN_EVENT_MTS 00285 the value of OVER_MAX_DBS_IN_EVENT_MTS is is put into the 00286 mts_accessed_dbs status. 00287 */ 00288 #define OVER_MAX_DBS_IN_EVENT_MTS 254 00289 00290 /* 00291 Max number of possible extra bytes in a replication event compared to a 00292 packet (i.e. a query) sent from client to master; 00293 First, an auxiliary log_event status vars estimation: 00294 */ 00295 #define MAX_SIZE_LOG_EVENT_STATUS (1U + 4 /* type, flags2 */ + \ 00296 1U + 8 /* type, sql_mode */ + \ 00297 1U + 1 + 255 /* type, length, catalog */ + \ 00298 1U + 4 /* type, auto_increment */ + \ 00299 1U + 6 /* type, charset */ + \ 00300 1U + 1 + 255 /* type, length, time_zone */ + \ 00301 1U + 2 /* type, lc_time_names_number */ + \ 00302 1U + 2 /* type, charset_database_number */ + \ 00303 1U + 8 /* type, table_map_for_update */ + \ 00304 1U + 4 /* type, master_data_written */ + \ 00305 /* type, db_1, db_2, ... */ \ 00306 1U + (MAX_DBS_IN_EVENT_MTS * (1 + NAME_LEN)) + \ 00307 3U + /* type, microseconds */ + \ 00308 1U + 16 + 1 + 60/* type, user_len, user, host_len, host */) 00309 #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ 00310 LOG_EVENT_HEADER_LEN + /* write_header */ \ 00311 QUERY_HEADER_LEN + /* write_data */ \ 00312 EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \ 00313 MAX_SIZE_LOG_EVENT_STATUS + /* status */ \ 00314 NAME_LEN + 1) 00315 00316 /* 00317 The new option is added to handle large packets that are sent from the master 00318 to the slave. It is used to increase the thd(max_allowed) for both the 00319 DUMP thread on the master and the SQL/IO thread on the slave. 00320 */ 00321 #define MAX_MAX_ALLOWED_PACKET 1024*1024*1024 00322 00323 /* 00324 Event header offsets; 00325 these point to places inside the fixed header. 00326 */ 00327 00328 #define EVENT_TYPE_OFFSET 4 00329 #define SERVER_ID_OFFSET 5 00330 #define EVENT_LEN_OFFSET 9 00331 #define LOG_POS_OFFSET 13 00332 #define FLAGS_OFFSET 17 00333 00334 /* start event post-header (for v3 and v4) */ 00335 00336 #define ST_BINLOG_VER_OFFSET 0 00337 #define ST_SERVER_VER_OFFSET 2 00338 #define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN) 00339 #define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4) 00340 00341 /* slave event post-header (this event is never written) */ 00342 00343 #define SL_MASTER_PORT_OFFSET 8 00344 #define SL_MASTER_POS_OFFSET 0 00345 #define SL_MASTER_HOST_OFFSET 10 00346 00347 /* query event post-header */ 00348 00349 #define Q_THREAD_ID_OFFSET 0 00350 #define Q_EXEC_TIME_OFFSET 4 00351 #define Q_DB_LEN_OFFSET 8 00352 #define Q_ERR_CODE_OFFSET 9 00353 #define Q_STATUS_VARS_LEN_OFFSET 11 00354 #define Q_DATA_OFFSET QUERY_HEADER_LEN 00355 /* these are codes, not offsets; not more than 256 values (1 byte). */ 00356 #define Q_FLAGS2_CODE 0 00357 #define Q_SQL_MODE_CODE 1 00358 /* 00359 Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL 00360 5.0.x where 0<=x<=3. We have to keep it to be able to replicate these 00361 old masters. 00362 */ 00363 #define Q_CATALOG_CODE 2 00364 #define Q_AUTO_INCREMENT 3 00365 #define Q_CHARSET_CODE 4 00366 #define Q_TIME_ZONE_CODE 5 00367 /* 00368 Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL 00369 5.0.x where x>=4. Saves one byte in every Query_log_event in binlog, 00370 compared to Q_CATALOG_CODE. The reason we didn't simply re-use 00371 Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would 00372 crash (segfault etc) because it would expect a 0 when there is none. 00373 */ 00374 #define Q_CATALOG_NZ_CODE 6 00375 00376 #define Q_LC_TIME_NAMES_CODE 7 00377 00378 #define Q_CHARSET_DATABASE_CODE 8 00379 00380 #define Q_TABLE_MAP_FOR_UPDATE_CODE 9 00381 00382 #define Q_MASTER_DATA_WRITTEN_CODE 10 00383 00384 #define Q_INVOKER 11 00385 00386 /* 00387 Q_UPDATED_DB_NAMES status variable collects of the updated databases 00388 total number and their names to be propagated to the slave in order 00389 to facilitate the parallel applying of the Query events. 00390 */ 00391 #define Q_UPDATED_DB_NAMES 12 00392 00393 #define Q_MICROSECONDS 13 00394 00395 /* Intvar event post-header */ 00396 00397 /* Intvar event data */ 00398 #define I_TYPE_OFFSET 0 00399 #define I_VAL_OFFSET 1 00400 00401 /* Rand event data */ 00402 #define RAND_SEED1_OFFSET 0 00403 #define RAND_SEED2_OFFSET 8 00404 00405 /* User_var event data */ 00406 #define UV_VAL_LEN_SIZE 4 00407 #define UV_VAL_IS_NULL 1 00408 #define UV_VAL_TYPE_SIZE 1 00409 #define UV_NAME_LEN_SIZE 4 00410 #define UV_CHARSET_NUMBER_SIZE 4 00411 00412 /* Load event post-header */ 00413 #define L_THREAD_ID_OFFSET 0 00414 #define L_EXEC_TIME_OFFSET 4 00415 #define L_SKIP_LINES_OFFSET 8 00416 #define L_TBL_LEN_OFFSET 12 00417 #define L_DB_LEN_OFFSET 13 00418 #define L_NUM_FIELDS_OFFSET 14 00419 #define L_SQL_EX_OFFSET 18 00420 #define L_DATA_OFFSET LOAD_HEADER_LEN 00421 00422 /* Rotate event post-header */ 00423 #define R_POS_OFFSET 0 00424 #define R_IDENT_OFFSET 8 00425 00426 /* CF to DF handle LOAD DATA INFILE */ 00427 00428 /* CF = "Create File" */ 00429 #define CF_FILE_ID_OFFSET 0 00430 #define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN 00431 00432 /* AB = "Append Block" */ 00433 #define AB_FILE_ID_OFFSET 0 00434 #define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN 00435 00436 /* EL = "Execute Load" */ 00437 #define EL_FILE_ID_OFFSET 0 00438 00439 /* DF = "Delete File" */ 00440 #define DF_FILE_ID_OFFSET 0 00441 00442 /* TM = "Table Map" */ 00443 #define TM_MAPID_OFFSET 0 00444 #define TM_FLAGS_OFFSET 6 00445 00446 /* RW = "RoWs" */ 00447 #define RW_MAPID_OFFSET 0 00448 #define RW_FLAGS_OFFSET 6 00449 #define RW_VHLEN_OFFSET 8 00450 #define RW_V_TAG_LEN 1 00451 #define RW_V_EXTRAINFO_TAG 0 00452 00453 /* ELQ = "Execute Load Query" */ 00454 #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN 00455 #define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4 00456 #define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8 00457 #define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12 00458 00459 /* 4 bytes which all binlogs should begin with */ 00460 #define BINLOG_MAGIC "\xfe\x62\x69\x6e" 00461 00462 /* 00463 The 2 flags below were useless : 00464 - the first one was never set 00465 - the second one was set in all Rotate events on the master, but not used for 00466 anything useful. 00467 So they are now removed and their place may later be reused for other 00468 flags. Then one must remember that Rotate events in 4.x have 00469 LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the 00470 replacing flag when reading a Rotate event. 00471 I keep the defines here just to remember what they were. 00472 */ 00473 #ifdef TO_BE_REMOVED 00474 #define LOG_EVENT_TIME_F 0x1 00475 #define LOG_EVENT_FORCED_ROTATE_F 0x2 00476 #endif 00477 00478 /* 00479 This flag only makes sense for Format_description_log_event. It is set 00480 when the event is written, and *reset* when a binlog file is 00481 closed (yes, it's the only case when MySQL modifies already written 00482 part of binlog). Thus it is a reliable indicator that binlog was 00483 closed correctly. (Stop_log_event is not enough, there's always a 00484 small chance that mysqld crashes in the middle of insert and end of 00485 the binlog would look like a Stop_log_event). 00486 00487 This flag is used to detect a restart after a crash, and to provide 00488 "unbreakable" binlog. The problem is that on a crash storage engines 00489 rollback automatically, while binlog does not. To solve this we use this 00490 flag and automatically append ROLLBACK to every non-closed binlog (append 00491 virtually, on reading, file itself is not changed). If this flag is found, 00492 mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on 00493 binlog corruption, but takes it as EOF, and replication slave forces a 00494 rollback in this case. 00495 00496 Note, that old binlogs does not have this flag set, so we get a 00497 a backward-compatible behaviour. 00498 */ 00499 00500 #define LOG_EVENT_BINLOG_IN_USE_F 0x1 00501 00510 #define LOG_EVENT_THREAD_SPECIFIC_F 0x4 00511 00525 #define LOG_EVENT_SUPPRESS_USE_F 0x8 00526 00527 /* 00528 Note: this is a place holder for the flag 00529 LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any 00530 more, please do not reused this value for other flags. 00531 */ 00532 00542 #define LOG_EVENT_ARTIFICIAL_F 0x20 00543 00550 #define LOG_EVENT_RELAY_LOG_F 0x40 00551 00561 #define LOG_EVENT_IGNORABLE_F 0x80 00562 00570 #define LOG_EVENT_NO_FILTER_F 0x100 00571 00581 #define LOG_EVENT_MTS_ISOLATE_F 0x200 00582 00583 00605 #define OPTIONS_WRITTEN_TO_BIN_LOG \ 00606 (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \ 00607 OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT) 00608 00609 /* Shouldn't be defined before */ 00610 #define EXPECTED_OPTIONS \ 00611 ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19)) 00612 00613 #if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS 00614 #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values! 00615 #endif 00616 #undef EXPECTED_OPTIONS /* You shouldn't use this one */ 00617 00618 enum enum_binlog_checksum_alg { 00619 BINLOG_CHECKSUM_ALG_OFF= 0, // Events are without checksum though its generator 00620 // is checksum-capable New Master (NM). 00621 BINLOG_CHECKSUM_ALG_CRC32= 1, // CRC32 of zlib algorithm. 00622 BINLOG_CHECKSUM_ALG_ENUM_END, // the cut line: valid alg range is [1, 0x7f]. 00623 BINLOG_CHECKSUM_ALG_UNDEF= 255 // special value to tag undetermined yet checksum 00624 // or events from checksum-unaware servers 00625 }; 00626 00627 #define CHECKSUM_CRC32_SIGNATURE_LEN 4 00628 00631 #define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN 00632 #define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */ 00633 00639 enum Log_event_type 00640 { 00641 /* 00642 Every time you update this enum (when you add a type), you have to 00643 fix Format_description_log_event::Format_description_log_event(). 00644 */ 00645 UNKNOWN_EVENT= 0, 00646 START_EVENT_V3= 1, 00647 QUERY_EVENT= 2, 00648 STOP_EVENT= 3, 00649 ROTATE_EVENT= 4, 00650 INTVAR_EVENT= 5, 00651 LOAD_EVENT= 6, 00652 SLAVE_EVENT= 7, /* Unused. Slave_log_event code has been removed. (15th Oct. 2010) */ 00653 CREATE_FILE_EVENT= 8, 00654 APPEND_BLOCK_EVENT= 9, 00655 EXEC_LOAD_EVENT= 10, 00656 DELETE_FILE_EVENT= 11, 00657 /* 00658 NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer 00659 sql_ex, allowing multibyte TERMINATED BY etc; both types share the 00660 same class (Load_log_event) 00661 */ 00662 NEW_LOAD_EVENT= 12, 00663 RAND_EVENT= 13, 00664 USER_VAR_EVENT= 14, 00665 FORMAT_DESCRIPTION_EVENT= 15, 00666 XID_EVENT= 16, 00667 BEGIN_LOAD_QUERY_EVENT= 17, 00668 EXECUTE_LOAD_QUERY_EVENT= 18, 00669 00670 TABLE_MAP_EVENT = 19, 00671 00672 /* 00673 These event numbers were used for 5.1.0 to 5.1.15 and are 00674 therefore obsolete. 00675 */ 00676 PRE_GA_WRITE_ROWS_EVENT = 20, 00677 PRE_GA_UPDATE_ROWS_EVENT = 21, 00678 PRE_GA_DELETE_ROWS_EVENT = 22, 00679 00680 /* 00681 These event numbers are used from 5.1.16 until mysql-trunk-xx 00682 */ 00683 WRITE_ROWS_EVENT_V1 = 23, 00684 UPDATE_ROWS_EVENT_V1 = 24, 00685 DELETE_ROWS_EVENT_V1 = 25, 00686 00687 /* 00688 Something out of the ordinary happened on the master 00689 */ 00690 INCIDENT_EVENT= 26, 00691 00692 /* 00693 Heartbeat event to be send by master at its idle time 00694 to ensure master's online status to slave 00695 */ 00696 HEARTBEAT_LOG_EVENT= 27, 00697 00698 /* 00699 In some situations, it is necessary to send over ignorable 00700 data to the slave: data that a slave can handle in case there 00701 is code for handling it, but which can be ignored if it is not 00702 recognized. 00703 */ 00704 IGNORABLE_LOG_EVENT= 28, 00705 ROWS_QUERY_LOG_EVENT= 29, 00706 00707 /* Version 2 of the Row events */ 00708 WRITE_ROWS_EVENT = 30, 00709 UPDATE_ROWS_EVENT = 31, 00710 DELETE_ROWS_EVENT = 32, 00711 00712 GTID_LOG_EVENT= 33, 00713 ANONYMOUS_GTID_LOG_EVENT= 34, 00714 00715 PREVIOUS_GTIDS_LOG_EVENT= 35, 00716 /* 00717 Add new events here - right above this comment! 00718 Existing events (except ENUM_END_EVENT) should never change their numbers 00719 */ 00720 00721 ENUM_END_EVENT /* end marker */ 00722 }; 00723 00724 /* 00725 The number of types we handle in Format_description_log_event (UNKNOWN_EVENT 00726 is not to be handled, it does not exist in binlogs, it does not have a 00727 format). 00728 */ 00729 #define LOG_EVENT_TYPES (ENUM_END_EVENT-1) 00730 00731 enum Int_event_type 00732 { 00733 INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2 00734 }; 00735 00736 00737 #ifdef MYSQL_SERVER 00738 class String; 00739 class MYSQL_BIN_LOG; 00740 class THD; 00741 #endif 00742 00743 class Format_description_log_event; 00744 class Relay_log_info; 00745 class Slave_worker; 00746 class Slave_committed_queue; 00747 00748 #ifdef MYSQL_CLIENT 00749 enum enum_base64_output_mode { 00750 BASE64_OUTPUT_NEVER= 0, 00751 BASE64_OUTPUT_AUTO= 1, 00752 BASE64_OUTPUT_UNSPEC= 2, 00753 BASE64_OUTPUT_DECODE_ROWS= 3, 00754 /* insert new output modes here */ 00755 BASE64_OUTPUT_MODE_COUNT 00756 }; 00757 00758 /* 00759 A structure for mysqlbinlog to know how to print events 00760 00761 This structure is passed to the event's print() methods, 00762 00763 There are two types of settings stored here: 00764 1. Last db, flags2, sql_mode etc comes from the last printed event. 00765 They are stored so that only the necessary USE and SET commands 00766 are printed. 00767 2. Other information on how to print the events, e.g. short_form, 00768 hexdump_from. These are not dependent on the last event. 00769 */ 00770 typedef struct st_print_event_info 00771 { 00772 /* 00773 Settings for database, sql_mode etc that comes from the last event 00774 that was printed. We cache these so that we don't have to print 00775 them if they are unchanged. 00776 */ 00777 // TODO: have the last catalog here ?? 00778 char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is 00779 bool flags2_inited; 00780 uint32 flags2; 00781 bool sql_mode_inited; 00782 sql_mode_t sql_mode; /* must be same as THD.variables.sql_mode */ 00783 ulong auto_increment_increment, auto_increment_offset; 00784 bool charset_inited; 00785 char charset[6]; // 3 variables, each of them storable in 2 bytes 00786 char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; 00787 uint lc_time_names_number; 00788 uint charset_database_number; 00789 uint thread_id; 00790 bool thread_id_printed; 00791 uint32 server_id_from_fd_event; 00792 00793 st_print_event_info(); 00794 00795 ~st_print_event_info() { 00796 close_cached_file(&head_cache); 00797 close_cached_file(&body_cache); 00798 } 00799 bool init_ok() /* tells if construction was successful */ 00800 { return my_b_inited(&head_cache) && my_b_inited(&body_cache); } 00801 00802 00803 /* Settings on how to print the events */ 00804 bool short_form; 00805 enum_base64_output_mode base64_output_mode; 00806 /* 00807 This is set whenever a Format_description_event is printed. 00808 Later, when an event is printed in base64, this flag is tested: if 00809 no Format_description_event has been seen, it is unsafe to print 00810 the base64 event, so an error message is generated. 00811 */ 00812 bool printed_fd_event; 00813 my_off_t hexdump_from; 00814 uint8 common_header_len; 00815 char delimiter[16]; 00816 00817 uint verbose; 00818 table_mapping m_table_map; 00819 table_mapping m_table_map_ignored; 00820 00821 /* 00822 These two caches are used by the row-based replication events to 00823 collect the header information and the main body of the events 00824 making up a statement. 00825 */ 00826 IO_CACHE head_cache; 00827 IO_CACHE body_cache; 00828 /* Indicate if the body cache has unflushed events */ 00829 bool have_unflushed_events; 00830 00831 /* 00832 True if an event was skipped while printing the events of 00833 a transaction and no COMMIT statement or XID event was ever 00834 output (ie, was filtered out as well). This can be triggered 00835 by the --database option of mysqlbinlog. 00836 00837 False, otherwise. 00838 */ 00839 bool skipped_event_in_transaction; 00840 00841 /* true if gtid_next is set with a value */ 00842 bool is_gtid_next_set; 00843 00844 /* 00845 Determines if the current value of gtid_next needs to be restored 00846 to AUTOMATIC if the binary log would end after the current event. 00847 00848 If the log ends after a transaction, then this should be false. 00849 If the log ends in the middle of a transaction, then this should 00850 be true; this can happen for relay logs where transactions are 00851 split over multiple logs. 00852 00853 Set to true initially, and after a Gtid_log_event is processed. 00854 Set to false if is_gtid_next_set is true. 00855 */ 00856 bool is_gtid_next_valid; 00857 } PRINT_EVENT_INFO; 00858 #endif 00859 00860 /* 00861 A specific to the database-scheduled MTS type. 00862 */ 00863 typedef struct st_mts_db_names 00864 { 00865 const char *name[MAX_DBS_IN_EVENT_MTS]; 00866 int num; 00867 } Mts_db_names; 00868 00869 01000 class Log_event 01001 { 01002 public: 01010 enum enum_skip_reason { 01014 EVENT_SKIP_NOT, 01015 01021 EVENT_SKIP_IGNORE, 01022 01026 EVENT_SKIP_COUNT 01027 }; 01028 01029 protected: 01030 enum enum_event_cache_type 01031 { 01032 EVENT_INVALID_CACHE= 0, 01033 /* 01034 If possible the event should use a non-transactional cache before 01035 being flushed to the binary log. This means that it must be flushed 01036 right after its correspondent statement is completed. 01037 */ 01038 EVENT_STMT_CACHE, 01039 /* 01040 The event should use a transactional cache before being flushed to 01041 the binary log. This means that it must be flushed upon commit or 01042 rollback. 01043 */ 01044 EVENT_TRANSACTIONAL_CACHE, 01045 /* 01046 The event must be written directly to the binary log without going 01047 through any cache. 01048 */ 01049 EVENT_NO_CACHE, 01050 /* 01051 If there is a need for different types, introduce them before this. 01052 */ 01053 EVENT_CACHE_COUNT 01054 }; 01055 01056 enum enum_event_logging_type 01057 { 01058 EVENT_INVALID_LOGGING= 0, 01059 /* 01060 The event must be written to a cache and upon commit or rollback 01061 written to the binary log. 01062 */ 01063 EVENT_NORMAL_LOGGING, 01064 /* 01065 The event must be written to an empty cache and immediatly written 01066 to the binary log without waiting for any other event. 01067 */ 01068 EVENT_IMMEDIATE_LOGGING, 01069 /* 01070 If there is a need for different types, introduce them before this. 01071 */ 01072 EVENT_CACHE_LOGGING_COUNT 01073 }; 01074 01075 public: 01076 /* 01077 The following type definition is to be used whenever data is placed 01078 and manipulated in a common buffer. Use this typedef for buffers 01079 that contain data containing binary and character data. 01080 */ 01081 typedef unsigned char Byte; 01082 01083 /* 01084 The offset in the log where this event originally appeared (it is 01085 preserved in relay logs, making SHOW SLAVE STATUS able to print 01086 coordinates of the event in the master's binlog). Note: when a 01087 transaction is written by the master to its binlog (wrapped in 01088 BEGIN/COMMIT) the log_pos of all the queries it contains is the 01089 one of the BEGIN (this way, when one does SHOW SLAVE STATUS it 01090 sees the offset of the BEGIN, which is logical as rollback may 01091 occur), except the COMMIT query which has its real offset. 01092 */ 01093 my_off_t log_pos; 01094 /* 01095 A temp buffer for read_log_event; it is later analysed according to the 01096 event's type, and its content is distributed in the event-specific fields. 01097 */ 01098 char *temp_buf; 01099 /* 01100 Timestamp on the master(for debugging and replication of 01101 NOW()/TIMESTAMP). It is important for queries and LOAD DATA 01102 INFILE. This is set at the event's creation time, except for Query 01103 and Load (et al.) events where this is set at the query's 01104 execution time, which guarantees good replication (otherwise, we 01105 could have a query and its event with different timestamps). 01106 */ 01107 struct timeval when; 01108 /* The number of seconds the query took to run on the master. */ 01109 ulong exec_time; 01110 /* Number of bytes written by write() function */ 01111 ulong data_written; 01112 01113 /* 01114 The master's server id (is preserved in the relay log; used to 01115 prevent from infinite loops in circular replication). 01116 */ 01117 uint32 server_id; 01118 01119 /* 01120 The server id read from the Binlog. server_id above has 01121 lowest bits of this only according to the value of 01122 opt_server_id_bits 01123 */ 01124 uint32 unmasked_server_id; 01125 01131 uint16 flags; 01132 01137 ulong slave_exec_mode; 01138 01143 enum_event_cache_type event_cache_type; 01144 01149 enum_event_logging_type event_logging_type; 01150 01154 ha_checksum crc; 01155 01162 ulong mts_group_idx; 01163 01169 Relay_log_info *worker; 01170 01174 ulonglong future_event_relay_log_pos; 01175 01176 #ifdef MYSQL_SERVER 01177 THD* thd; 01181 db_worker_hash_entry *mts_assigned_partitions[MAX_DBS_IN_EVENT_MTS]; 01182 01183 Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE, 01184 enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING); 01185 Log_event(THD* thd_arg, uint16 flags_arg, 01186 enum_event_cache_type cache_type_arg, 01187 enum_event_logging_type logging_type_arg); 01188 /* 01189 read_log_event() functions read an event from a binlog or relay 01190 log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the 01191 master (reads master's binlog), the slave IO thread (reads the 01192 event sent by binlog_dump), the slave SQL thread (reads the event 01193 from the relay log). If mutex is 0, the read will proceed without 01194 mutex. We need the description_event to be able to parse the 01195 event (to know the post-header's size); in fact in read_log_event 01196 we detect the event's type, then call the specific event's 01197 constructor and pass description_event as an argument. 01198 */ 01199 static Log_event* read_log_event(IO_CACHE* file, 01200 mysql_mutex_t* log_lock, 01201 const Format_description_log_event 01202 *description_event, 01203 my_bool crc_check); 01204 01229 static int read_log_event(IO_CACHE* file, String* packet, 01230 mysql_mutex_t* log_lock, 01231 uint8 checksum_alg_arg, 01232 const char *log_file_name_arg= NULL, 01233 bool* is_binlog_active= NULL); 01234 /* 01235 init_show_field_list() prepares the column names and types for the 01236 output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG 01237 EVENTS. 01238 */ 01239 static void init_show_field_list(List<Item>* field_list); 01240 #ifdef HAVE_REPLICATION 01241 int net_send(Protocol *protocol, const char* log_name, my_off_t pos); 01242 01250 virtual int pack_info(Protocol *protocol); 01251 01252 #endif /* HAVE_REPLICATION */ 01253 virtual const char* get_db() 01254 { 01255 return thd ? thd->db : 0; 01256 } 01257 #else // ifdef MYSQL_SERVER 01258 Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE, 01259 enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING) 01260 : temp_buf(0), flags(0), event_cache_type(cache_type_arg), 01261 event_logging_type(logging_type_arg) 01262 { } 01263 /* avoid having to link mysqlbinlog against libpthread */ 01264 static Log_event* read_log_event(IO_CACHE* file, 01265 const Format_description_log_event 01266 *description_event, my_bool crc_check); 01267 /* print*() functions are used by mysqlbinlog */ 01268 virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0; 01269 void print_timestamp(IO_CACHE* file, time_t* ts); 01270 void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, 01271 bool is_more); 01272 void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info, 01273 bool is_more); 01274 #endif // ifdef MYSQL_SERVER ... else 01275 /* 01276 The value is set by caller of FD constructor and 01277 Log_event::write_header() for the rest. 01278 In the FD case it's propagated into the last byte 01279 of post_header_len[] at FD::write(). 01280 On the slave side the value is assigned from post_header_len[last] 01281 of the last seen FD event. 01282 */ 01283 uint8 checksum_alg; 01284 01285 static void *operator new(size_t size) 01286 { 01287 return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE)); 01288 } 01289 01290 static void operator delete(void *ptr, size_t) 01291 { 01292 my_free(ptr); 01293 } 01294 01295 /* Placement version of the above operators */ 01296 static void *operator new(size_t, void* ptr) { return ptr; } 01297 static void operator delete(void*, void*) { } 01298 bool wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong data_length); 01299 01300 #ifdef MYSQL_SERVER 01301 bool write_header(IO_CACHE* file, ulong data_length); 01302 bool write_footer(IO_CACHE* file); 01303 my_bool need_checksum(); 01304 01305 virtual bool write(IO_CACHE* file) 01306 { 01307 return(write_header(file, get_data_size()) || 01308 write_data_header(file) || 01309 write_data_body(file) || 01310 write_footer(file)); 01311 } 01312 virtual bool write_data_header(IO_CACHE* file) 01313 { return 0; } 01314 virtual bool write_data_body(IO_CACHE* file __attribute__((unused))) 01315 { return 0; } 01316 inline time_t get_time() 01317 { 01318 if (!when.tv_sec && !when.tv_usec) /* Not previously initialized */ 01319 { 01320 THD *tmp_thd= thd ? thd : current_thd; 01321 if (tmp_thd) 01322 when= tmp_thd->start_time; 01323 else 01324 my_micro_time_to_timeval(my_micro_time(), &when); 01325 } 01326 return (time_t) when.tv_sec; 01327 } 01328 #endif 01329 virtual Log_event_type get_type_code() = 0; 01330 virtual bool is_valid() const = 0; 01331 void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; } 01332 void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; } 01333 bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; } 01334 bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; } 01335 bool is_ignorable_event() const { return flags & LOG_EVENT_IGNORABLE_F; } 01336 bool is_no_filter_event() const { return flags & LOG_EVENT_NO_FILTER_F; } 01337 inline bool is_using_trans_cache() const 01338 { 01339 return (event_cache_type == EVENT_TRANSACTIONAL_CACHE); 01340 } 01341 inline bool is_using_stmt_cache() const 01342 { 01343 return(event_cache_type == EVENT_STMT_CACHE); 01344 } 01345 inline bool is_using_immediate_logging() const 01346 { 01347 return(event_logging_type == EVENT_IMMEDIATE_LOGGING); 01348 } 01349 Log_event(const char* buf, const Format_description_log_event 01350 *description_event); 01351 virtual ~Log_event() { free_temp_buf();} 01352 void register_temp_buf(char* buf) { temp_buf = buf; } 01353 void free_temp_buf() 01354 { 01355 if (temp_buf) 01356 { 01357 my_free(temp_buf); 01358 temp_buf = 0; 01359 } 01360 } 01361 /* 01362 Get event length for simple events. For complicated events the length 01363 is calculated during write() 01364 */ 01365 virtual int get_data_size() { return 0;} 01366 static Log_event* read_log_event(const char* buf, uint event_len, 01367 const char **error, 01368 const Format_description_log_event 01369 *description_event, my_bool crc_check); 01373 static const char* get_type_str(Log_event_type type); 01377 const char* get_type_str(); 01378 01379 /* Return start of query time or current time */ 01380 01381 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 01382 01383 private: 01384 01385 /* 01386 possible decisions by get_mts_execution_mode(). 01387 The execution mode can be PARALLEL or not (thereby sequential 01388 unless impossible at all). When it's sequential it further breaks into 01389 ASYNChronous and SYNChronous. 01390 */ 01391 enum enum_mts_event_exec_mode 01392 { 01393 /* 01394 Event is run by a Worker. 01395 */ 01396 EVENT_EXEC_PARALLEL, 01397 /* 01398 Event is run by Coordinator. 01399 */ 01400 EVENT_EXEC_ASYNC, 01401 /* 01402 Event is run by Coordinator and requires synchronization with Workers. 01403 */ 01404 EVENT_EXEC_SYNC, 01405 /* 01406 Event can't be executed neither by Workers nor Coordinator. 01407 */ 01408 EVENT_EXEC_CAN_NOT 01409 }; 01410 01424 bool is_mts_sequential_exec() 01425 { 01426 return 01427 get_type_code() == START_EVENT_V3 || 01428 get_type_code() == STOP_EVENT || 01429 get_type_code() == ROTATE_EVENT || 01430 get_type_code() == LOAD_EVENT || 01431 get_type_code() == SLAVE_EVENT || 01432 get_type_code() == CREATE_FILE_EVENT || 01433 get_type_code() == DELETE_FILE_EVENT || 01434 get_type_code() == NEW_LOAD_EVENT || 01435 get_type_code() == EXEC_LOAD_EVENT || 01436 get_type_code() == FORMAT_DESCRIPTION_EVENT|| 01437 01438 get_type_code() == INCIDENT_EVENT; 01439 } 01440 01453 enum enum_mts_event_exec_mode get_mts_execution_mode(ulong slave_server_id, 01454 bool mts_in_group) 01455 { 01456 if ((get_type_code() == FORMAT_DESCRIPTION_EVENT && 01457 ((server_id == (uint32) ::server_id) || (log_pos == 0))) || 01458 (get_type_code() == ROTATE_EVENT && 01459 ((server_id == (uint32) ::server_id) || 01460 (log_pos == 0 /* very first fake Rotate (R_f) */ 01461 && mts_in_group /* ignored event turned into R_f at slave stop */)))) 01462 return EVENT_EXEC_ASYNC; 01463 else if (is_mts_sequential_exec()) 01464 return EVENT_EXEC_SYNC; 01465 else 01466 return EVENT_EXEC_PARALLEL; 01467 } 01468 01474 Slave_worker *get_slave_worker(Relay_log_info *rli); 01475 01488 virtual uint8 get_mts_dbs(Mts_db_names *arg) 01489 { 01490 arg->name[0]= get_db(); 01491 01492 return arg->num= mts_number_dbs(); 01493 } 01494 01495 /* 01496 Group of events can be marked to force its execution 01497 in isolation from any other Workers. 01498 Typically that is done for a transaction that contains 01499 a query accessing more than OVER_MAX_DBS_IN_EVENT_MTS databases. 01500 Factually that's a sequential mode where a Worker remains to 01501 be the applier. 01502 */ 01503 virtual void set_mts_isolate_group() 01504 { 01505 DBUG_ASSERT(ends_group() || 01506 get_type_code() == QUERY_EVENT || 01507 get_type_code() == EXEC_LOAD_EVENT || 01508 get_type_code() == EXECUTE_LOAD_QUERY_EVENT); 01509 flags |= LOG_EVENT_MTS_ISOLATE_F; 01510 } 01511 01512 01513 public: 01514 01518 bool contains_partition_info(bool); 01519 01520 /* 01521 @return the number of updated by the event databases. 01522 01523 @note In other than Query-log-event case that's one. 01524 */ 01525 virtual uint8 mts_number_dbs() { return 1; } 01526 01532 bool is_mts_group_isolated() { return flags & LOG_EVENT_MTS_ISOLATE_F; } 01533 01543 virtual bool starts_group() { return FALSE; } 01544 01549 virtual bool ends_group() { return FALSE; } 01550 01559 int apply_event(Relay_log_info *rli); 01560 01569 int update_pos(Relay_log_info *rli) 01570 { 01571 return do_update_pos(rli); 01572 } 01573 01580 enum_skip_reason shall_skip(Relay_log_info *rli) 01581 { 01582 return do_shall_skip(rli); 01583 } 01584 01600 virtual int do_apply_event(Relay_log_info const *rli) 01601 { 01602 return 0; /* Default implementation does nothing */ 01603 } 01604 01605 virtual int do_apply_event_worker(Slave_worker *w); 01606 01607 protected: 01608 01626 enum_skip_reason continue_group(Relay_log_info *rli); 01627 01651 virtual int do_update_pos(Relay_log_info *rli); 01652 01653 01683 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 01684 #endif 01685 }; 01686 01687 01688 /* 01689 One class for each type of event. 01690 Two constructors for each class: 01691 - one to create the event for logging (when the server acts as a master), 01692 called after an update to the database is done, 01693 which accepts parameters like the query, the database, the options for LOAD 01694 DATA INFILE... 01695 - one to create the event from a packet (when the server acts as a slave), 01696 called before reproducing the update, which accepts parameters (like a 01697 buffer). Used to read from the master, from the relay log, and in 01698 mysqlbinlog. This constructor must be format-tolerant. 01699 */ 01700 02041 class Query_log_event: public Log_event 02042 { 02043 LEX_STRING user; 02044 LEX_STRING host; 02045 protected: 02046 Log_event::Byte* data_buf; 02047 public: 02048 const char* query; 02049 const char* catalog; 02050 const char* db; 02051 /* 02052 If we already know the length of the query string 02053 we pass it with q_len, so we would not have to call strlen() 02054 otherwise, set it to 0, in which case, we compute it with strlen() 02055 */ 02056 uint32 q_len; 02057 uint32 db_len; 02058 uint16 error_code; 02059 ulong thread_id; 02060 /* 02061 For events created by Query_log_event::do_apply_event (and 02062 Load_log_event::do_apply_event()) we need the *original* thread 02063 id, to be able to log the event with the original (=master's) 02064 thread id (fix for BUG#1686). 02065 */ 02066 ulong slave_proxy_id; 02067 02068 /* 02069 Binlog format 3 and 4 start to differ (as far as class members are 02070 concerned) from here. 02071 */ 02072 02073 uint catalog_len; // <= 255 char; 0 means uninited 02074 02075 /* 02076 We want to be able to store a variable number of N-bit status vars: 02077 (generally N=32; but N=64 for SQL_MODE) a user may want to log the number 02078 of affected rows (for debugging) while another does not want to lose 4 02079 bytes in this. 02080 The storage on disk is the following: 02081 status_vars_len is part of the post-header, 02082 status_vars are in the variable-length part, after the post-header, before 02083 the db & query. 02084 status_vars on disk is a sequence of pairs (code, value) where 'code' means 02085 'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so 02086 its first byte is its length. For now the order of status vars is: 02087 flags2 - sql_mode - catalog - autoinc - charset 02088 We should add the same thing to Load_log_event, but in fact 02089 LOAD DATA INFILE is going to be logged with a new type of event (logging of 02090 the plain text query), so Load_log_event would be frozen, so no need. The 02091 new way of logging LOAD DATA INFILE would use a derived class of 02092 Query_log_event, so automatically benefit from the work already done for 02093 status variables in Query_log_event. 02094 */ 02095 uint16 status_vars_len; 02096 02097 /* 02098 'flags2' is a second set of flags (on top of those in Log_event), for 02099 session variables. These are thd->options which is & against a mask 02100 (OPTIONS_WRITTEN_TO_BIN_LOG). 02101 flags2_inited helps make a difference between flags2==0 (3.23 or 4.x 02102 master, we don't know flags2, so use the slave server's global options) and 02103 flags2==0 (5.0 master, we know this has a meaning of flags all down which 02104 must influence the query). 02105 */ 02106 bool flags2_inited; 02107 bool sql_mode_inited; 02108 bool charset_inited; 02109 02110 uint32 flags2; 02111 /* In connections sql_mode is 32 bits now but will be 64 bits soon */ 02112 sql_mode_t sql_mode; 02113 ulong auto_increment_increment, auto_increment_offset; 02114 char charset[6]; 02115 uint time_zone_len; /* 0 means uninited */ 02116 const char *time_zone_str; 02117 uint lc_time_names_number; /* 0 means en_US */ 02118 uint charset_database_number; 02119 /* 02120 map for tables that will be updated for a multi-table update query 02121 statement, for other query statements, this will be zero. 02122 */ 02123 ulonglong table_map_for_update; 02124 /* 02125 Holds the original length of a Query_log_event that comes from a 02126 master of version < 5.0 (i.e., binlog_version < 4). When the IO 02127 thread writes the relay log, it augments the Query_log_event with a 02128 Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event 02129 length. This field is initialized to non-zero in the SQL thread when 02130 it reads this augmented event. SQL thread does not write 02131 Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog. 02132 */ 02133 uint32 master_data_written; 02134 /* 02135 number of updated databases by the query and their names. This info 02136 is requested by both Coordinator and Worker. 02137 */ 02138 uchar mts_accessed_dbs; 02139 char mts_accessed_db_names[MAX_DBS_IN_EVENT_MTS][NAME_LEN]; 02140 02141 #ifdef MYSQL_SERVER 02142 02143 Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, 02144 bool using_trans, bool immediate, bool suppress_use, 02145 int error, bool ignore_command= FALSE); 02146 const char* get_db() { return db; } 02147 02158 virtual uint8 get_mts_dbs(Mts_db_names* arg) 02159 { 02160 if (mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) 02161 { 02162 // the empty string db name is special to indicate sequential applying 02163 mts_accessed_db_names[0][0]= 0; 02164 } 02165 else 02166 { 02167 for (uchar i= 0; i < mts_accessed_dbs; i++) 02168 { 02169 char *db_name= mts_accessed_db_names[i]; 02170 02171 // Only default database is rewritten. 02172 if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name)) 02173 { 02174 size_t dummy_len; 02175 const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len); 02176 // db_name != db_filtered means that db_name is rewritten. 02177 if (strcmp(db_name, db_filtered)) 02178 db_name= (char*)db_filtered; 02179 } 02180 arg->name[i]= db_name; 02181 } 02182 } 02183 return arg->num= mts_accessed_dbs; 02184 } 02185 02186 void attach_temp_tables_worker(THD*); 02187 void detach_temp_tables_worker(THD*); 02188 02189 virtual uchar mts_number_dbs() { return mts_accessed_dbs; } 02190 02191 #ifdef HAVE_REPLICATION 02192 int pack_info(Protocol* protocol); 02193 #endif /* HAVE_REPLICATION */ 02194 #else 02195 void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info); 02196 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02197 #endif 02198 02199 Query_log_event(); 02200 Query_log_event(const char* buf, uint event_len, 02201 const Format_description_log_event *description_event, 02202 Log_event_type event_type); 02203 ~Query_log_event() 02204 { 02205 if (data_buf) 02206 my_free(data_buf); 02207 } 02208 Log_event_type get_type_code() { return QUERY_EVENT; } 02209 #ifdef MYSQL_SERVER 02210 bool write(IO_CACHE* file); 02211 virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; } 02212 #endif 02213 bool is_valid() const { return query != 0; } 02214 02215 /* 02216 Returns number of bytes additionaly written to post header by derived 02217 events (so far it is only Execute_load_query event). 02218 */ 02219 virtual ulong get_post_header_size_for_derived() { return 0; } 02220 /* Writes derived event-specific part of post header. */ 02221 02222 public: /* !!! Public in this patch to allow old usage */ 02223 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02224 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 02225 virtual int do_apply_event(Relay_log_info const *rli); 02226 virtual int do_update_pos(Relay_log_info *rli); 02227 02228 int do_apply_event(Relay_log_info const *rli, 02229 const char *query_arg, 02230 uint32 q_len_arg); 02231 #endif /* HAVE_REPLICATION */ 02232 /* 02233 If true, the event always be applied by slave SQL thread or be printed by 02234 mysqlbinlog 02235 */ 02236 bool is_trans_keyword() 02237 { 02238 /* 02239 Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO' 02240 queries input by user was written into log events directly. 02241 So the keywords can be written in both upper case and lower case 02242 together, strncasecmp is used to check both cases. they also could be 02243 binlogged with comments in the front of these keywords. for examples: 02244 / * bla bla * / SAVEPOINT a; 02245 / * bla bla * / ROLLBACK TO a; 02246 but we don't handle these cases and after the patch, both quiries are 02247 binlogged in upper case with no comments. 02248 */ 02249 return !strncmp(query, "BEGIN", q_len) || 02250 !strncmp(query, "COMMIT", q_len) || 02251 !strncasecmp(query, "SAVEPOINT", 9) || 02252 !strncasecmp(query, "ROLLBACK", 8); 02253 } 02259 bool starts_group() { return !strncmp(query, "BEGIN", q_len); } 02260 virtual bool ends_group() 02261 { 02262 return 02263 !strncmp(query, "COMMIT", q_len) || 02264 (!strncasecmp(query, STRING_WITH_LEN("ROLLBACK")) 02265 && strncasecmp(query, STRING_WITH_LEN("ROLLBACK TO "))); 02266 } 02267 }; 02268 02269 02469 class Load_log_event: public Log_event 02470 { 02471 private: 02472 protected: 02473 int copy_log_event(const char *buf, ulong event_len, 02474 int body_offset, 02475 const Format_description_log_event* description_event); 02476 02477 public: 02478 uint get_query_buffer_length(); 02479 void print_query(bool need_db, const char *cs, char *buf, char **end, 02480 char **fn_start, char **fn_end); 02481 ulong thread_id; 02482 ulong slave_proxy_id; 02483 uint32 table_name_len; 02484 /* 02485 No need to have a catalog, as these events can only come from 4.x. 02486 TODO: this may become false if Dmitri pushes his new LOAD DATA INFILE in 02487 5.0 only (not in 4.x). 02488 */ 02489 uint32 db_len; 02490 uint32 fname_len; 02491 uint32 num_fields; 02492 const char* fields; 02493 const uchar* field_lens; 02494 uint32 field_block_len; 02495 02496 const char* table_name; 02497 const char* db; 02498 const char* fname; 02499 uint32 skip_lines; 02500 sql_ex_info sql_ex; 02501 bool local_fname; 02512 bool is_concurrent; 02513 02514 /* fname doesn't point to memory inside Log_event::temp_buf */ 02515 void set_fname_outside_temp_buf(const char *afname, uint alen) 02516 { 02517 fname= afname; 02518 fname_len= alen; 02519 local_fname= TRUE; 02520 } 02521 /* fname doesn't point to memory inside Log_event::temp_buf */ 02522 int check_fname_outside_temp_buf() 02523 { 02524 return local_fname; 02525 } 02526 02527 #ifdef MYSQL_SERVER 02528 String field_lens_buf; 02529 String fields_buf; 02530 02531 Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg, 02532 const char* table_name_arg, 02533 List<Item>& fields_arg, 02534 bool is_concurrent_arg, 02535 enum enum_duplicates handle_dup, bool ignore, 02536 bool using_trans); 02537 void set_fields(const char* db, List<Item> &fields_arg, 02538 Name_resolution_context *context); 02539 const char* get_db() { return db; } 02540 #ifdef HAVE_REPLICATION 02541 int pack_info(Protocol* protocol); 02542 #endif /* HAVE_REPLICATION */ 02543 #else 02544 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02545 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented); 02546 #endif 02547 02548 /* 02549 Note that for all the events related to LOAD DATA (Load_log_event, 02550 Create_file/Append/Exec/Delete, we pass description_event; however as 02551 logging of LOAD DATA is going to be changed in 4.1 or 5.0, this is only used 02552 for the common_header_len (post_header_len will not be changed). 02553 */ 02554 Load_log_event(const char* buf, uint event_len, 02555 const Format_description_log_event* description_event); 02556 ~Load_log_event() 02557 {} 02558 Log_event_type get_type_code() 02559 { 02560 return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT; 02561 } 02562 #ifdef MYSQL_SERVER 02563 bool write_data_header(IO_CACHE* file); 02564 bool write_data_body(IO_CACHE* file); 02565 #endif 02566 bool is_valid() const { return table_name != 0; } 02567 int get_data_size() 02568 { 02569 return (table_name_len + db_len + 2 + fname_len 02570 + LOAD_HEADER_LEN 02571 + sql_ex.data_size() + field_block_len + num_fields); 02572 } 02573 02574 public: /* !!! Public in this patch to allow old usage */ 02575 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02576 virtual int do_apply_event(Relay_log_info const* rli) 02577 { 02578 return do_apply_event(thd->slave_net,rli,0); 02579 } 02580 02581 int do_apply_event(NET *net, Relay_log_info const *rli, 02582 bool use_rli_only_for_errors); 02583 #endif 02584 }; 02585 02586 extern char server_version[SERVER_VERSION_LENGTH]; 02587 02603 class Start_log_event_v3: public Log_event 02604 { 02605 public: 02606 /* 02607 If this event is at the start of the first binary log since server 02608 startup 'created' should be the timestamp when the event (and the 02609 binary log) was created. In the other case (i.e. this event is at 02610 the start of a binary log created by FLUSH LOGS or automatic 02611 rotation), 'created' should be 0. This "trick" is used by MySQL 02612 >=4.0.14 slaves to know whether they must drop stale temporary 02613 tables and whether they should abort unfinished transaction. 02614 02615 Note that when 'created'!=0, it is always equal to the event's 02616 timestamp; indeed Start_log_event is written only in log.cc where 02617 the first constructor below is called, in which 'created' is set 02618 to 'when'. So in fact 'created' is a useless variable. When it is 02619 0 we can read the actual value from timestamp ('when') and when it 02620 is non-zero we can read the same value from timestamp 02621 ('when'). Conclusion: 02622 - we use timestamp to print when the binlog was created. 02623 - we use 'created' only to know if this is a first binlog or not. 02624 In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in 02625 3.23.57 does not print 'created the_date' if created was zero. This is now 02626 fixed. 02627 */ 02628 time_t created; 02629 uint16 binlog_version; 02630 char server_version[ST_SERVER_VER_LEN]; 02631 /* 02632 We set this to 1 if we don't want to have the created time in the log, 02633 which is the case when we rollover to a new log. 02634 */ 02635 bool dont_set_created; 02636 02637 #ifdef MYSQL_SERVER 02638 Start_log_event_v3(); 02639 #ifdef HAVE_REPLICATION 02640 int pack_info(Protocol* protocol); 02641 #endif /* HAVE_REPLICATION */ 02642 #else 02643 Start_log_event_v3() {} 02644 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02645 #endif 02646 02647 Start_log_event_v3(const char* buf, uint event_len, 02648 const Format_description_log_event* description_event); 02649 ~Start_log_event_v3() {} 02650 Log_event_type get_type_code() { return START_EVENT_V3;} 02651 #ifdef MYSQL_SERVER 02652 bool write(IO_CACHE* file); 02653 #endif 02654 bool is_valid() const { return server_version[0] != 0; } 02655 int get_data_size() 02656 { 02657 return START_V3_HEADER_LEN; //no variable-sized part 02658 } 02659 02660 protected: 02661 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02662 virtual int do_apply_event(Relay_log_info const *rli); 02663 virtual enum_skip_reason do_shall_skip(Relay_log_info*) 02664 { 02665 /* 02666 Events from ourself should be skipped, but they should not 02667 decrease the slave skip counter. 02668 */ 02669 if (this->server_id == ::server_id) 02670 return Log_event::EVENT_SKIP_IGNORE; 02671 else 02672 return Log_event::EVENT_SKIP_NOT; 02673 } 02674 #endif 02675 }; 02676 02677 02688 class Format_description_log_event: public Start_log_event_v3 02689 { 02690 public: 02691 /* 02692 The size of the fixed header which _all_ events have 02693 (for binlogs written by this version, this is equal to 02694 LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT 02695 (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN). 02696 */ 02697 uint8 common_header_len; 02698 uint8 number_of_event_types; 02699 /* 02700 The list of post-headers' lengths followed 02701 by the checksum alg decription byte 02702 */ 02703 uint8 *post_header_len; 02704 uchar server_version_split[3]; 02705 const uint8 *event_type_permutation; 02706 02707 Format_description_log_event(uint8 binlog_ver, const char* server_ver=0); 02708 Format_description_log_event(const char* buf, uint event_len, 02709 const Format_description_log_event 02710 *description_event); 02711 ~Format_description_log_event() 02712 { 02713 my_free(post_header_len); 02714 } 02715 Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;} 02716 #ifdef MYSQL_SERVER 02717 bool write(IO_CACHE* file); 02718 #endif 02719 bool header_is_valid() const 02720 { 02721 return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN : 02722 LOG_EVENT_MINIMAL_HEADER_LEN)) && 02723 (post_header_len != NULL)); 02724 } 02725 02726 bool version_is_valid() const 02727 { 02728 /* It is invalid only when all version numbers are 0 */ 02729 return !(server_version_split[0] == 0 && 02730 server_version_split[1] == 0 && 02731 server_version_split[2] == 0); 02732 } 02733 02734 bool is_valid() const 02735 { 02736 return header_is_valid() && version_is_valid(); 02737 } 02738 02739 int get_data_size() 02740 { 02741 /* 02742 The vector of post-header lengths is considered as part of the 02743 post-header, because in a given version it never changes (contrary to the 02744 query in a Query_log_event). 02745 */ 02746 return FORMAT_DESCRIPTION_HEADER_LEN; 02747 } 02748 02749 void calc_server_version_split(); 02750 ulong get_version_product() const; 02751 bool is_version_before_checksum() const; 02752 protected: 02753 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02754 virtual int do_apply_event(Relay_log_info const *rli); 02755 virtual int do_update_pos(Relay_log_info *rli); 02756 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 02757 #endif 02758 }; 02759 02760 02799 class Intvar_log_event: public Log_event 02800 { 02801 public: 02802 ulonglong val; 02803 uchar type; 02804 02805 #ifdef MYSQL_SERVER 02806 Intvar_log_event(THD* thd_arg, uchar type_arg, ulonglong val_arg, 02807 enum_event_cache_type cache_type_arg, 02808 enum_event_logging_type logging_type_arg) 02809 :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), 02810 val(val_arg), type(type_arg) { } 02811 #ifdef HAVE_REPLICATION 02812 int pack_info(Protocol* protocol); 02813 #endif /* HAVE_REPLICATION */ 02814 #else 02815 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02816 #endif 02817 02818 Intvar_log_event(const char* buf, 02819 const Format_description_log_event *description_event); 02820 ~Intvar_log_event() {} 02821 Log_event_type get_type_code() { return INTVAR_EVENT;} 02822 const char* get_var_type_name(); 02823 int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;} 02824 #ifdef MYSQL_SERVER 02825 bool write(IO_CACHE* file); 02826 #endif 02827 bool is_valid() const { return 1; } 02828 02829 private: 02830 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02831 virtual int do_apply_event(Relay_log_info const *rli); 02832 virtual int do_update_pos(Relay_log_info *rli); 02833 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 02834 #endif 02835 }; 02836 02837 02877 class Rand_log_event: public Log_event 02878 { 02879 public: 02880 ulonglong seed1; 02881 ulonglong seed2; 02882 02883 #ifdef MYSQL_SERVER 02884 Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg, 02885 enum_event_cache_type cache_type_arg, 02886 enum_event_logging_type logging_type_arg) 02887 :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), 02888 seed1(seed1_arg), seed2(seed2_arg) { } 02889 #ifdef HAVE_REPLICATION 02890 int pack_info(Protocol* protocol); 02891 #endif /* HAVE_REPLICATION */ 02892 #else 02893 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02894 #endif 02895 02896 Rand_log_event(const char* buf, 02897 const Format_description_log_event *description_event); 02898 ~Rand_log_event() {} 02899 Log_event_type get_type_code() { return RAND_EVENT;} 02900 int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ } 02901 #ifdef MYSQL_SERVER 02902 bool write(IO_CACHE* file); 02903 #endif 02904 bool is_valid() const { return 1; } 02905 02906 private: 02907 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02908 virtual int do_apply_event(Relay_log_info const *rli); 02909 virtual int do_update_pos(Relay_log_info *rli); 02910 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 02911 #endif 02912 }; 02913 02922 #ifdef MYSQL_CLIENT 02923 typedef ulonglong my_xid; // this line is the same as in handler.h 02924 #endif 02925 02926 class Xid_log_event: public Log_event 02927 { 02928 public: 02929 my_xid xid; 02930 02931 #ifdef MYSQL_SERVER 02932 Xid_log_event(THD* thd_arg, my_xid x) 02933 : Log_event(thd_arg, 0, 02934 Log_event::EVENT_TRANSACTIONAL_CACHE, 02935 Log_event::EVENT_NORMAL_LOGGING), 02936 xid(x) 02937 { } 02938 #ifdef HAVE_REPLICATION 02939 int pack_info(Protocol* protocol); 02940 #endif /* HAVE_REPLICATION */ 02941 #else 02942 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 02943 #endif 02944 02945 Xid_log_event(const char* buf, 02946 const Format_description_log_event *description_event); 02947 ~Xid_log_event() {} 02948 Log_event_type get_type_code() { return XID_EVENT;} 02949 int get_data_size() { return sizeof(xid); } 02950 #ifdef MYSQL_SERVER 02951 bool write(IO_CACHE* file); 02952 #endif 02953 bool is_valid() const { return 1; } 02954 virtual bool ends_group() { return TRUE; } 02955 private: 02956 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 02957 virtual int do_apply_event(Relay_log_info const *rli); 02958 virtual int do_apply_event_worker(Slave_worker *rli); 02959 enum_skip_reason do_shall_skip(Relay_log_info *rli); 02960 bool do_commit(THD *thd); 02961 #endif 02962 }; 02963 02973 class User_var_log_event: public Log_event 02974 { 02975 public: 02976 enum { 02977 UNDEF_F= 0, 02978 UNSIGNED_F= 1 02979 }; 02980 const char *name; 02981 uint name_len; 02982 char *val; 02983 ulong val_len; 02984 Item_result type; 02985 uint charset_number; 02986 bool is_null; 02987 uchar flags; 02988 #ifdef MYSQL_SERVER 02989 bool deferred; 02990 query_id_t query_id; 02991 User_var_log_event(THD* thd_arg, const char *name_arg, uint name_len_arg, 02992 char *val_arg, ulong val_len_arg, Item_result type_arg, 02993 uint charset_number_arg, uchar flags_arg, 02994 enum_event_cache_type cache_type_arg, 02995 enum_event_logging_type logging_type_arg) 02996 :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), name(name_arg), 02997 name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg), 02998 charset_number(charset_number_arg), flags(flags_arg), deferred(false) 02999 { 03000 is_null= !val; 03001 } 03002 int pack_info(Protocol* protocol); 03003 #else 03004 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03005 #endif 03006 03007 User_var_log_event(const char* buf, uint event_len, 03008 const Format_description_log_event *description_event); 03009 ~User_var_log_event() {} 03010 Log_event_type get_type_code() { return USER_VAR_EVENT;} 03011 #ifdef MYSQL_SERVER 03012 bool write(IO_CACHE* file); 03013 /* 03014 Getter and setter for deferred User-event. 03015 Returns true if the event is not applied directly 03016 and which case the applier adjusts execution path. 03017 */ 03018 bool is_deferred() { return deferred; } 03019 /* 03020 In case of the deffered applying the variable instance is flagged 03021 and the parsing time query id is stored to be used at applying time. 03022 */ 03023 void set_deferred(query_id_t qid) { deferred= true; query_id= qid; } 03024 #endif 03025 bool is_valid() const { return name != 0; } 03026 03027 private: 03028 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03029 virtual int do_apply_event(Relay_log_info const *rli); 03030 virtual int do_update_pos(Relay_log_info *rli); 03031 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 03032 #endif 03033 }; 03034 03035 03044 class Stop_log_event: public Log_event 03045 { 03046 public: 03047 #ifdef MYSQL_SERVER 03048 Stop_log_event() :Log_event() 03049 {} 03050 #else 03051 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03052 #endif 03053 03054 Stop_log_event(const char* buf, 03055 const Format_description_log_event *description_event): 03056 Log_event(buf, description_event) 03057 {} 03058 ~Stop_log_event() {} 03059 Log_event_type get_type_code() { return STOP_EVENT;} 03060 bool is_valid() const { return 1; } 03061 03062 private: 03063 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03064 virtual int do_update_pos(Relay_log_info *rli); 03065 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli) 03066 { 03067 /* 03068 Events from ourself should be skipped, but they should not 03069 decrease the slave skip counter. 03070 */ 03071 if (this->server_id == ::server_id) 03072 return Log_event::EVENT_SKIP_IGNORE; 03073 else 03074 return Log_event::EVENT_SKIP_NOT; 03075 } 03076 #endif 03077 }; 03078 03128 class Rotate_log_event: public Log_event 03129 { 03130 public: 03131 enum { 03132 DUP_NAME= 2, // if constructor should dup the string argument 03133 RELAY_LOG=4 // rotate event for relay log 03134 }; 03135 const char* new_log_ident; 03136 ulonglong pos; 03137 uint ident_len; 03138 uint flags; 03139 #ifdef MYSQL_SERVER 03140 Rotate_log_event(const char* new_log_ident_arg, 03141 uint ident_len_arg, 03142 ulonglong pos_arg, uint flags); 03143 #ifdef HAVE_REPLICATION 03144 int pack_info(Protocol* protocol); 03145 #endif /* HAVE_REPLICATION */ 03146 #else 03147 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03148 #endif 03149 03150 Rotate_log_event(const char* buf, uint event_len, 03151 const Format_description_log_event* description_event); 03152 ~Rotate_log_event() 03153 { 03154 if (flags & DUP_NAME) 03155 my_free((void*) new_log_ident); 03156 } 03157 Log_event_type get_type_code() { return ROTATE_EVENT;} 03158 int get_data_size() { return ident_len + ROTATE_HEADER_LEN;} 03159 bool is_valid() const { return new_log_ident != 0; } 03160 #ifdef MYSQL_SERVER 03161 bool write(IO_CACHE* file); 03162 #endif 03163 03164 private: 03165 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03166 virtual int do_update_pos(Relay_log_info *rli); 03167 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 03168 #endif 03169 }; 03170 03171 03172 /* the classes below are for the new LOAD DATA INFILE logging */ 03173 03180 class Create_file_log_event: public Load_log_event 03181 { 03182 protected: 03183 /* 03184 Pretend we are Load event, so we can write out just 03185 our Load part - used on the slave when writing event out to 03186 SQL_LOAD-*.info file 03187 */ 03188 bool fake_base; 03189 public: 03190 uchar* block; 03191 const char *event_buf; 03192 uint block_len; 03193 uint file_id; 03194 bool inited_from_old; 03195 03196 #ifdef MYSQL_SERVER 03197 Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, 03198 const char* table_name_arg, 03199 List<Item>& fields_arg, 03200 bool is_concurrent_arg, 03201 enum enum_duplicates handle_dup, bool ignore, 03202 uchar* block_arg, uint block_len_arg, 03203 bool using_trans); 03204 #ifdef HAVE_REPLICATION 03205 int pack_info(Protocol* protocol); 03206 #endif /* HAVE_REPLICATION */ 03207 #else 03208 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03209 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, 03210 bool enable_local); 03211 #endif 03212 03213 Create_file_log_event(const char* buf, uint event_len, 03214 const Format_description_log_event* description_event); 03215 ~Create_file_log_event() 03216 { 03217 my_free((void*) event_buf); 03218 } 03219 03220 Log_event_type get_type_code() 03221 { 03222 return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT; 03223 } 03224 int get_data_size() 03225 { 03226 return (fake_base ? Load_log_event::get_data_size() : 03227 Load_log_event::get_data_size() + 03228 4 + 1 + block_len); 03229 } 03230 bool is_valid() const { return inited_from_old || block != 0; } 03231 #ifdef MYSQL_SERVER 03232 bool write_data_header(IO_CACHE* file); 03233 bool write_data_body(IO_CACHE* file); 03234 /* 03235 Cut out Create_file extentions and 03236 write it as Load event - used on the slave 03237 */ 03238 bool write_base(IO_CACHE* file); 03239 #endif 03240 03241 private: 03242 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03243 virtual int do_apply_event(Relay_log_info const *rli); 03244 #endif 03245 }; 03246 03247 03254 class Append_block_log_event: public Log_event 03255 { 03256 public: 03257 uchar* block; 03258 uint block_len; 03259 uint file_id; 03260 /* 03261 'db' is filled when the event is created in mysql_load() (the 03262 event needs to have a 'db' member to be well filtered by 03263 binlog-*-db rules). 'db' is not written to the binlog (it's not 03264 used by Append_block_log_event::write()), so it can't be read in 03265 the Append_block_log_event(const char* buf, int event_len) 03266 constructor. In other words, 'db' is used only for filtering by 03267 binlog-*-db rules. Create_file_log_event is different: it's 'db' 03268 (which is inherited from Load_log_event) is written to the binlog 03269 and can be re-read. 03270 */ 03271 const char* db; 03272 03273 #ifdef MYSQL_SERVER 03274 Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg, 03275 uint block_len_arg, bool using_trans); 03276 #ifdef HAVE_REPLICATION 03277 int pack_info(Protocol* protocol); 03278 virtual int get_create_or_append() const; 03279 #endif /* HAVE_REPLICATION */ 03280 #else 03281 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03282 #endif 03283 03284 Append_block_log_event(const char* buf, uint event_len, 03285 const Format_description_log_event 03286 *description_event); 03287 ~Append_block_log_event() {} 03288 Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;} 03289 int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} 03290 bool is_valid() const { return block != 0; } 03291 #ifdef MYSQL_SERVER 03292 bool write(IO_CACHE* file); 03293 const char* get_db() { return db; } 03294 #endif 03295 03296 private: 03297 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03298 virtual int do_apply_event(Relay_log_info const *rli); 03299 #endif 03300 }; 03301 03302 03309 class Delete_file_log_event: public Log_event 03310 { 03311 public: 03312 uint file_id; 03313 const char* db; /* see comment in Append_block_log_event */ 03314 03315 #ifdef MYSQL_SERVER 03316 Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); 03317 #ifdef HAVE_REPLICATION 03318 int pack_info(Protocol* protocol); 03319 #endif /* HAVE_REPLICATION */ 03320 #else 03321 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03322 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, 03323 bool enable_local); 03324 #endif 03325 03326 Delete_file_log_event(const char* buf, uint event_len, 03327 const Format_description_log_event* description_event); 03328 ~Delete_file_log_event() {} 03329 Log_event_type get_type_code() { return DELETE_FILE_EVENT;} 03330 int get_data_size() { return DELETE_FILE_HEADER_LEN ;} 03331 bool is_valid() const { return file_id != 0; } 03332 #ifdef MYSQL_SERVER 03333 bool write(IO_CACHE* file); 03334 const char* get_db() { return db; } 03335 #endif 03336 03337 private: 03338 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03339 virtual int do_apply_event(Relay_log_info const *rli); 03340 #endif 03341 }; 03342 03343 03350 class Execute_load_log_event: public Log_event 03351 { 03352 public: 03353 uint file_id; 03354 const char* db; /* see comment in Append_block_log_event */ 03355 03356 #ifdef MYSQL_SERVER 03357 Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); 03358 #ifdef HAVE_REPLICATION 03359 int pack_info(Protocol* protocol); 03360 #endif /* HAVE_REPLICATION */ 03361 #else 03362 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03363 #endif 03364 03365 Execute_load_log_event(const char* buf, uint event_len, 03366 const Format_description_log_event 03367 *description_event); 03368 ~Execute_load_log_event() {} 03369 Log_event_type get_type_code() { return EXEC_LOAD_EVENT;} 03370 int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} 03371 bool is_valid() const { return file_id != 0; } 03372 #ifdef MYSQL_SERVER 03373 bool write(IO_CACHE* file); 03374 const char* get_db() { return db; } 03375 #endif 03376 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03377 virtual uint8 mts_number_dbs() { return OVER_MAX_DBS_IN_EVENT_MTS; } 03385 virtual uint8 get_mts_dbs(Mts_db_names *arg) 03386 { 03387 return arg->num= mts_number_dbs(); 03388 } 03389 #endif 03390 03391 private: 03392 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03393 virtual int do_apply_event(Relay_log_info const *rli); 03394 #endif 03395 }; 03396 03397 03407 class Begin_load_query_log_event: public Append_block_log_event 03408 { 03409 public: 03410 #ifdef MYSQL_SERVER 03411 Begin_load_query_log_event(THD* thd_arg, const char *db_arg, 03412 uchar* block_arg, uint block_len_arg, 03413 bool using_trans); 03414 #ifdef HAVE_REPLICATION 03415 Begin_load_query_log_event(THD* thd); 03416 int get_create_or_append() const; 03417 #endif /* HAVE_REPLICATION */ 03418 #endif 03419 Begin_load_query_log_event(const char* buf, uint event_len, 03420 const Format_description_log_event 03421 *description_event); 03422 ~Begin_load_query_log_event() {} 03423 Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; } 03424 private: 03425 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03426 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 03427 #endif 03428 }; 03429 03430 03431 /* 03432 Elements of this enum describe how LOAD DATA handles duplicates. 03433 */ 03434 enum enum_load_dup_handling { LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE, 03435 LOAD_DUP_REPLACE }; 03436 03446 class Execute_load_query_log_event: public Query_log_event 03447 { 03448 public: 03449 uint file_id; // file_id of temporary file 03450 uint fn_pos_start; // pointer to the part of the query that should 03451 // be substituted 03452 uint fn_pos_end; // pointer to the end of this part of query 03453 /* 03454 We have to store type of duplicate handling explicitly, because 03455 for LOAD DATA it also depends on LOCAL option. And this part 03456 of query will be rewritten during replication so this information 03457 may be lost... 03458 */ 03459 enum_load_dup_handling dup_handling; 03460 03461 #ifdef MYSQL_SERVER 03462 Execute_load_query_log_event(THD* thd, const char* query_arg, 03463 ulong query_length, uint fn_pos_start_arg, 03464 uint fn_pos_end_arg, 03465 enum_load_dup_handling dup_handling_arg, 03466 bool using_trans, bool immediate, 03467 bool suppress_use, int errcode); 03468 #ifdef HAVE_REPLICATION 03469 int pack_info(Protocol* protocol); 03470 #endif /* HAVE_REPLICATION */ 03471 #else 03472 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03473 /* Prints the query as LOAD DATA LOCAL and with rewritten filename */ 03474 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, 03475 const char *local_fname); 03476 #endif 03477 Execute_load_query_log_event(const char* buf, uint event_len, 03478 const Format_description_log_event 03479 *description_event); 03480 ~Execute_load_query_log_event() {} 03481 03482 Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; } 03483 bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; } 03484 03485 ulong get_post_header_size_for_derived(); 03486 #ifdef MYSQL_SERVER 03487 bool write_post_header_for_derived(IO_CACHE* file); 03488 #endif 03489 03490 private: 03491 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03492 virtual int do_apply_event(Relay_log_info const *rli); 03493 #endif 03494 }; 03495 03496 03497 #ifdef MYSQL_CLIENT 03498 03503 class Unknown_log_event: public Log_event 03504 { 03505 public: 03506 /* 03507 Even if this is an unknown event, we still pass description_event to 03508 Log_event's ctor, this way we can extract maximum information from the 03509 event's header (the unique ID for example). 03510 */ 03511 Unknown_log_event(const char* buf, 03512 const Format_description_log_event *description_event): 03513 Log_event(buf, description_event) 03514 {} 03515 ~Unknown_log_event() {} 03516 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 03517 Log_event_type get_type_code() { return UNKNOWN_EVENT;} 03518 bool is_valid() const { return 1; } 03519 }; 03520 #endif 03521 char *str_to_hex(char *to, const char *from, uint len); 03522 03837 class Table_map_log_event : public Log_event 03838 { 03839 public: 03840 /* Constants */ 03841 enum 03842 { 03843 TYPE_CODE = TABLE_MAP_EVENT 03844 }; 03845 03849 enum enum_error 03850 { 03851 ERR_OPEN_FAILURE = -1, 03852 ERR_OK = 0, 03853 ERR_TABLE_LIMIT_EXCEEDED = 1, 03854 ERR_OUT_OF_MEM = 2, 03855 ERR_BAD_TABLE_DEF = 3, 03856 ERR_RBR_TO_SBR = 4 03857 }; 03858 03859 enum enum_flag 03860 { 03861 /* 03862 Nothing here right now, but the flags support is there in 03863 preparation for changes that are coming. Need to add a 03864 constant to make it compile under HP-UX: aCC does not like 03865 empty enumerations. 03866 */ 03867 ENUM_FLAG_COUNT 03868 }; 03869 03870 typedef uint16 flag_set; 03871 03872 /* Special constants representing sets of flags */ 03873 enum 03874 { 03875 TM_NO_FLAGS = 0U, 03876 TM_BIT_LEN_EXACT_F = (1U << 0), 03877 TM_REFERRED_FK_DB_F = (1U << 1) 03878 }; 03879 03880 flag_set get_flags(flag_set flag) const { return m_flags & flag; } 03881 03882 #ifdef MYSQL_SERVER 03883 Table_map_log_event(THD *thd, TABLE *tbl, const Table_id& tid, 03884 bool is_transactional); 03885 #endif 03886 #ifdef HAVE_REPLICATION 03887 Table_map_log_event(const char *buf, uint event_len, 03888 const Format_description_log_event *description_event); 03889 #endif 03890 03891 ~Table_map_log_event(); 03892 03893 #ifdef MYSQL_CLIENT 03894 table_def *create_table_def() 03895 { 03896 return new table_def(m_coltype, m_colcnt, m_field_metadata, 03897 m_field_metadata_size, m_null_bits, m_flags); 03898 } 03899 #endif 03900 const Table_id& get_table_id() const { return m_table_id; } 03901 const char *get_table_name() const { return m_tblnam; } 03902 const char *get_db_name() const { return m_dbnam; } 03903 03904 virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } 03905 virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } 03906 03907 virtual int get_data_size() { return (uint) m_data_size; } 03908 #ifdef MYSQL_SERVER 03909 virtual int save_field_metadata(); 03910 virtual bool write_data_header(IO_CACHE *file); 03911 virtual bool write_data_body(IO_CACHE *file); 03912 virtual const char *get_db() { return m_dbnam; } 03913 virtual uint8 mts_number_dbs() 03914 { 03915 return get_flags(TM_REFERRED_FK_DB_F) ? OVER_MAX_DBS_IN_EVENT_MTS : 1; 03916 } 03925 virtual uint8 get_mts_dbs(Mts_db_names *arg) 03926 { 03927 const char *db_name= get_db(); 03928 03929 if (!rpl_filter->is_rewrite_empty() && !get_flags(TM_REFERRED_FK_DB_F)) 03930 { 03931 size_t dummy_len; 03932 const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len); 03933 // db_name != db_filtered means that db_name is rewritten. 03934 if (strcmp(db_name, db_filtered)) 03935 db_name= db_filtered; 03936 } 03937 03938 if (!get_flags(TM_REFERRED_FK_DB_F)) 03939 arg->name[0]= db_name; 03940 03941 return arg->num= mts_number_dbs(); 03942 } 03943 03944 #endif 03945 03946 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03947 virtual int pack_info(Protocol *protocol); 03948 #endif 03949 03950 #ifdef MYSQL_CLIENT 03951 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 03952 #endif 03953 03954 03955 private: 03956 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 03957 virtual int do_apply_event(Relay_log_info const *rli); 03958 virtual int do_update_pos(Relay_log_info *rli); 03959 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 03960 #endif 03961 03962 #ifdef MYSQL_SERVER 03963 TABLE *m_table; 03964 #endif 03965 char const *m_dbnam; 03966 size_t m_dblen; 03967 char const *m_tblnam; 03968 size_t m_tbllen; 03969 ulong m_colcnt; 03970 uchar *m_coltype; 03971 03972 uchar *m_memory; 03973 Table_id m_table_id; 03974 flag_set m_flags; 03975 03976 size_t m_data_size; 03977 03978 uchar *m_field_metadata; // buffer for field metadata 03979 /* 03980 The size of field metadata buffer set by calling save_field_metadata() 03981 */ 03982 ulong m_field_metadata_size; 03983 uchar *m_null_bits; 03984 uchar *m_meta_memory; 03985 }; 03986 03987 04003 class Rows_log_event : public Log_event 04004 { 04005 public: 04006 enum row_lookup_mode { 04007 ROW_LOOKUP_UNDEFINED= 0, 04008 ROW_LOOKUP_NOT_NEEDED= 1, 04009 ROW_LOOKUP_INDEX_SCAN= 2, 04010 ROW_LOOKUP_TABLE_SCAN= 3, 04011 ROW_LOOKUP_HASH_SCAN= 4 04012 }; 04013 04017 enum enum_error 04018 { 04019 ERR_OPEN_FAILURE = -1, 04020 ERR_OK = 0, 04021 ERR_TABLE_LIMIT_EXCEEDED = 1, 04022 ERR_OUT_OF_MEM = 2, 04023 ERR_BAD_TABLE_DEF = 3, 04024 ERR_RBR_TO_SBR = 4 04025 }; 04026 04027 /* 04028 These definitions allow you to combine the flags into an 04029 appropriate flag set using the normal bitwise operators. The 04030 implicit conversion from an enum-constant to an integer is 04031 accepted by the compiler, which is then used to set the real set 04032 of flags. 04033 */ 04034 enum enum_flag 04035 { 04036 /* Last event of a statement */ 04037 STMT_END_F = (1U << 0), 04038 04039 /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */ 04040 NO_FOREIGN_KEY_CHECKS_F = (1U << 1), 04041 04042 /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */ 04043 RELAXED_UNIQUE_CHECKS_F = (1U << 2), 04044 04049 COMPLETE_ROWS_F = (1U << 3) 04050 }; 04051 04052 typedef uint16 flag_set; 04053 04054 /* Special constants representing sets of flags */ 04055 enum 04056 { 04057 RLE_NO_FLAGS = 0U 04058 }; 04059 04060 virtual ~Rows_log_event(); 04061 04062 void set_flags(flag_set flags_arg) { m_flags |= flags_arg; } 04063 void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; } 04064 flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; } 04065 04066 Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */ 04067 virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */ 04068 04069 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04070 virtual int pack_info(Protocol *protocol); 04071 #endif 04072 04073 #ifdef MYSQL_CLIENT 04074 /* not for direct call, each derived has its own ::print() */ 04075 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0; 04076 void print_verbose(IO_CACHE *file, 04077 PRINT_EVENT_INFO *print_event_info); 04078 size_t print_verbose_one_row(IO_CACHE *file, table_def *td, 04079 PRINT_EVENT_INFO *print_event_info, 04080 MY_BITMAP *cols_bitmap, 04081 const uchar *ptr, const uchar *prefix); 04082 #endif 04083 04084 #ifdef MYSQL_SERVER 04085 int add_row_data(uchar *data, size_t length) 04086 { 04087 return do_add_row_data(data,length); 04088 } 04089 #endif 04090 04091 /* Member functions to implement superclass interface */ 04092 virtual int get_data_size(); 04093 04094 MY_BITMAP const *get_cols() const { return &m_cols; } 04095 MY_BITMAP const *get_cols_ai() const { return &m_cols_ai; } 04096 size_t get_width() const { return m_width; } 04097 const Table_id& get_table_id() const { return m_table_id; } 04098 04099 #if defined(MYSQL_SERVER) 04100 /* 04101 This member function compares the table's read/write_set 04102 with this event's m_cols and m_cols_ai. Comparison takes 04103 into account what type of rows event is this: Delete, Write or 04104 Update, therefore it uses the correct m_cols[_ai] according 04105 to the event type code. 04106 04107 Note that this member function should only be called for the 04108 following events: 04109 - Delete_rows_log_event 04110 - Write_rows_log_event 04111 - Update_rows_log_event 04112 04113 @param[IN] table The table to compare this events bitmaps 04114 against. 04115 04116 @return TRUE if sets match, FALSE otherwise. (following 04117 bitmap_cmp return logic). 04118 04119 */ 04120 virtual bool read_write_bitmaps_cmp(TABLE *table) 04121 { 04122 bool res= FALSE; 04123 04124 switch (get_general_type_code()) 04125 { 04126 case DELETE_ROWS_EVENT: 04127 res= bitmap_cmp(get_cols(), table->read_set); 04128 break; 04129 case UPDATE_ROWS_EVENT: 04130 res= (bitmap_cmp(get_cols(), table->read_set) && 04131 bitmap_cmp(get_cols_ai(), table->write_set)); 04132 break; 04133 case WRITE_ROWS_EVENT: 04134 res= bitmap_cmp(get_cols(), table->write_set); 04135 break; 04136 default: 04137 /* 04138 We should just compare bitmaps for Delete, Write 04139 or Update rows events. 04140 */ 04141 DBUG_ASSERT(0); 04142 } 04143 return res; 04144 } 04145 #endif 04146 04147 #ifdef MYSQL_SERVER 04148 virtual bool write_data_header(IO_CACHE *file); 04149 virtual bool write_data_body(IO_CACHE *file); 04150 virtual const char *get_db() { return m_table->s->db.str; } 04151 #endif 04152 /* 04153 Check that malloc() succeeded in allocating memory for the rows 04154 buffer and the COLS vector. Checking that an Update_rows_log_event 04155 is valid is done in the Update_rows_log_event::is_valid() 04156 function. 04157 */ 04158 virtual bool is_valid() const 04159 { 04160 return m_rows_buf && m_cols.bitmap; 04161 } 04162 04163 uint m_row_count; /* The number of rows added to the event */ 04164 04165 const uchar* get_extra_row_data() const { return m_extra_row_data; } 04166 04167 protected: 04168 /* 04169 The constructors are protected since you're supposed to inherit 04170 this class, not create instances of this class. 04171 */ 04172 #ifdef MYSQL_SERVER 04173 Rows_log_event(THD*, TABLE*, const Table_id& table_id, 04174 MY_BITMAP const *cols, bool is_transactional, 04175 Log_event_type event_type, 04176 const uchar* extra_row_info); 04177 #endif 04178 Rows_log_event(const char *row_data, uint event_len, 04179 const Format_description_log_event *description_event); 04180 04181 #ifdef MYSQL_CLIENT 04182 void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name); 04183 #endif 04184 04185 #ifdef MYSQL_SERVER 04186 virtual int do_add_row_data(uchar *data, size_t length); 04187 #endif 04188 04189 #ifdef MYSQL_SERVER 04190 TABLE *m_table; /* The table the rows belong to */ 04191 #endif 04192 Table_id m_table_id; /* Table ID */ 04193 MY_BITMAP m_cols; /* Bitmap denoting columns available */ 04194 ulong m_width; /* The width of the columns bitmap */ 04195 #ifndef MYSQL_CLIENT 04196 04200 Hash_slave_rows m_hash; 04201 04206 uint m_rows_lookup_algorithm; 04207 #endif 04208 /* 04209 Bitmap for columns available in the after image, if present. These 04210 fields are only available for Update_rows events. Observe that the 04211 width of both the before image COLS vector and the after image 04212 COLS vector is the same: the number of columns of the table on the 04213 master. 04214 */ 04215 MY_BITMAP m_cols_ai; 04216 04217 ulong m_master_reclength; /* Length of record on master side */ 04218 04219 /* Bit buffers in the same memory as the class */ 04220 uint32 m_bitbuf[128/(sizeof(uint32)*8)]; 04221 uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)]; 04222 04223 uchar *m_rows_buf; /* The rows in packed format */ 04224 uchar *m_rows_cur; /* One-after the end of the data */ 04225 uchar *m_rows_end; /* One-after the end of the allocated space */ 04226 04227 flag_set m_flags; /* Flags for row-level events */ 04228 04229 Log_event_type m_type; /* Actual event type */ 04230 04231 uchar *m_extra_row_data; /* Pointer to extra row data if any */ 04232 /* If non null, first byte is length */ 04233 04234 /* helper functions */ 04235 04236 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04237 const uchar *m_curr_row; /* Start of the row being processed */ 04238 const uchar *m_curr_row_end; /* One-after the end of the current row */ 04239 uchar *m_key; /* Buffer to keep key value during searches */ 04240 uint m_key_index; 04241 KEY *m_key_info; /* Points to description of index #m_key_index */ 04242 class Key_compare 04243 { 04244 public: 04256 Key_compare(KEY **ki= NULL) : m_key_info(ki) {} 04257 bool operator()(uchar *k1, uchar *k2) const 04258 { 04259 return key_cmp2((*m_key_info)->key_part, 04260 k1, (*m_key_info)->key_length, 04261 k2, (*m_key_info)->key_length) < 0 ; 04262 } 04263 private: 04264 KEY **m_key_info; 04265 }; 04266 std::set<uchar *, Key_compare> m_distinct_keys; 04267 std::set<uchar *, Key_compare>::iterator m_itr; 04272 uchar *m_distinct_key_spare_buf; 04273 04274 // Unpack the current row into m_table->record[0] 04275 int unpack_current_row(const Relay_log_info *const rli, 04276 MY_BITMAP const *cols) 04277 { 04278 DBUG_ASSERT(m_table); 04279 04280 ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT); 04281 return ::unpack_row(rli, m_table, m_width, m_curr_row, cols, 04282 &m_curr_row_end, &m_master_reclength, m_rows_end); 04283 } 04284 04285 /* 04286 This member function is called when deciding the algorithm to be used to 04287 find the rows to be updated on the slave during row based replication. 04288 This this functions sets the m_rows_lookup_algorithm and also the 04289 m_key_index with the key index to be used if the algorithm is dependent on 04290 an index. 04291 */ 04292 void decide_row_lookup_algorithm_and_key(); 04293 04294 /* 04295 Encapsulates the operations to be done before applying 04296 row event for update and delete. 04297 */ 04298 int row_operations_scan_and_key_setup(); 04299 04300 /* 04301 Encapsulates the operations to be done after applying 04302 row event for update and delete. 04303 */ 04304 int row_operations_scan_and_key_teardown(int error); 04305 04313 inline bool is_auto_inc_in_extra_columns() 04314 { 04315 DBUG_ASSERT(m_table); 04316 return (m_table->next_number_field && 04317 m_table->next_number_field->field_index >= m_width); 04318 } 04319 #endif 04320 04321 private: 04322 04323 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04324 virtual int do_apply_event(Relay_log_info const *rli); 04325 virtual int do_update_pos(Relay_log_info *rli); 04326 virtual enum_skip_reason do_shall_skip(Relay_log_info *rli); 04327 04328 /* 04329 Primitive to prepare for a sequence of row executions. 04330 04331 DESCRIPTION 04332 04333 Before doing a sequence of do_prepare_row() and do_exec_row() 04334 calls, this member function should be called to prepare for the 04335 entire sequence. Typically, this member function will allocate 04336 space for any buffers that are needed for the two member 04337 functions mentioned above. 04338 04339 RETURN VALUE 04340 04341 The member function will return 0 if all went OK, or a non-zero 04342 error code otherwise. 04343 */ 04344 virtual 04345 int do_before_row_operations(const Slave_reporting_capability *const log) = 0; 04346 04347 /* 04348 Primitive to clean up after a sequence of row executions. 04349 04350 DESCRIPTION 04351 04352 After doing a sequence of do_prepare_row() and do_exec_row(), 04353 this member function should be called to clean up and release 04354 any allocated buffers. 04355 04356 The error argument, if non-zero, indicates an error which happened during 04357 row processing before this function was called. In this case, even if 04358 function is successful, it should return the error code given in the argument. 04359 */ 04360 virtual 04361 int do_after_row_operations(const Slave_reporting_capability *const log, 04362 int error) = 0; 04363 04364 /* 04365 Primitive to do the actual execution necessary for a row. 04366 04367 DESCRIPTION 04368 The member function will do the actual execution needed to handle a row. 04369 The row is located at m_curr_row. When the function returns, 04370 m_curr_row_end should point at the next row (one byte after the end 04371 of the current row). 04372 04373 RETURN VALUE 04374 0 if execution succeeded, 1 if execution failed. 04375 04376 */ 04377 virtual int do_exec_row(const Relay_log_info *const rli) = 0; 04378 04386 int handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err); 04387 04396 void do_post_row_operations(Relay_log_info const *rli, int err); 04397 04402 int do_apply_row(Relay_log_info const *rli); 04403 04409 int do_index_scan_and_update(Relay_log_info const *rli); 04410 04418 int do_hash_scan_and_update(Relay_log_info const *rli); 04419 04426 int do_table_scan_and_update(Relay_log_info const *rli); 04427 04433 int open_record_scan(); 04434 04440 int close_record_scan(); 04441 04454 int next_record_scan(bool first_read); 04455 04462 int add_key_to_distinct_keyset(); 04463 04476 int do_hash_row(Relay_log_info const *rli); 04477 04486 int do_scan_and_update(Relay_log_info const *rli); 04487 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */ 04488 04489 friend class Old_rows_log_event; 04490 }; 04491 04501 class Write_rows_log_event : public Rows_log_event 04502 { 04503 public: 04504 enum 04505 { 04506 /* Support interface to THD::binlog_prepare_pending_rows_event */ 04507 TYPE_CODE = WRITE_ROWS_EVENT 04508 }; 04509 04510 #if defined(MYSQL_SERVER) 04511 Write_rows_log_event(THD*, TABLE*, const Table_id& table_id, 04512 bool is_transactional, 04513 const uchar* extra_row_info); 04514 #endif 04515 #ifdef HAVE_REPLICATION 04516 Write_rows_log_event(const char *buf, uint event_len, 04517 const Format_description_log_event *description_event); 04518 #endif 04519 #if defined(MYSQL_SERVER) 04520 static bool binlog_row_logging_function(THD *thd, TABLE *table, 04521 bool is_transactional, 04522 const uchar *before_record 04523 __attribute__((unused)), 04524 const uchar *after_record) 04525 { 04526 return thd->binlog_write_row(table, is_transactional, 04527 after_record, NULL); 04528 } 04529 #endif 04530 04531 protected: 04532 int write_row(const Relay_log_info *const, const bool); 04533 04534 private: 04535 virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } 04536 04537 #ifdef MYSQL_CLIENT 04538 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04539 #endif 04540 04541 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04542 virtual int do_before_row_operations(const Slave_reporting_capability *const); 04543 virtual int do_after_row_operations(const Slave_reporting_capability *const,int); 04544 virtual int do_exec_row(const Relay_log_info *const); 04545 #endif 04546 }; 04547 04548 04561 class Update_rows_log_event : public Rows_log_event 04562 { 04563 public: 04564 enum 04565 { 04566 /* Support interface to THD::binlog_prepare_pending_rows_event */ 04567 TYPE_CODE = UPDATE_ROWS_EVENT 04568 }; 04569 04570 #ifdef MYSQL_SERVER 04571 Update_rows_log_event(THD*, TABLE*, const Table_id& table_id, 04572 MY_BITMAP const *cols_bi, 04573 MY_BITMAP const *cols_ai, 04574 bool is_transactional, 04575 const uchar* extra_row_info); 04576 04577 Update_rows_log_event(THD*, TABLE*, const Table_id& table_id, 04578 bool is_transactional, 04579 const uchar* extra_row_info); 04580 04581 void init(MY_BITMAP const *cols); 04582 #endif 04583 04584 virtual ~Update_rows_log_event(); 04585 04586 #ifdef HAVE_REPLICATION 04587 Update_rows_log_event(const char *buf, uint event_len, 04588 const Format_description_log_event *description_event); 04589 #endif 04590 04591 #ifdef MYSQL_SERVER 04592 static bool binlog_row_logging_function(THD *thd, TABLE *table, 04593 bool is_transactional, 04594 const uchar *before_record, 04595 const uchar *after_record) 04596 { 04597 return thd->binlog_update_row(table, is_transactional, 04598 before_record, after_record, NULL); 04599 } 04600 #endif 04601 04602 virtual bool is_valid() const 04603 { 04604 return Rows_log_event::is_valid() && m_cols_ai.bitmap; 04605 } 04606 04607 protected: 04608 virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } 04609 04610 #ifdef MYSQL_CLIENT 04611 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04612 #endif 04613 04614 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04615 virtual int do_before_row_operations(const Slave_reporting_capability *const); 04616 virtual int do_after_row_operations(const Slave_reporting_capability *const,int); 04617 virtual int do_exec_row(const Relay_log_info *const); 04618 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */ 04619 }; 04620 04641 class Delete_rows_log_event : public Rows_log_event 04642 { 04643 public: 04644 enum 04645 { 04646 /* Support interface to THD::binlog_prepare_pending_rows_event */ 04647 TYPE_CODE = DELETE_ROWS_EVENT 04648 }; 04649 04650 #ifdef MYSQL_SERVER 04651 Delete_rows_log_event(THD*, TABLE*, const Table_id&, 04652 bool is_transactional, const uchar* extra_row_info); 04653 #endif 04654 #ifdef HAVE_REPLICATION 04655 Delete_rows_log_event(const char *buf, uint event_len, 04656 const Format_description_log_event *description_event); 04657 #endif 04658 #ifdef MYSQL_SERVER 04659 static bool binlog_row_logging_function(THD *thd, TABLE *table, 04660 bool is_transactional, 04661 const uchar *before_record, 04662 const uchar *after_record 04663 __attribute__((unused))) 04664 { 04665 return thd->binlog_delete_row(table, is_transactional, 04666 before_record, NULL); 04667 } 04668 #endif 04669 04670 protected: 04671 virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; } 04672 04673 #ifdef MYSQL_CLIENT 04674 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04675 #endif 04676 04677 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04678 virtual int do_before_row_operations(const Slave_reporting_capability *const); 04679 virtual int do_after_row_operations(const Slave_reporting_capability *const,int); 04680 virtual int do_exec_row(const Relay_log_info *const); 04681 #endif 04682 }; 04683 04684 04685 #include "log_event_old.h" 04686 04723 class Incident_log_event : public Log_event { 04724 public: 04725 #ifdef MYSQL_SERVER 04726 Incident_log_event(THD *thd_arg, Incident incident) 04727 : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, Log_event::EVENT_NO_CACHE, 04728 Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident) 04729 { 04730 DBUG_ENTER("Incident_log_event::Incident_log_event"); 04731 DBUG_PRINT("enter", ("m_incident: %d", m_incident)); 04732 m_message.str= NULL; /* Just as a precaution */ 04733 m_message.length= 0; 04734 DBUG_VOID_RETURN; 04735 } 04736 04737 Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg) 04738 : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, 04739 Log_event::EVENT_NO_CACHE, 04740 Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident) 04741 { 04742 DBUG_ENTER("Incident_log_event::Incident_log_event"); 04743 DBUG_PRINT("enter", ("m_incident: %d", m_incident)); 04744 m_message.str= NULL; 04745 m_message.length= 0; 04746 if (!(m_message.str= (char*) my_malloc(msg.length+1, MYF(MY_WME)))) 04747 { 04748 /* Mark this event invalid */ 04749 m_incident= INCIDENT_NONE; 04750 DBUG_VOID_RETURN; 04751 } 04752 strmake(m_message.str, msg.str, msg.length); 04753 m_message.length= msg.length; 04754 DBUG_VOID_RETURN; 04755 } 04756 #endif 04757 04758 #ifdef MYSQL_SERVER 04759 int pack_info(Protocol*); 04760 #endif 04761 04762 Incident_log_event(const char *buf, uint event_len, 04763 const Format_description_log_event *descr_event); 04764 04765 virtual ~Incident_log_event(); 04766 04767 #ifdef MYSQL_CLIENT 04768 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04769 #endif 04770 04771 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04772 virtual int do_apply_event(Relay_log_info const *rli); 04773 #endif 04774 04775 virtual bool write_data_header(IO_CACHE *file); 04776 virtual bool write_data_body(IO_CACHE *file); 04777 04778 virtual Log_event_type get_type_code() { return INCIDENT_EVENT; } 04779 04780 virtual bool is_valid() const 04781 { 04782 return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT; 04783 } 04784 virtual int get_data_size() { 04785 return INCIDENT_HEADER_LEN + 1 + (uint) m_message.length; 04786 } 04787 04788 private: 04789 const char *description() const; 04790 04791 Incident m_incident; 04792 LEX_STRING m_message; 04793 }; 04794 04795 04813 class Ignorable_log_event : public Log_event { 04814 public: 04815 #ifndef MYSQL_CLIENT 04816 Ignorable_log_event(THD *thd_arg) 04817 : Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, 04818 Log_event::EVENT_STMT_CACHE, 04819 Log_event::EVENT_NORMAL_LOGGING) 04820 { 04821 DBUG_ENTER("Ignorable_log_event::Ignorable_log_event"); 04822 DBUG_VOID_RETURN; 04823 } 04824 #endif 04825 04826 Ignorable_log_event(const char *buf, 04827 const Format_description_log_event *descr_event); 04828 virtual ~Ignorable_log_event(); 04829 04830 #ifndef MYSQL_CLIENT 04831 int pack_info(Protocol*); 04832 #endif 04833 04834 #ifdef MYSQL_CLIENT 04835 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04836 #endif 04837 04838 virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; } 04839 04840 virtual bool is_valid() const { return 1; } 04841 04842 virtual int get_data_size() { return IGNORABLE_HEADER_LEN; } 04843 }; 04844 04845 04846 class Rows_query_log_event : public Ignorable_log_event { 04847 public: 04848 #ifndef MYSQL_CLIENT 04849 Rows_query_log_event(THD *thd_arg, const char * query, ulong query_len) 04850 : Ignorable_log_event(thd_arg) 04851 { 04852 DBUG_ENTER("Rows_query_log_event::Rows_query_log_event"); 04853 if (!(m_rows_query= (char*) my_malloc(query_len + 1, MYF(MY_WME)))) 04854 return; 04855 my_snprintf(m_rows_query, query_len + 1, "%s", query); 04856 DBUG_PRINT("enter", ("%s", m_rows_query)); 04857 DBUG_VOID_RETURN; 04858 } 04859 #endif 04860 04861 #ifndef MYSQL_CLIENT 04862 int pack_info(Protocol*); 04863 #endif 04864 04865 Rows_query_log_event(const char *buf, uint event_len, 04866 const Format_description_log_event *descr_event); 04867 04868 virtual ~Rows_query_log_event(); 04869 04870 #ifdef MYSQL_CLIENT 04871 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04872 #endif 04873 virtual bool write_data_body(IO_CACHE *file); 04874 04875 virtual Log_event_type get_type_code() { return ROWS_QUERY_LOG_EVENT; } 04876 04877 virtual int get_data_size() 04878 { 04879 return IGNORABLE_HEADER_LEN + 1 + (uint) strlen(m_rows_query); 04880 } 04881 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04882 virtual int do_apply_event(Relay_log_info const *rli); 04883 #endif 04884 04885 private: 04886 04887 char * m_rows_query; 04888 }; 04889 04890 04891 04892 static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache, 04893 FILE *file, 04894 bool flush_stream) 04895 { 04896 return 04897 my_b_copy_to_file(cache, file) || 04898 (flush_stream ? (fflush(file) || ferror(file)) : 0) || 04899 reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE); 04900 } 04901 04902 #ifdef MYSQL_SERVER 04903 /***************************************************************************** 04904 04905 Heartbeat Log Event class 04906 04907 Replication event to ensure to slave that master is alive. 04908 The event is originated by master's dump thread and sent straight to 04909 slave without being logged. Slave itself does not store it in relay log 04910 but rather uses a data for immediate checks and throws away the event. 04911 04912 Two members of the class log_ident and Log_event::log_pos comprise 04913 @see the event_coordinates instance. The coordinates that a heartbeat 04914 instance carries correspond to the last event master has sent from 04915 its binlog. 04916 04917 ****************************************************************************/ 04918 class Heartbeat_log_event: public Log_event 04919 { 04920 public: 04921 Heartbeat_log_event(const char* buf, uint event_len, 04922 const Format_description_log_event* description_event); 04923 Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; } 04924 bool is_valid() const 04925 { 04926 return (log_ident != NULL && 04927 log_pos >= BIN_LOG_HEADER_SIZE); 04928 } 04929 const char * get_log_ident() { return log_ident; } 04930 uint get_ident_len() { return ident_len; } 04931 04932 private: 04933 const char* log_ident; 04934 uint ident_len; 04935 }; 04936 04943 bool slave_execute_deferred_events(THD *thd); 04944 #endif 04945 04946 int append_query_string(THD *thd, const CHARSET_INFO *csinfo, 04947 String const *from, String *to); 04948 bool event_checksum_test(uchar *buf, ulong event_len, uint8 alg); 04949 uint8 get_checksum_alg(const char* buf, ulong len); 04950 extern TYPELIB binlog_checksum_typelib; 04951 04952 class Gtid_log_event : public Log_event 04953 { 04954 public: 04955 #ifndef MYSQL_CLIENT 04956 04960 Gtid_log_event(THD *thd_arg, bool using_trans, 04961 const Gtid_specification *spec= NULL); 04962 #endif 04963 04964 #ifndef MYSQL_CLIENT 04965 int pack_info(Protocol*); 04966 #endif 04967 04968 Gtid_log_event(const char *buffer, uint event_len, 04969 const Format_description_log_event *descr_event); 04970 04971 virtual ~Gtid_log_event() {} 04972 04973 Log_event_type get_type_code() 04974 { 04975 DBUG_ENTER("Gtid_log_event::get_type_code()"); 04976 Log_event_type ret= (spec.type == ANONYMOUS_GROUP ? 04977 ANONYMOUS_GTID_LOG_EVENT : GTID_LOG_EVENT); 04978 DBUG_PRINT("info", ("code=%d=%s", ret, get_type_str(ret))); 04979 DBUG_RETURN(ret); 04980 } 04981 04982 int get_data_size() { return POST_HEADER_LENGTH; } 04983 04984 private: 04986 size_t to_string(char *buf) const; 04987 04988 public: 04989 #ifdef MYSQL_CLIENT 04990 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 04991 #endif 04992 #ifdef MYSQL_SERVER 04993 bool write_data_header(IO_CACHE *file); 04994 #endif 04995 04996 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 04997 int do_apply_event(Relay_log_info const *rli); 04998 int do_update_pos(Relay_log_info *rli); 04999 #endif 05000 05005 enum_group_type get_type() const { return spec.type; } 05006 bool is_valid() const { return true; } 05007 05012 const rpl_sid* get_sid() const { return &sid; } 05028 rpl_sidno get_sidno(bool need_lock) 05029 { 05030 if (spec.gtid.sidno < 0) 05031 { 05032 if (need_lock) 05033 global_sid_lock->rdlock(); 05034 else 05035 global_sid_lock->assert_some_lock(); 05036 spec.gtid.sidno= global_sid_map->add_sid(sid); 05037 if (need_lock) 05038 global_sid_lock->unlock(); 05039 } 05040 return spec.gtid.sidno; 05041 } 05052 rpl_sidno get_sidno(Sid_map *sid_map) 05053 { 05054 return sid_map->add_sid(sid); 05055 } 05057 rpl_gno get_gno() const { return spec.gtid.gno; } 05059 bool get_commit_flag() const { return commit_flag; } 05060 05062 static const char *SET_STRING_PREFIX; 05063 private: 05065 static const size_t SET_STRING_PREFIX_LENGTH= 26; 05067 static const size_t MAX_SET_STRING_LENGTH= SET_STRING_PREFIX_LENGTH + 05068 rpl_sid::TEXT_LENGTH + 1 + MAX_GNO_TEXT_LENGTH + 1; 05069 05071 static const int ENCODED_FLAG_LENGTH= 1; 05073 static const int ENCODED_SID_LENGTH= rpl_sid::BYTE_LENGTH; 05075 static const int ENCODED_GNO_LENGTH= 8; 05076 05077 public: 05079 static const int POST_HEADER_LENGTH= 05080 ENCODED_FLAG_LENGTH + ENCODED_SID_LENGTH + ENCODED_GNO_LENGTH; 05081 05082 private: 05087 Gtid_specification spec; 05089 rpl_sid sid; 05091 bool commit_flag; 05092 }; 05093 05094 05095 class Previous_gtids_log_event : public Log_event 05096 { 05097 public: 05098 #ifndef MYSQL_CLIENT 05099 Previous_gtids_log_event(const Gtid_set *set); 05100 #endif 05101 05102 #ifndef MYSQL_CLIENT 05103 int pack_info(Protocol*); 05104 #endif 05105 05106 Previous_gtids_log_event(const char *buffer, uint event_len, 05107 const Format_description_log_event *descr_event); 05108 virtual ~Previous_gtids_log_event() {} 05109 05110 Log_event_type get_type_code() { return PREVIOUS_GTIDS_LOG_EVENT; } 05111 05112 bool is_valid() const { return buf != NULL; } 05113 int get_data_size() { return buf_size; } 05114 05115 #ifdef MYSQL_CLIENT 05116 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 05117 #endif 05118 #ifdef MYSQL_SERVER 05119 bool write(IO_CACHE* file) 05120 { 05121 if (DBUG_EVALUATE_IF("skip_writing_previous_gtids_log_event", 1, 0)) 05122 { 05123 DBUG_PRINT("info", ("skip writing Previous_gtids_log_event because of debug option 'skip_writing_previous_gtids_log_event'")); 05124 return false; 05125 } 05126 05127 if (DBUG_EVALUATE_IF("write_partial_previous_gtids_log_event", 1, 0)) 05128 { 05129 DBUG_PRINT("info", ("writing partial Previous_gtids_log_event because of debug option 'write_partial_previous_gtids_log_event'")); 05130 return (Log_event::write_header(file, get_data_size()) || 05131 Log_event::write_data_header(file)); 05132 } 05133 05134 return (Log_event::write_header(file, get_data_size()) || 05135 Log_event::write_data_header(file) || 05136 write_data_body(file) || 05137 Log_event::write_footer(file)); 05138 } 05139 bool write_data_body(IO_CACHE *file); 05140 #endif 05141 05143 const uchar *get_buf() { return buf; } 05150 char *get_str(size_t *length, 05151 const Gtid_set::String_format *string_format) const; 05153 int add_to_set(Gtid_set *gtid_set) const; 05154 /* 05155 Previous Gtid Log events should always be skipped 05156 there is nothing to apply there, whether it is 05157 relay log's (generated on Slave) or it is binary log's 05158 (generated on Master, copied to slave as relay log). 05159 Also, we should not increment slave_skip_counter 05160 for this event, hence return EVENT_SKIP_IGNORE. 05161 */ 05162 enum_skip_reason do_shall_skip(Relay_log_info *rli) 05163 { 05164 return EVENT_SKIP_IGNORE; 05165 } 05166 05167 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) 05168 int do_apply_event(Relay_log_info const *rli) { return 0; } 05169 int do_update_pos(Relay_log_info *rli); 05170 #endif 05171 05172 private: 05173 int buf_size; 05174 const uchar *buf; 05175 }; 05176 05177 inline bool is_gtid_event(Log_event* evt) 05178 { 05179 return (evt->get_type_code() == GTID_LOG_EVENT || 05180 evt->get_type_code() == ANONYMOUS_GTID_LOG_EVENT); 05181 } 05182 05183 inline ulong version_product(const uchar* version_split) 05184 { 05185 return ((version_split[0] * 256 + version_split[1]) * 256 05186 + version_split[2]); 05187 } 05188 05195 inline void do_server_version_split(char* version, uchar split_versions[3]) 05196 { 05197 char *p= version, *r; 05198 ulong number; 05199 for (uint i= 0; i<=2; i++) 05200 { 05201 number= strtoul(p, &r, 10); 05202 /* 05203 It is an invalid version if any version number greater than 255 or 05204 first number is not followed by '.'. 05205 */ 05206 if (number < 256 && (*r == '.' || i != 0)) 05207 split_versions[i]= (uchar)number; 05208 else 05209 { 05210 split_versions[0]= 0; 05211 split_versions[1]= 0; 05212 split_versions[2]= 0; 05213 break; 05214 } 05215 05216 p= r; 05217 if (*r == '.') 05218 p++; // skip the dot 05219 } 05220 } 05221 05222 #ifdef MYSQL_SERVER 05223 /* 05224 This is an utility function that adds a quoted identifier into the a buffer. 05225 This also escapes any existance of the quote string inside the identifier. 05226 */ 05227 size_t my_strmov_quoted_identifier(THD *thd, char *buffer, 05228 const char* identifier, 05229 uint length); 05230 #else 05231 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier); 05232 #endif 05233 size_t my_strmov_quoted_identifier_helper(int q, char *buffer, 05234 const char* identifier, 05235 uint length); 05236 05241 #endif /* _log_event_h */