00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 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; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 #ifndef _log_event_h 00019 #define _log_event_h 00020 00021 #if defined(USE_PRAGMA_INTERFACE) && !defined(MYSQL_CLIENT) 00022 #pragma interface /* gcc class implementation */ 00023 #endif 00024 00025 #include <my_bitmap.h> 00026 00027 #define LOG_READ_EOF -1 00028 #define LOG_READ_BOGUS -2 00029 #define LOG_READ_IO -3 00030 #define LOG_READ_MEM -5 00031 #define LOG_READ_TRUNC -6 00032 #define LOG_READ_TOO_LARGE -7 00033 00034 #define LOG_EVENT_OFFSET 4 00035 00036 /* 00037 3 is MySQL 4.x; 4 is MySQL 5.0.0. 00038 Compared to version 3, version 4 has: 00039 - a different Start_log_event, which includes info about the binary log 00040 (sizes of headers); this info is included for better compatibility if the 00041 master's MySQL version is different from the slave's. 00042 - all events have a unique ID (the triplet (server_id, timestamp at server 00043 start, other) to be sure an event is not executed more than once in a 00044 multimaster setup, example: 00045 M1 00046 / \ 00047 v v 00048 M2 M3 00049 \ / 00050 v v 00051 S 00052 if a query is run on M1, it will arrive twice on S, so we need that S 00053 remembers the last unique ID it has processed, to compare and know if the 00054 event should be skipped or not. Example of ID: we already have the server id 00055 (4 bytes), plus: 00056 timestamp_when_the_master_started (4 bytes), a counter (a sequence number 00057 which increments every time we write an event to the binlog) (3 bytes). 00058 Q: how do we handle when the counter is overflowed and restarts from 0 ? 00059 00060 - Query and Load (Create or Execute) events may have a more precise timestamp 00061 (with microseconds), number of matched/affected/warnings rows 00062 and fields of session variables: SQL_MODE, 00063 FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and 00064 charsets, the PASSWORD() version (old/new/...). 00065 */ 00066 #define BINLOG_VERSION 4 00067 00068 /* 00069 We could have used SERVER_VERSION_LENGTH, but this introduces an 00070 obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH 00071 this would break the replication protocol 00072 */ 00073 #define ST_SERVER_VER_LEN 50 00074 00075 /* 00076 These are flags and structs to handle all the LOAD DATA INFILE options (LINES 00077 TERMINATED etc). 00078 */ 00079 00080 /* 00081 These are flags and structs to handle all the LOAD DATA INFILE options (LINES 00082 TERMINATED etc). 00083 DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD 00084 DATA). 00085 */ 00086 #define DUMPFILE_FLAG 0x1 00087 #define OPT_ENCLOSED_FLAG 0x2 00088 #define REPLACE_FLAG 0x4 00089 #define IGNORE_FLAG 0x8 00090 00091 #define FIELD_TERM_EMPTY 0x1 00092 #define ENCLOSED_EMPTY 0x2 00093 #define LINE_TERM_EMPTY 0x4 00094 #define LINE_START_EMPTY 0x8 00095 #define ESCAPED_EMPTY 0x10 00096 00097 /***************************************************************************** 00098 00099 old_sql_ex struct 00100 00101 ****************************************************************************/ 00102 struct old_sql_ex 00103 { 00104 char field_term; 00105 char enclosed; 00106 char line_term; 00107 char line_start; 00108 char escaped; 00109 char opt_flags; 00110 char empty_flags; 00111 }; 00112 00113 #define NUM_LOAD_DELIM_STRS 5 00114 00115 /***************************************************************************** 00116 00117 sql_ex_info struct 00118 00119 ****************************************************************************/ 00120 struct sql_ex_info 00121 { 00122 sql_ex_info() {} /* Remove gcc warning */ 00123 char* field_term; 00124 char* enclosed; 00125 char* line_term; 00126 char* line_start; 00127 char* escaped; 00128 int cached_new_format; 00129 uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len; 00130 char opt_flags; 00131 char empty_flags; 00132 00133 // store in new format even if old is possible 00134 void force_new_format() { cached_new_format = 1;} 00135 int data_size() 00136 { 00137 return (new_format() ? 00138 field_term_len + enclosed_len + line_term_len + 00139 line_start_len + escaped_len + 6 : 7); 00140 } 00141 bool write_data(IO_CACHE* file); 00142 char* init(char* buf,char* buf_end,bool use_new_format); 00143 bool new_format() 00144 { 00145 return ((cached_new_format != -1) ? cached_new_format : 00146 (cached_new_format=(field_term_len > 1 || 00147 enclosed_len > 1 || 00148 line_term_len > 1 || line_start_len > 1 || 00149 escaped_len > 1))); 00150 } 00151 }; 00152 00153 /***************************************************************************** 00154 00155 MySQL Binary Log 00156 00157 This log consists of events. Each event has a fixed-length header, 00158 possibly followed by a variable length data body. 00159 00160 The data body consists of an optional fixed length segment (post-header) 00161 and an optional variable length segment. 00162 00163 See the #defines below for the format specifics. 00164 00165 The events which really update data are Query_log_event, 00166 Execute_load_query_log_event and old Load_log_event and 00167 Execute_load_log_event events (Execute_load_query is used together with 00168 Begin_load_query and Append_block events to replicate LOAD DATA INFILE. 00169 Create_file/Append_block/Execute_load (which includes Load_log_event) 00170 were used to replicate LOAD DATA before the 5.0.3). 00171 00172 ****************************************************************************/ 00173 00174 #define LOG_EVENT_HEADER_LEN 19 /* the fixed header length */ 00175 #define OLD_HEADER_LEN 13 /* the fixed header length in 3.23 */ 00176 /* 00177 Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer 00178 header (it will for sure when we have the unique event's ID), but at least 00179 the first 19 bytes are the same in 4.x and 5.0. So when we have the unique 00180 event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but 00181 LOG_EVENT_MINIMAL_HEADER_LEN will remain 19. 00182 */ 00183 #define LOG_EVENT_MINIMAL_HEADER_LEN 19 00184 00185 /* event-specific post-header sizes */ 00186 // where 3.23, 4.x and 5.0 agree 00187 #define QUERY_HEADER_MINIMAL_LEN (4 + 4 + 1 + 2) 00188 // where 5.0 differs: 2 for len of N-bytes vars. 00189 #define QUERY_HEADER_LEN (QUERY_HEADER_MINIMAL_LEN + 2) 00190 #define LOAD_HEADER_LEN (4 + 4 + 4 + 1 +1 + 4) 00191 #define START_V3_HEADER_LEN (2 + ST_SERVER_VER_LEN + 4) 00192 #define ROTATE_HEADER_LEN 8 // this is FROZEN (the Rotate post-header is frozen) 00193 #define CREATE_FILE_HEADER_LEN 4 00194 #define APPEND_BLOCK_HEADER_LEN 4 00195 #define EXEC_LOAD_HEADER_LEN 4 00196 #define DELETE_FILE_HEADER_LEN 4 00197 #define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES) 00198 #define ROWS_HEADER_LEN 8 00199 #define TABLE_MAP_HEADER_LEN 8 00200 #define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1) 00201 #define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN) 00202 00203 /* 00204 Event header offsets; 00205 these point to places inside the fixed header. 00206 */ 00207 00208 #define EVENT_TYPE_OFFSET 4 00209 #define SERVER_ID_OFFSET 5 00210 #define EVENT_LEN_OFFSET 9 00211 #define LOG_POS_OFFSET 13 00212 #define FLAGS_OFFSET 17 00213 00214 /* start event post-header (for v3 and v4) */ 00215 00216 #define ST_BINLOG_VER_OFFSET 0 00217 #define ST_SERVER_VER_OFFSET 2 00218 #define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN) 00219 #define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4) 00220 00221 /* slave event post-header (this event is never written) */ 00222 00223 #define SL_MASTER_PORT_OFFSET 8 00224 #define SL_MASTER_POS_OFFSET 0 00225 #define SL_MASTER_HOST_OFFSET 10 00226 00227 /* query event post-header */ 00228 00229 #define Q_THREAD_ID_OFFSET 0 00230 #define Q_EXEC_TIME_OFFSET 4 00231 #define Q_DB_LEN_OFFSET 8 00232 #define Q_ERR_CODE_OFFSET 9 00233 #define Q_STATUS_VARS_LEN_OFFSET 11 00234 #define Q_DATA_OFFSET QUERY_HEADER_LEN 00235 /* these are codes, not offsets; not more than 256 values (1 byte). */ 00236 #define Q_FLAGS2_CODE 0 00237 #define Q_SQL_MODE_CODE 1 00238 /* 00239 Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL 00240 5.0.x where 0<=x<=3. We have to keep it to be able to replicate these 00241 old masters. 00242 */ 00243 #define Q_CATALOG_CODE 2 00244 #define Q_AUTO_INCREMENT 3 00245 #define Q_CHARSET_CODE 4 00246 #define Q_TIME_ZONE_CODE 5 00247 /* 00248 Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL 00249 5.0.x where x>=4. Saves one byte in every Query_log_event in binlog, 00250 compared to Q_CATALOG_CODE. The reason we didn't simply re-use 00251 Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would 00252 crash (segfault etc) because it would expect a 0 when there is none. 00253 */ 00254 #define Q_CATALOG_NZ_CODE 6 00255 00256 /* Intvar event post-header */ 00257 00258 #define I_TYPE_OFFSET 0 00259 #define I_VAL_OFFSET 1 00260 00261 /* Rand event post-header */ 00262 00263 #define RAND_SEED1_OFFSET 0 00264 #define RAND_SEED2_OFFSET 8 00265 00266 /* User_var event post-header */ 00267 00268 #define UV_VAL_LEN_SIZE 4 00269 #define UV_VAL_IS_NULL 1 00270 #define UV_VAL_TYPE_SIZE 1 00271 #define UV_NAME_LEN_SIZE 4 00272 #define UV_CHARSET_NUMBER_SIZE 4 00273 00274 /* Load event post-header */ 00275 00276 #define L_THREAD_ID_OFFSET 0 00277 #define L_EXEC_TIME_OFFSET 4 00278 #define L_SKIP_LINES_OFFSET 8 00279 #define L_TBL_LEN_OFFSET 12 00280 #define L_DB_LEN_OFFSET 13 00281 #define L_NUM_FIELDS_OFFSET 14 00282 #define L_SQL_EX_OFFSET 18 00283 #define L_DATA_OFFSET LOAD_HEADER_LEN 00284 00285 /* Rotate event post-header */ 00286 00287 #define R_POS_OFFSET 0 00288 #define R_IDENT_OFFSET 8 00289 00290 /* CF to DF handle LOAD DATA INFILE */ 00291 00292 /* CF = "Create File" */ 00293 #define CF_FILE_ID_OFFSET 0 00294 #define CF_DATA_OFFSET CREATE_FILE_HEADER_LEN 00295 00296 /* AB = "Append Block" */ 00297 #define AB_FILE_ID_OFFSET 0 00298 #define AB_DATA_OFFSET APPEND_BLOCK_HEADER_LEN 00299 00300 /* EL = "Execute Load" */ 00301 #define EL_FILE_ID_OFFSET 0 00302 00303 /* DF = "Delete File" */ 00304 #define DF_FILE_ID_OFFSET 0 00305 00306 /* TM = "Table Map" */ 00307 #define TM_MAPID_OFFSET 0 00308 #define TM_FLAGS_OFFSET 6 00309 00310 /* RW = "RoWs" */ 00311 #define RW_MAPID_OFFSET 0 00312 #define RW_FLAGS_OFFSET 6 00313 00314 /* ELQ = "Execute Load Query" */ 00315 #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN 00316 #define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4 00317 #define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8 00318 #define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12 00319 00320 /* 4 bytes which all binlogs should begin with */ 00321 #define BINLOG_MAGIC "\xfe\x62\x69\x6e" 00322 00323 /* 00324 The 2 flags below were useless : 00325 - the first one was never set 00326 - the second one was set in all Rotate events on the master, but not used for 00327 anything useful. 00328 So they are now removed and their place may later be reused for other 00329 flags. Then one must remember that Rotate events in 4.x have 00330 LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the 00331 replacing flag when reading a Rotate event. 00332 I keep the defines here just to remember what they were. 00333 */ 00334 #ifdef TO_BE_REMOVED 00335 #define LOG_EVENT_TIME_F 0x1 00336 #define LOG_EVENT_FORCED_ROTATE_F 0x2 00337 #endif 00338 00339 /* 00340 This flag only makes sense for Format_description_log_event. It is set 00341 when the event is written, and *reset* when a binlog file is 00342 closed (yes, it's the only case when MySQL modifies already written 00343 part of binlog). Thus it is a reliable indicator that binlog was 00344 closed correctly. (Stop_log_event is not enough, there's always a 00345 small chance that mysqld crashes in the middle of insert and end of 00346 the binlog would look like a Stop_log_event). 00347 00348 This flag is used to detect a restart after a crash, and to provide 00349 "unbreakable" binlog. The problem is that on a crash storage engines 00350 rollback automatically, while binlog does not. To solve this we use this 00351 flag and automatically append ROLLBACK to every non-closed binlog (append 00352 virtually, on reading, file itself is not changed). If this flag is found, 00353 mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on 00354 binlog corruption, but takes it as EOF, and replication slave forces a 00355 rollback in this case. 00356 00357 Note, that old binlogs does not have this flag set, so we get a 00358 a backward-compatible behaviour. 00359 */ 00360 00361 #define LOG_EVENT_BINLOG_IN_USE_F 0x1 00362 00363 /* 00364 If the query depends on the thread (for example: TEMPORARY TABLE). 00365 Currently this is used by mysqlbinlog to know it must print 00366 SET @@PSEUDO_THREAD_ID=xx; before the query (it would not hurt to print it 00367 for every query but this would be slow). 00368 */ 00369 #define LOG_EVENT_THREAD_SPECIFIC_F 0x4 00370 00371 /* 00372 Suppress the generation of 'USE' statements before the actual 00373 statement. This flag should be set for any events that does not need 00374 the current database set to function correctly. Most notable cases 00375 are 'CREATE DATABASE' and 'DROP DATABASE'. 00376 00377 This flags should only be used in exceptional circumstances, since 00378 it introduce a significant change in behaviour regarding the 00379 replication logic together with the flags --binlog-do-db and 00380 --replicated-do-db. 00381 */ 00382 #define LOG_EVENT_SUPPRESS_USE_F 0x8 00383 00384 /* 00385 The table map version internal to the log should be increased after 00386 the event has been written to the binary log. 00387 */ 00388 #define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10 00389 00390 /* 00391 OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must be 00392 written to the binlog. OPTIONS_WRITTEN_TO_BINLOG could be written 00393 into the Format_description_log_event, so that if later we don't want 00394 to replicate a variable we did replicate, or the contrary, it's 00395 doable. But it should not be too hard to decide once for all of what 00396 we replicate and what we don't, among the fixed 32 bits of 00397 thd->options. 00398 I (Guilhem) have read through every option's usage, and it looks like 00399 OPTION_AUTO_IS_NULL and OPTION_NO_FOREIGN_KEYS are the only ones 00400 which alter how the query modifies the table. It's good to replicate 00401 OPTION_RELAXED_UNIQUE_CHECKS too because otherwise, the slave may 00402 insert data slower than the master, in InnoDB. 00403 OPTION_BIG_SELECTS is not needed (the slave thread runs with 00404 max_join_size=HA_POS_ERROR) and OPTION_BIG_TABLES is not needed 00405 either, as the manual says (because a too big in-memory temp table is 00406 automatically written to disk). 00407 */ 00408 #define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_AUTO_IS_NULL | \ 00409 OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS) 00410 00411 #if OPTIONS_WRITTEN_TO_BIN_LOG != ((1L << 14) | (1L << 26) | (1L << 27)) 00412 #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values! 00413 #endif 00414 00415 enum Log_event_type 00416 { 00417 /* 00418 Every time you update this enum (when you add a type), you have to 00419 fix Format_description_log_event::Format_description_log_event(). 00420 */ 00421 UNKNOWN_EVENT= 0, 00422 START_EVENT_V3= 1, 00423 QUERY_EVENT= 2, 00424 STOP_EVENT= 3, 00425 ROTATE_EVENT= 4, 00426 INTVAR_EVENT= 5, 00427 LOAD_EVENT= 6, 00428 SLAVE_EVENT= 7, 00429 CREATE_FILE_EVENT= 8, 00430 APPEND_BLOCK_EVENT= 9, 00431 EXEC_LOAD_EVENT= 10, 00432 DELETE_FILE_EVENT= 11, 00433 /* 00434 NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer 00435 sql_ex, allowing multibyte TERMINATED BY etc; both types share the 00436 same class (Load_log_event) 00437 */ 00438 NEW_LOAD_EVENT= 12, 00439 RAND_EVENT= 13, 00440 USER_VAR_EVENT= 14, 00441 FORMAT_DESCRIPTION_EVENT= 15, 00442 XID_EVENT= 16, 00443 BEGIN_LOAD_QUERY_EVENT= 17, 00444 EXECUTE_LOAD_QUERY_EVENT= 18, 00445 TABLE_MAP_EVENT = 19, 00446 WRITE_ROWS_EVENT = 20, 00447 UPDATE_ROWS_EVENT = 21, 00448 DELETE_ROWS_EVENT = 22, 00449 00450 /* 00451 Add new events here - right above this comment! 00452 Existing events (except ENUM_END_EVENT) should never change their numbers 00453 */ 00454 00455 ENUM_END_EVENT /* end marker */ 00456 }; 00457 00458 /* 00459 The number of types we handle in Format_description_log_event (UNKNOWN_EVENT 00460 is not to be handled, it does not exist in binlogs, it does not have a 00461 format). 00462 */ 00463 #define LOG_EVENT_TYPES (ENUM_END_EVENT-1) 00464 00465 enum Int_event_type 00466 { 00467 INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2 00468 }; 00469 00470 00471 #ifndef MYSQL_CLIENT 00472 class String; 00473 class MYSQL_BIN_LOG; 00474 class THD; 00475 #endif 00476 00477 class Format_description_log_event; 00478 00479 struct st_relay_log_info; 00480 00481 #ifdef MYSQL_CLIENT 00482 /* 00483 A structure for mysqlbinlog to know how to print events 00484 00485 This structure is passed to the event's print() methods, 00486 00487 There are two types of settings stored here: 00488 1. Last db, flags2, sql_mode etc comes from the last printed event. 00489 They are stored so that only the necessary USE and SET commands 00490 are printed. 00491 2. Other information on how to print the events, e.g. short_form, 00492 hexdump_from. These are not dependent on the last event. 00493 */ 00494 typedef struct st_print_event_info 00495 { 00496 /* 00497 Settings for database, sql_mode etc that comes from the last event 00498 that was printed. 00499 */ 00500 // TODO: have the last catalog here ?? 00501 char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is 00502 bool flags2_inited; 00503 uint32 flags2; 00504 bool sql_mode_inited; 00505 ulong sql_mode; /* must be same as THD.variables.sql_mode */ 00506 ulong auto_increment_increment, auto_increment_offset; 00507 bool charset_inited; 00508 char charset[6]; // 3 variables, each of them storable in 2 bytes 00509 char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH]; 00510 st_print_event_info() 00511 :flags2_inited(0), sql_mode_inited(0), 00512 auto_increment_increment(1),auto_increment_offset(1), charset_inited(0) 00513 { 00514 /* 00515 Currently we only use static PRINT_EVENT_INFO objects, so zeroed at 00516 program's startup, but these explicit bzero() is for the day someone 00517 creates dynamic instances. 00518 */ 00519 bzero(db, sizeof(db)); 00520 bzero(charset, sizeof(charset)); 00521 bzero(time_zone_str, sizeof(time_zone_str)); 00522 } 00523 00524 /* Settings on how to print the events */ 00525 bool short_form; 00526 bool base64_output; 00527 my_off_t hexdump_from; 00528 uint8 common_header_len; 00529 00530 } PRINT_EVENT_INFO; 00531 #endif 00532 00533 00534 /***************************************************************************** 00535 00536 Log_event class 00537 00538 This is the abstract base class for binary log events. 00539 00540 ****************************************************************************/ 00541 class Log_event 00542 { 00543 public: 00544 /* 00545 The offset in the log where this event originally appeared (it is 00546 preserved in relay logs, making SHOW SLAVE STATUS able to print 00547 coordinates of the event in the master's binlog). Note: when a 00548 transaction is written by the master to its binlog (wrapped in 00549 BEGIN/COMMIT) the log_pos of all the queries it contains is the 00550 one of the BEGIN (this way, when one does SHOW SLAVE STATUS it 00551 sees the offset of the BEGIN, which is logical as rollback may 00552 occur), except the COMMIT query which has its real offset. 00553 */ 00554 my_off_t log_pos; 00555 /* 00556 A temp buffer for read_log_event; it is later analysed according to the 00557 event's type, and its content is distributed in the event-specific fields. 00558 */ 00559 char *temp_buf; 00560 /* 00561 Timestamp on the master(for debugging and replication of 00562 NOW()/TIMESTAMP). It is important for queries and LOAD DATA 00563 INFILE. This is set at the event's creation time, except for Query 00564 and Load (et al.) events where this is set at the query's 00565 execution time, which guarantees good replication (otherwise, we 00566 could have a query and its event with different timestamps). 00567 */ 00568 time_t when; 00569 /* The number of seconds the query took to run on the master. */ 00570 ulong exec_time; 00571 /* Number of bytes written by write() function */ 00572 ulong data_written; 00573 00574 /* 00575 The master's server id (is preserved in the relay log; used to 00576 prevent from infinite loops in circular replication). 00577 */ 00578 uint32 server_id; 00579 00580 /* 00581 Some 16 flags. Look above for LOG_EVENT_TIME_F, 00582 LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F, and 00583 LOG_EVENT_SUPPRESS_USE_F for notes. 00584 */ 00585 uint16 flags; 00586 00587 bool cache_stmt; 00588 00589 #ifndef MYSQL_CLIENT 00590 THD* thd; 00591 00592 Log_event(); 00593 Log_event(THD* thd_arg, uint16 flags_arg, bool cache_stmt); 00594 /* 00595 read_log_event() functions read an event from a binlog or relay 00596 log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the 00597 master (reads master's binlog), the slave IO thread (reads the 00598 event sent by binlog_dump), the slave SQL thread (reads the event 00599 from the relay log). If mutex is 0, the read will proceed without 00600 mutex. We need the description_event to be able to parse the 00601 event (to know the post-header's size); in fact in read_log_event 00602 we detect the event's type, then call the specific event's 00603 constructor and pass description_event as an argument. 00604 */ 00605 static Log_event* read_log_event(IO_CACHE* file, 00606 pthread_mutex_t* log_lock, 00607 const Format_description_log_event *description_event); 00608 static int read_log_event(IO_CACHE* file, String* packet, 00609 pthread_mutex_t* log_lock); 00610 /* 00611 init_show_field_list() prepares the column names and types for the 00612 output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG 00613 EVENTS. 00614 */ 00615 static void init_show_field_list(List<Item>* field_list); 00616 #ifdef HAVE_REPLICATION 00617 int net_send(Protocol *protocol, const char* log_name, my_off_t pos); 00618 /* 00619 pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends 00620 a string to display to the user, so it resembles print(). 00621 */ 00622 virtual void pack_info(Protocol *protocol); 00623 /* 00624 The SQL slave thread calls exec_event() to execute the event; this is where 00625 the slave's data is modified. 00626 */ 00627 virtual int exec_event(struct st_relay_log_info* rli); 00628 #endif /* HAVE_REPLICATION */ 00629 virtual const char* get_db() 00630 { 00631 return thd ? thd->db : 0; 00632 } 00633 #else 00634 Log_event() : temp_buf(0) {} 00635 /* avoid having to link mysqlbinlog against libpthread */ 00636 static Log_event* read_log_event(IO_CACHE* file, 00637 const Format_description_log_event *description_event); 00638 /* print*() functions are used by mysqlbinlog */ 00639 virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0; 00640 void print_timestamp(FILE* file, time_t *ts = 0); 00641 void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info); 00642 void print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info); 00643 #endif 00644 00645 static void *operator new(size_t size) 00646 { 00647 return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE)); 00648 } 00649 00650 static void operator delete(void *ptr, size_t size) 00651 { 00652 my_free((gptr) ptr, MYF(MY_WME|MY_ALLOW_ZERO_PTR)); 00653 } 00654 00655 /* Placement version of the above operators */ 00656 static void *operator new(size_t, void* ptr) { return ptr; } 00657 static void operator delete(void*, void*) { } 00658 00659 #ifndef MYSQL_CLIENT 00660 bool write_header(IO_CACHE* file, ulong data_length); 00661 virtual bool write(IO_CACHE* file) 00662 { 00663 return (write_header(file, get_data_size()) || 00664 write_data_header(file) || 00665 write_data_body(file)); 00666 } 00667 virtual bool write_data_header(IO_CACHE* file) 00668 { return 0; } 00669 virtual bool write_data_body(IO_CACHE* file __attribute__((unused))) 00670 { return 0; } 00671 #endif 00672 virtual Log_event_type get_type_code() = 0; 00673 virtual bool is_valid() const = 0; 00674 virtual bool is_artificial_event() { return 0; } 00675 inline bool get_cache_stmt() const { return cache_stmt; } 00676 Log_event(const char* buf, const Format_description_log_event* description_event); 00677 virtual ~Log_event() { free_temp_buf();} 00678 void register_temp_buf(char* buf) { temp_buf = buf; } 00679 void free_temp_buf() 00680 { 00681 if (temp_buf) 00682 { 00683 my_free(temp_buf, MYF(0)); 00684 temp_buf = 0; 00685 } 00686 } 00687 /* 00688 Get event length for simple events. For complicated events the length 00689 is calculated during write() 00690 */ 00691 virtual int get_data_size() { return 0;} 00692 static Log_event* read_log_event(const char* buf, uint event_len, 00693 const char **error, 00694 const Format_description_log_event 00695 *description_event); 00696 /* returns the human readable name of the event's type */ 00697 const char* get_type_str(); 00698 }; 00699 00700 /* 00701 One class for each type of event. 00702 Two constructors for each class: 00703 - one to create the event for logging (when the server acts as a master), 00704 called after an update to the database is done, 00705 which accepts parameters like the query, the database, the options for LOAD 00706 DATA INFILE... 00707 - one to create the event from a packet (when the server acts as a slave), 00708 called before reproducing the update, which accepts parameters (like a 00709 buffer). Used to read from the master, from the relay log, and in 00710 mysqlbinlog. This constructor must be format-tolerant. 00711 */ 00712 00713 /***************************************************************************** 00714 00715 Query Log Event class 00716 00717 Logs SQL queries 00718 00719 ****************************************************************************/ 00720 class Query_log_event: public Log_event 00721 { 00722 protected: 00723 char* data_buf; 00724 public: 00725 const char* query; 00726 const char* catalog; 00727 const char* db; 00728 /* 00729 If we already know the length of the query string 00730 we pass it with q_len, so we would not have to call strlen() 00731 otherwise, set it to 0, in which case, we compute it with strlen() 00732 */ 00733 uint32 q_len; 00734 uint32 db_len; 00735 uint16 error_code; 00736 ulong thread_id; 00737 /* 00738 For events created by Query_log_event::exec_event (and 00739 Load_log_event::exec_event()) we need the *original* thread id, to be able 00740 to log the event with the original (=master's) thread id (fix for 00741 BUG#1686). 00742 */ 00743 ulong slave_proxy_id; 00744 00745 /* 00746 Binlog format 3 and 4 start to differ (as far as class members are 00747 concerned) from here. 00748 */ 00749 00750 uint catalog_len; // <= 255 char; 0 means uninited 00751 00752 /* 00753 We want to be able to store a variable number of N-bit status vars: 00754 (generally N=32; but N=64 for SQL_MODE) a user may want to log the number 00755 of affected rows (for debugging) while another does not want to lose 4 00756 bytes in this. 00757 The storage on disk is the following: 00758 status_vars_len is part of the post-header, 00759 status_vars are in the variable-length part, after the post-header, before 00760 the db & query. 00761 status_vars on disk is a sequence of pairs (code, value) where 'code' means 00762 'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so 00763 its first byte is its length. For now the order of status vars is: 00764 flags2 - sql_mode - catalog - autoinc - charset 00765 We should add the same thing to Load_log_event, but in fact 00766 LOAD DATA INFILE is going to be logged with a new type of event (logging of 00767 the plain text query), so Load_log_event would be frozen, so no need. The 00768 new way of logging LOAD DATA INFILE would use a derived class of 00769 Query_log_event, so automatically benefit from the work already done for 00770 status variables in Query_log_event. 00771 */ 00772 uint16 status_vars_len; 00773 00774 /* 00775 'flags2' is a second set of flags (on top of those in Log_event), for 00776 session variables. These are thd->options which is & against a mask 00777 (OPTIONS_WRITTEN_TO_BINLOG). 00778 flags2_inited helps make a difference between flags2==0 (3.23 or 4.x 00779 master, we don't know flags2, so use the slave server's global options) and 00780 flags2==0 (5.0 master, we know this has a meaning of flags all down which 00781 must influence the query). 00782 */ 00783 bool flags2_inited; 00784 bool sql_mode_inited; 00785 bool charset_inited; 00786 00787 uint32 flags2; 00788 /* In connections sql_mode is 32 bits now but will be 64 bits soon */ 00789 ulong sql_mode; 00790 ulong auto_increment_increment, auto_increment_offset; 00791 char charset[6]; 00792 uint time_zone_len; /* 0 means uninited */ 00793 const char *time_zone_str; 00794 00795 #ifndef MYSQL_CLIENT 00796 00797 Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length, 00798 bool using_trans, bool suppress_use); 00799 const char* get_db() { return db; } 00800 #ifdef HAVE_REPLICATION 00801 void pack_info(Protocol* protocol); 00802 int exec_event(struct st_relay_log_info* rli); 00803 int exec_event(struct st_relay_log_info* rli, const char *query_arg, 00804 uint32 q_len_arg); 00805 #endif /* HAVE_REPLICATION */ 00806 #else 00807 void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info); 00808 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 00809 #endif 00810 00811 Query_log_event(); 00812 Query_log_event(const char* buf, uint event_len, 00813 const Format_description_log_event *description_event, 00814 Log_event_type event_type); 00815 ~Query_log_event() 00816 { 00817 if (data_buf) 00818 my_free((gptr) data_buf, MYF(0)); 00819 } 00820 Log_event_type get_type_code() { return QUERY_EVENT; } 00821 #ifndef MYSQL_CLIENT 00822 bool write(IO_CACHE* file); 00823 virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; } 00824 #endif 00825 bool is_valid() const { return query != 0; } 00826 00827 /* 00828 Returns number of bytes additionaly written to post header by derived 00829 events (so far it is only Execute_load_query event). 00830 */ 00831 virtual ulong get_post_header_size_for_derived() { return 0; } 00832 /* Writes derived event-specific part of post header. */ 00833 }; 00834 00835 00836 /***************************************************************************** 00837 00838 Muted Query Log Event class 00839 00840 Pretends to Log SQL queries, but doesn't actually do so. 00841 00842 ****************************************************************************/ 00843 class Muted_query_log_event: public Query_log_event 00844 { 00845 public: 00846 #ifndef MYSQL_CLIENT 00847 Muted_query_log_event(); 00848 00849 bool write(IO_CACHE* file) { return(false); }; 00850 virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; } 00851 #endif 00852 }; 00853 00854 00855 #ifdef HAVE_REPLICATION 00856 00857 /***************************************************************************** 00858 00859 Slave Log Event class 00860 Note that this class is currently not used at all; no code writes a 00861 Slave_log_event (though some code in repl_failsafe.cc reads Slave_log_event). 00862 So it's not a problem if this code is not maintained. 00863 00864 ****************************************************************************/ 00865 class Slave_log_event: public Log_event 00866 { 00867 protected: 00868 char* mem_pool; 00869 void init_from_mem_pool(int data_size); 00870 public: 00871 my_off_t master_pos; 00872 char* master_host; 00873 char* master_log; 00874 int master_host_len; 00875 int master_log_len; 00876 uint16 master_port; 00877 00878 #ifndef MYSQL_CLIENT 00879 Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli); 00880 void pack_info(Protocol* protocol); 00881 int exec_event(struct st_relay_log_info* rli); 00882 #else 00883 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 00884 #endif 00885 00886 Slave_log_event(const char* buf, uint event_len); 00887 ~Slave_log_event(); 00888 int get_data_size(); 00889 bool is_valid() const { return master_host != 0; } 00890 Log_event_type get_type_code() { return SLAVE_EVENT; } 00891 #ifndef MYSQL_CLIENT 00892 bool write(IO_CACHE* file); 00893 #endif 00894 }; 00895 00896 #endif /* HAVE_REPLICATION */ 00897 00898 00899 /***************************************************************************** 00900 00901 Load Log Event class 00902 00903 ****************************************************************************/ 00904 class Load_log_event: public Log_event 00905 { 00906 private: 00907 uint get_query_buffer_length(); 00908 void print_query(bool need_db, char *buf, char **end, 00909 char **fn_start, char **fn_end); 00910 protected: 00911 int copy_log_event(const char *buf, ulong event_len, 00912 int body_offset, const Format_description_log_event* description_event); 00913 00914 public: 00915 ulong thread_id; 00916 ulong slave_proxy_id; 00917 uint32 table_name_len; 00918 /* 00919 No need to have a catalog, as these events can only come from 4.x. 00920 TODO: this may become false if Dmitri pushes his new LOAD DATA INFILE in 00921 5.0 only (not in 4.x). 00922 */ 00923 uint32 db_len; 00924 uint32 fname_len; 00925 uint32 num_fields; 00926 const char* fields; 00927 const uchar* field_lens; 00928 uint32 field_block_len; 00929 00930 const char* table_name; 00931 const char* db; 00932 const char* fname; 00933 uint32 skip_lines; 00934 sql_ex_info sql_ex; 00935 bool local_fname; 00936 00937 /* fname doesn't point to memory inside Log_event::temp_buf */ 00938 void set_fname_outside_temp_buf(const char *afname, uint alen) 00939 { 00940 fname= afname; 00941 fname_len= alen; 00942 local_fname= TRUE; 00943 } 00944 /* fname doesn't point to memory inside Log_event::temp_buf */ 00945 int check_fname_outside_temp_buf() 00946 { 00947 return local_fname; 00948 } 00949 00950 #ifndef MYSQL_CLIENT 00951 String field_lens_buf; 00952 String fields_buf; 00953 00954 Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg, 00955 const char* table_name_arg, 00956 List<Item>& fields_arg, enum enum_duplicates handle_dup, bool ignore, 00957 bool using_trans); 00958 void set_fields(const char* db, List<Item> &fields_arg, 00959 Name_resolution_context *context); 00960 const char* get_db() { return db; } 00961 #ifdef HAVE_REPLICATION 00962 void pack_info(Protocol* protocol); 00963 int exec_event(struct st_relay_log_info* rli) 00964 { 00965 return exec_event(thd->slave_net,rli,0); 00966 } 00967 int exec_event(NET* net, struct st_relay_log_info* rli, 00968 bool use_rli_only_for_errors); 00969 #endif /* HAVE_REPLICATION */ 00970 #else 00971 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 00972 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented); 00973 #endif 00974 00975 /* 00976 Note that for all the events related to LOAD DATA (Load_log_event, 00977 Create_file/Append/Exec/Delete, we pass description_event; however as 00978 logging of LOAD DATA is going to be changed in 4.1 or 5.0, this is only used 00979 for the common_header_len (post_header_len will not be changed). 00980 */ 00981 Load_log_event(const char* buf, uint event_len, 00982 const Format_description_log_event* description_event); 00983 ~Load_log_event() 00984 {} 00985 Log_event_type get_type_code() 00986 { 00987 return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT; 00988 } 00989 #ifndef MYSQL_CLIENT 00990 bool write_data_header(IO_CACHE* file); 00991 bool write_data_body(IO_CACHE* file); 00992 #endif 00993 bool is_valid() const { return table_name != 0; } 00994 int get_data_size() 00995 { 00996 return (table_name_len + db_len + 2 + fname_len 00997 + LOAD_HEADER_LEN 00998 + sql_ex.data_size() + field_block_len + num_fields); 00999 } 01000 }; 01001 01002 extern char server_version[SERVER_VERSION_LENGTH]; 01003 01004 /***************************************************************************** 01005 01006 Start Log Event_v3 class 01007 01008 Start_log_event_v3 is the Start_log_event of binlog format 3 (MySQL 3.23 and 01009 4.x). 01010 Format_description_log_event derives from Start_log_event_v3; it is the 01011 Start_log_event of binlog format 4 (MySQL 5.0), that is, the event that 01012 describes the other events' header/postheader lengths. This event is sent by 01013 MySQL 5.0 whenever it starts sending a new binlog if the requested position 01014 is >4 (otherwise if ==4 the event will be sent naturally). 01015 01016 ****************************************************************************/ 01017 01018 class Start_log_event_v3: public Log_event 01019 { 01020 public: 01021 /* 01022 If this event is at the start of the first binary log since server 01023 startup 'created' should be the timestamp when the event (and the 01024 binary log) was created. In the other case (i.e. this event is at 01025 the start of a binary log created by FLUSH LOGS or automatic 01026 rotation), 'created' should be 0. This "trick" is used by MySQL 01027 >=4.0.14 slaves to know whether they must drop stale temporary 01028 tables and whether they should abort unfinished transaction. 01029 01030 Note that when 'created'!=0, it is always equal to the event's 01031 timestamp; indeed Start_log_event is written only in log.cc where 01032 the first constructor below is called, in which 'created' is set 01033 to 'when'. So in fact 'created' is a useless variable. When it is 01034 0 we can read the actual value from timestamp ('when') and when it 01035 is non-zero we can read the same value from timestamp 01036 ('when'). Conclusion: 01037 - we use timestamp to print when the binlog was created. 01038 - we use 'created' only to know if this is a first binlog or not. 01039 In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in 01040 3.23.57 does not print 'created the_date' if created was zero. This is now 01041 fixed. 01042 */ 01043 time_t created; 01044 uint16 binlog_version; 01045 char server_version[ST_SERVER_VER_LEN]; 01046 /* 01047 artifical_event is 1 in the case where this is a generated event that 01048 should not case any cleanup actions. We handle this in the log by 01049 setting log_event == 0 (for now). 01050 */ 01051 bool artificial_event; 01052 01053 #ifndef MYSQL_CLIENT 01054 Start_log_event_v3(); 01055 #ifdef HAVE_REPLICATION 01056 void pack_info(Protocol* protocol); 01057 int exec_event(struct st_relay_log_info* rli); 01058 #endif /* HAVE_REPLICATION */ 01059 #else 01060 Start_log_event_v3() {} 01061 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01062 #endif 01063 01064 Start_log_event_v3(const char* buf, 01065 const Format_description_log_event* description_event); 01066 ~Start_log_event_v3() {} 01067 Log_event_type get_type_code() { return START_EVENT_V3;} 01068 #ifndef MYSQL_CLIENT 01069 bool write(IO_CACHE* file); 01070 #endif 01071 bool is_valid() const { return 1; } 01072 int get_data_size() 01073 { 01074 return START_V3_HEADER_LEN; //no variable-sized part 01075 } 01076 virtual bool is_artificial_event() { return artificial_event; } 01077 }; 01078 01079 01080 /* 01081 For binlog version 4. 01082 This event is saved by threads which read it, as they need it for future 01083 use (to decode the ordinary events). 01084 */ 01085 01086 class Format_description_log_event: public Start_log_event_v3 01087 { 01088 public: 01089 /* 01090 The size of the fixed header which _all_ events have 01091 (for binlogs written by this version, this is equal to 01092 LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT 01093 (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN). 01094 */ 01095 uint8 common_header_len; 01096 uint8 number_of_event_types; 01097 /* The list of post-headers' lengthes */ 01098 uint8 *post_header_len; 01099 01100 Format_description_log_event(uint8 binlog_ver, const char* server_ver=0); 01101 01102 #ifndef MYSQL_CLIENT 01103 #ifdef HAVE_REPLICATION 01104 int exec_event(struct st_relay_log_info* rli); 01105 #endif /* HAVE_REPLICATION */ 01106 #endif 01107 01108 Format_description_log_event(const char* buf, uint event_len, 01109 const Format_description_log_event* description_event); 01110 ~Format_description_log_event() { my_free((gptr)post_header_len, MYF(0)); } 01111 Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;} 01112 #ifndef MYSQL_CLIENT 01113 bool write(IO_CACHE* file); 01114 #endif 01115 bool is_valid() const 01116 { 01117 return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN : 01118 LOG_EVENT_MINIMAL_HEADER_LEN)) && 01119 (post_header_len != NULL)); 01120 } 01121 int get_data_size() 01122 { 01123 /* 01124 The vector of post-header lengths is considered as part of the 01125 post-header, because in a given version it never changes (contrary to the 01126 query in a Query_log_event). 01127 */ 01128 return FORMAT_DESCRIPTION_HEADER_LEN; 01129 } 01130 }; 01131 01132 01133 /***************************************************************************** 01134 01135 Intvar Log Event class 01136 01137 Logs special variables such as auto_increment values 01138 01139 ****************************************************************************/ 01140 01141 class Intvar_log_event: public Log_event 01142 { 01143 public: 01144 ulonglong val; 01145 uchar type; 01146 01147 #ifndef MYSQL_CLIENT 01148 Intvar_log_event(THD* thd_arg,uchar type_arg, ulonglong val_arg) 01149 :Log_event(thd_arg,0,0),val(val_arg),type(type_arg) 01150 {} 01151 #ifdef HAVE_REPLICATION 01152 void pack_info(Protocol* protocol); 01153 int exec_event(struct st_relay_log_info* rli); 01154 #endif /* HAVE_REPLICATION */ 01155 #else 01156 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01157 #endif 01158 01159 Intvar_log_event(const char* buf, const Format_description_log_event* description_event); 01160 ~Intvar_log_event() {} 01161 Log_event_type get_type_code() { return INTVAR_EVENT;} 01162 const char* get_var_type_name(); 01163 int get_data_size() { return 9; /* sizeof(type) + sizeof(val) */;} 01164 #ifndef MYSQL_CLIENT 01165 bool write(IO_CACHE* file); 01166 #endif 01167 bool is_valid() const { return 1; } 01168 }; 01169 01170 01171 /***************************************************************************** 01172 01173 Rand Log Event class 01174 01175 Logs random seed used by the next RAND(), and by PASSWORD() in 4.1.0. 01176 4.1.1 does not need it (it's repeatable again) so this event needn't be 01177 written in 4.1.1 for PASSWORD() (but the fact that it is written is just a 01178 waste, it does not cause bugs). 01179 01180 ****************************************************************************/ 01181 01182 class Rand_log_event: public Log_event 01183 { 01184 public: 01185 ulonglong seed1; 01186 ulonglong seed2; 01187 01188 #ifndef MYSQL_CLIENT 01189 Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg) 01190 :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg) 01191 {} 01192 #ifdef HAVE_REPLICATION 01193 void pack_info(Protocol* protocol); 01194 int exec_event(struct st_relay_log_info* rli); 01195 #endif /* HAVE_REPLICATION */ 01196 #else 01197 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01198 #endif 01199 01200 Rand_log_event(const char* buf, const Format_description_log_event* description_event); 01201 ~Rand_log_event() {} 01202 Log_event_type get_type_code() { return RAND_EVENT;} 01203 int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ } 01204 #ifndef MYSQL_CLIENT 01205 bool write(IO_CACHE* file); 01206 #endif 01207 bool is_valid() const { return 1; } 01208 }; 01209 01210 /***************************************************************************** 01211 01212 Xid Log Event class 01213 01214 Logs xid of the transaction-to-be-committed in the 2pc protocol. 01215 Has no meaning in replication, slaves ignore it. 01216 01217 ****************************************************************************/ 01218 #ifdef MYSQL_CLIENT 01219 typedef ulonglong my_xid; // this line is the same as in handler.h 01220 #endif 01221 01222 class Xid_log_event: public Log_event 01223 { 01224 public: 01225 my_xid xid; 01226 01227 #ifndef MYSQL_CLIENT 01228 Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {} 01229 #ifdef HAVE_REPLICATION 01230 void pack_info(Protocol* protocol); 01231 int exec_event(struct st_relay_log_info* rli); 01232 #endif /* HAVE_REPLICATION */ 01233 #else 01234 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01235 #endif 01236 01237 Xid_log_event(const char* buf, const Format_description_log_event* description_event); 01238 ~Xid_log_event() {} 01239 Log_event_type get_type_code() { return XID_EVENT;} 01240 int get_data_size() { return sizeof(xid); } 01241 #ifndef MYSQL_CLIENT 01242 bool write(IO_CACHE* file); 01243 #endif 01244 bool is_valid() const { return 1; } 01245 }; 01246 01247 /***************************************************************************** 01248 01249 User var Log Event class 01250 01251 Every time a query uses the value of a user variable, a User_var_log_event is 01252 written before the Query_log_event, to set the user variable. 01253 01254 ****************************************************************************/ 01255 01256 class User_var_log_event: public Log_event 01257 { 01258 public: 01259 char *name; 01260 uint name_len; 01261 char *val; 01262 ulong val_len; 01263 Item_result type; 01264 uint charset_number; 01265 bool is_null; 01266 #ifndef MYSQL_CLIENT 01267 User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, 01268 char *val_arg, ulong val_len_arg, Item_result type_arg, 01269 uint charset_number_arg) 01270 :Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg), 01271 val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg) 01272 { is_null= !val; } 01273 void pack_info(Protocol* protocol); 01274 int exec_event(struct st_relay_log_info* rli); 01275 #else 01276 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01277 #endif 01278 01279 User_var_log_event(const char* buf, const Format_description_log_event* description_event); 01280 ~User_var_log_event() {} 01281 Log_event_type get_type_code() { return USER_VAR_EVENT;} 01282 #ifndef MYSQL_CLIENT 01283 bool write(IO_CACHE* file); 01284 #endif 01285 bool is_valid() const { return 1; } 01286 }; 01287 01288 01289 /***************************************************************************** 01290 01291 Stop Log Event class 01292 01293 ****************************************************************************/ 01294 class Stop_log_event: public Log_event 01295 { 01296 public: 01297 #ifndef MYSQL_CLIENT 01298 Stop_log_event() :Log_event() 01299 {} 01300 int exec_event(struct st_relay_log_info* rli); 01301 #else 01302 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01303 #endif 01304 01305 Stop_log_event(const char* buf, const Format_description_log_event* description_event): 01306 Log_event(buf, description_event) 01307 {} 01308 ~Stop_log_event() {} 01309 Log_event_type get_type_code() { return STOP_EVENT;} 01310 bool is_valid() const { return 1; } 01311 }; 01312 01313 /***************************************************************************** 01314 01315 Rotate Log Event class 01316 01317 This will be deprecated when we move to using sequence ids. 01318 01319 ****************************************************************************/ 01320 01321 class Rotate_log_event: public Log_event 01322 { 01323 public: 01324 enum { 01325 DUP_NAME= 2 // if constructor should dup the string argument 01326 }; 01327 const char* new_log_ident; 01328 ulonglong pos; 01329 uint ident_len; 01330 uint flags; 01331 #ifndef MYSQL_CLIENT 01332 Rotate_log_event(const char* new_log_ident_arg, 01333 uint ident_len_arg, 01334 ulonglong pos_arg, uint flags); 01335 #ifdef HAVE_REPLICATION 01336 void pack_info(Protocol* protocol); 01337 int exec_event(struct st_relay_log_info* rli); 01338 #endif /* HAVE_REPLICATION */ 01339 #else 01340 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01341 #endif 01342 01343 Rotate_log_event(const char* buf, uint event_len, 01344 const Format_description_log_event* description_event); 01345 ~Rotate_log_event() 01346 { 01347 if (flags & DUP_NAME) 01348 my_free((gptr) new_log_ident, MYF(MY_ALLOW_ZERO_PTR)); 01349 } 01350 Log_event_type get_type_code() { return ROTATE_EVENT;} 01351 int get_data_size() { return ident_len + ROTATE_HEADER_LEN;} 01352 bool is_valid() const { return new_log_ident != 0; } 01353 #ifndef MYSQL_CLIENT 01354 bool write(IO_CACHE* file); 01355 #endif 01356 }; 01357 01358 01359 /* the classes below are for the new LOAD DATA INFILE logging */ 01360 01361 /***************************************************************************** 01362 Create File Log Event class 01363 ****************************************************************************/ 01364 01365 class Create_file_log_event: public Load_log_event 01366 { 01367 protected: 01368 /* 01369 Pretend we are Load event, so we can write out just 01370 our Load part - used on the slave when writing event out to 01371 SQL_LOAD-*.info file 01372 */ 01373 bool fake_base; 01374 public: 01375 char* block; 01376 const char *event_buf; 01377 uint block_len; 01378 uint file_id; 01379 bool inited_from_old; 01380 01381 #ifndef MYSQL_CLIENT 01382 Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, 01383 const char* table_name_arg, 01384 List<Item>& fields_arg, 01385 enum enum_duplicates handle_dup, bool ignore, 01386 char* block_arg, uint block_len_arg, 01387 bool using_trans); 01388 #ifdef HAVE_REPLICATION 01389 void pack_info(Protocol* protocol); 01390 int exec_event(struct st_relay_log_info* rli); 01391 #endif /* HAVE_REPLICATION */ 01392 #else 01393 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01394 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local); 01395 #endif 01396 01397 Create_file_log_event(const char* buf, uint event_len, 01398 const Format_description_log_event* description_event); 01399 ~Create_file_log_event() 01400 { 01401 my_free((char*) event_buf, MYF(MY_ALLOW_ZERO_PTR)); 01402 } 01403 01404 Log_event_type get_type_code() 01405 { 01406 return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT; 01407 } 01408 int get_data_size() 01409 { 01410 return (fake_base ? Load_log_event::get_data_size() : 01411 Load_log_event::get_data_size() + 01412 4 + 1 + block_len); 01413 } 01414 bool is_valid() const { return inited_from_old || block != 0; } 01415 #ifndef MYSQL_CLIENT 01416 bool write_data_header(IO_CACHE* file); 01417 bool write_data_body(IO_CACHE* file); 01418 /* 01419 Cut out Create_file extentions and 01420 write it as Load event - used on the slave 01421 */ 01422 bool write_base(IO_CACHE* file); 01423 #endif 01424 }; 01425 01426 01427 /***************************************************************************** 01428 01429 Append Block Log Event class 01430 01431 ****************************************************************************/ 01432 01433 class Append_block_log_event: public Log_event 01434 { 01435 public: 01436 char* block; 01437 uint block_len; 01438 uint file_id; 01439 /* 01440 'db' is filled when the event is created in mysql_load() (the 01441 event needs to have a 'db' member to be well filtered by 01442 binlog-*-db rules). 'db' is not written to the binlog (it's not 01443 used by Append_block_log_event::write()), so it can't be read in 01444 the Append_block_log_event(const char* buf, int event_len) 01445 constructor. In other words, 'db' is used only for filtering by 01446 binlog-*-db rules. Create_file_log_event is different: it's 'db' 01447 (which is inherited from Load_log_event) is written to the binlog 01448 and can be re-read. 01449 */ 01450 const char* db; 01451 01452 #ifndef MYSQL_CLIENT 01453 Append_block_log_event(THD* thd, const char* db_arg, char* block_arg, 01454 uint block_len_arg, bool using_trans); 01455 #ifdef HAVE_REPLICATION 01456 int exec_event(struct st_relay_log_info* rli); 01457 void pack_info(Protocol* protocol); 01458 virtual int get_create_or_append() const; 01459 #endif /* HAVE_REPLICATION */ 01460 #else 01461 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01462 #endif 01463 01464 Append_block_log_event(const char* buf, uint event_len, 01465 const Format_description_log_event* description_event); 01466 ~Append_block_log_event() {} 01467 Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;} 01468 int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} 01469 bool is_valid() const { return block != 0; } 01470 #ifndef MYSQL_CLIENT 01471 bool write(IO_CACHE* file); 01472 const char* get_db() { return db; } 01473 #endif 01474 }; 01475 01476 01477 /***************************************************************************** 01478 01479 Delete File Log Event class 01480 01481 ****************************************************************************/ 01482 01483 class Delete_file_log_event: public Log_event 01484 { 01485 public: 01486 uint file_id; 01487 const char* db; /* see comment in Append_block_log_event */ 01488 01489 #ifndef MYSQL_CLIENT 01490 Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); 01491 #ifdef HAVE_REPLICATION 01492 void pack_info(Protocol* protocol); 01493 int exec_event(struct st_relay_log_info* rli); 01494 #endif /* HAVE_REPLICATION */ 01495 #else 01496 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01497 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local); 01498 #endif 01499 01500 Delete_file_log_event(const char* buf, uint event_len, 01501 const Format_description_log_event* description_event); 01502 ~Delete_file_log_event() {} 01503 Log_event_type get_type_code() { return DELETE_FILE_EVENT;} 01504 int get_data_size() { return DELETE_FILE_HEADER_LEN ;} 01505 bool is_valid() const { return file_id != 0; } 01506 #ifndef MYSQL_CLIENT 01507 bool write(IO_CACHE* file); 01508 const char* get_db() { return db; } 01509 #endif 01510 }; 01511 01512 01513 /***************************************************************************** 01514 01515 Execute Load Log Event class 01516 01517 ****************************************************************************/ 01518 01519 class Execute_load_log_event: public Log_event 01520 { 01521 public: 01522 uint file_id; 01523 const char* db; /* see comment in Append_block_log_event */ 01524 01525 #ifndef MYSQL_CLIENT 01526 Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); 01527 #ifdef HAVE_REPLICATION 01528 void pack_info(Protocol* protocol); 01529 int exec_event(struct st_relay_log_info* rli); 01530 #endif /* HAVE_REPLICATION */ 01531 #else 01532 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01533 #endif 01534 01535 Execute_load_log_event(const char* buf, uint event_len, 01536 const Format_description_log_event* description_event); 01537 ~Execute_load_log_event() {} 01538 Log_event_type get_type_code() { return EXEC_LOAD_EVENT;} 01539 int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} 01540 bool is_valid() const { return file_id != 0; } 01541 #ifndef MYSQL_CLIENT 01542 bool write(IO_CACHE* file); 01543 const char* get_db() { return db; } 01544 #endif 01545 }; 01546 01547 01548 /*************************************************************************** 01549 01550 Begin load query Log Event class 01551 01552 Event for the first block of file to be loaded, its only difference from 01553 Append_block event is that this event creates or truncates existing file 01554 before writing data. 01555 01556 ****************************************************************************/ 01557 class Begin_load_query_log_event: public Append_block_log_event 01558 { 01559 public: 01560 #ifndef MYSQL_CLIENT 01561 Begin_load_query_log_event(THD* thd_arg, const char *db_arg, 01562 char* block_arg, uint block_len_arg, 01563 bool using_trans); 01564 #ifdef HAVE_REPLICATION 01565 Begin_load_query_log_event(THD* thd); 01566 int get_create_or_append() const; 01567 #endif /* HAVE_REPLICATION */ 01568 #endif 01569 Begin_load_query_log_event(const char* buf, uint event_len, 01570 const Format_description_log_event* description_event); 01571 ~Begin_load_query_log_event() {} 01572 Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; } 01573 }; 01574 01575 01576 /* 01577 Elements of this enum describe how LOAD DATA handles duplicates. 01578 */ 01579 enum enum_load_dup_handling { LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE, 01580 LOAD_DUP_REPLACE }; 01581 01582 /**************************************************************************** 01583 01584 Execute load query Log Event class 01585 01586 Event responsible for LOAD DATA execution, it similar to Query_log_event 01587 but before executing the query it substitutes original filename in LOAD DATA 01588 query with name of temporary file. 01589 01590 ****************************************************************************/ 01591 class Execute_load_query_log_event: public Query_log_event 01592 { 01593 public: 01594 uint file_id; // file_id of temporary file 01595 uint fn_pos_start; // pointer to the part of the query that should 01596 // be substituted 01597 uint fn_pos_end; // pointer to the end of this part of query 01598 /* 01599 We have to store type of duplicate handling explicitly, because 01600 for LOAD DATA it also depends on LOCAL option. And this part 01601 of query will be rewritten during replication so this information 01602 may be lost... 01603 */ 01604 enum_load_dup_handling dup_handling; 01605 01606 #ifndef MYSQL_CLIENT 01607 Execute_load_query_log_event(THD* thd, const char* query_arg, 01608 ulong query_length, uint fn_pos_start_arg, 01609 uint fn_pos_end_arg, 01610 enum_load_dup_handling dup_handling_arg, 01611 bool using_trans, bool suppress_use); 01612 #ifdef HAVE_REPLICATION 01613 void pack_info(Protocol* protocol); 01614 int exec_event(struct st_relay_log_info* rli); 01615 #endif /* HAVE_REPLICATION */ 01616 #else 01617 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01618 /* Prints the query as LOAD DATA LOCAL and with rewritten filename */ 01619 void print(FILE* file, PRINT_EVENT_INFO* print_event_info, 01620 const char *local_fname); 01621 #endif 01622 Execute_load_query_log_event(const char* buf, uint event_len, 01623 const Format_description_log_event *description_event); 01624 ~Execute_load_query_log_event() {} 01625 01626 Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; } 01627 bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; } 01628 01629 ulong get_post_header_size_for_derived(); 01630 #ifndef MYSQL_CLIENT 01631 bool write_post_header_for_derived(IO_CACHE* file); 01632 #endif 01633 }; 01634 01635 01636 #ifdef MYSQL_CLIENT 01637 class Unknown_log_event: public Log_event 01638 { 01639 public: 01640 /* 01641 Even if this is an unknown event, we still pass description_event to 01642 Log_event's ctor, this way we can extract maximum information from the 01643 event's header (the unique ID for example). 01644 */ 01645 Unknown_log_event(const char* buf, const Format_description_log_event* description_event): 01646 Log_event(buf, description_event) 01647 {} 01648 ~Unknown_log_event() {} 01649 void print(FILE* file, PRINT_EVENT_INFO* print_event_info); 01650 Log_event_type get_type_code() { return UNKNOWN_EVENT;} 01651 bool is_valid() const { return 1; } 01652 }; 01653 #endif 01654 char *str_to_hex(char *to, const char *from, uint len); 01655 01656 #ifdef HAVE_ROW_BASED_REPLICATION 01657 01658 /***************************************************************************** 01659 01660 Table map log event class 01661 01662 Create a mapping from a (database name, table name) couple to a table 01663 identifier (an integer number). 01664 01665 ****************************************************************************/ 01666 class Table_map_log_event : public Log_event 01667 { 01668 public: 01669 /* Constants */ 01670 enum 01671 { 01672 TYPE_CODE = TABLE_MAP_EVENT 01673 }; 01674 01675 enum enum_error 01676 { 01677 ERR_OPEN_FAILURE = -1, /* Failure to open table */ 01678 ERR_OK = 0, /* No error */ 01679 ERR_TABLE_LIMIT_EXCEEDED = 1, /* No more room for tables */ 01680 ERR_OUT_OF_MEM = 2, /* Out of memory */ 01681 ERR_BAD_TABLE_DEF = 3, /* Table definition does not match */ 01682 ERR_RBR_TO_SBR = 4 /* daisy-chanining RBR to SBR not allowed */ 01683 }; 01684 01685 enum enum_flag 01686 { 01687 /* 01688 Nothing here right now, but the flags support is there in 01689 preparation for changes that are coming. Need to add a 01690 constant to make it compile under HP-UX: aCC does not like 01691 empty enumerations. 01692 */ 01693 ENUM_FLAG_COUNT 01694 }; 01695 01696 typedef uint16 flag_set; 01697 01698 /* Special constants representing sets of flags */ 01699 enum 01700 { 01701 TM_NO_FLAGS = 0U 01702 }; 01703 01704 void set_flags(flag_set flag) { m_flags |= flag; } 01705 void clear_flags(flag_set flag) { m_flags &= ~flag; } 01706 flag_set get_flags(flag_set flag) const { return m_flags & flag; } 01707 01708 #ifndef MYSQL_CLIENT 01709 Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, 01710 bool is_transactional, uint16 flags); 01711 #endif 01712 #ifdef HAVE_REPLICATION 01713 Table_map_log_event(const char *buf, uint event_len, 01714 const Format_description_log_event *description_event); 01715 #endif 01716 01717 ~Table_map_log_event(); 01718 01719 virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; } 01720 virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ } 01721 01722 virtual int get_data_size() { return m_data_size; } 01723 #ifndef MYSQL_CLIENT 01724 virtual bool write_data_header(IO_CACHE *file); 01725 virtual bool write_data_body(IO_CACHE *file); 01726 virtual const char *get_db() { return m_dbnam; } 01727 #endif 01728 01729 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 01730 virtual int exec_event(struct st_relay_log_info *rli); 01731 virtual void pack_info(Protocol *protocol); 01732 #endif 01733 01734 #ifdef MYSQL_CLIENT 01735 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 01736 #endif 01737 01738 01739 private: 01740 #ifndef MYSQL_CLIENT 01741 TABLE *m_table; 01742 #endif 01743 char const *m_dbnam; 01744 my_size_t m_dblen; 01745 char const *m_tblnam; 01746 my_size_t m_tbllen; 01747 ulong m_colcnt; 01748 unsigned char *m_coltype; 01749 01750 gptr m_memory; 01751 ulong m_table_id; 01752 flag_set m_flags; 01753 01754 my_size_t m_data_size; 01755 }; 01756 01757 01758 /***************************************************************************** 01759 01760 Row level log event class. 01761 01762 Common base class for all row-level log events. 01763 01764 RESPONSIBILITIES 01765 01766 Encode the common parts of all events containing rows, which are: 01767 - Write data header and data body to an IO_CACHE. 01768 - Provide an interface for adding an individual row to the event. 01769 01770 ****************************************************************************/ 01771 01772 01773 class Rows_log_event : public Log_event 01774 { 01775 public: 01776 /* 01777 These definitions allow you to combine the flags into an 01778 appropriate flag set using the normal bitwise operators. The 01779 implicit conversion from an enum-constant to an integer is 01780 accepted by the compiler, which is then used to set the real set 01781 of flags. 01782 */ 01783 01784 enum enum_flag 01785 { 01786 /* Last event of a statement */ 01787 STMT_END_F = (1U << 0), 01788 01789 /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */ 01790 NO_FOREIGN_KEY_CHECKS_F = (1U << 1), 01791 01792 /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */ 01793 RELAXED_UNIQUE_CHECKS_F = (1U << 2) 01794 }; 01795 01796 typedef uint16 flag_set; 01797 01798 /* Special constants representing sets of flags */ 01799 enum 01800 { 01801 RLE_NO_FLAGS = 0U 01802 }; 01803 01804 virtual ~Rows_log_event(); 01805 01806 void set_flags(flag_set flags) { m_flags |= flags; } 01807 void clear_flags(flag_set flags) { m_flags &= ~flags; } 01808 flag_set get_flags(flag_set flags) const { return m_flags & flags; } 01809 01810 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 01811 virtual int exec_event(struct st_relay_log_info *rli); 01812 virtual void pack_info(Protocol *protocol); 01813 #endif 01814 01815 #ifdef MYSQL_CLIENT 01816 /* not for direct call, each derived has its own ::print() */ 01817 virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0; 01818 #endif 01819 01820 #ifndef MYSQL_CLIENT 01821 int add_row_data(byte *data, my_size_t length) 01822 { 01823 return do_add_row_data(data,length); 01824 } 01825 #endif 01826 01827 /* Member functions to implement superclass interface */ 01828 virtual int get_data_size() 01829 { 01830 DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", 01831 return 6 + 1 + no_bytes_in_map(&m_cols) + 01832 (m_rows_cur - m_rows_buf);); 01833 return ROWS_HEADER_LEN + 1 + no_bytes_in_map(&m_cols) + 01834 (m_rows_cur - m_rows_buf); 01835 } 01836 01837 MY_BITMAP const *get_cols() const { return &m_cols; } 01838 my_size_t get_width() const { return m_width; } 01839 ulong get_table_id() const { return m_table_id; } 01840 01841 #ifndef MYSQL_CLIENT 01842 virtual bool write_data_header(IO_CACHE *file); 01843 virtual bool write_data_body(IO_CACHE *file); 01844 virtual const char *get_db() { return m_table->s->db.str; } 01845 #endif 01846 virtual bool is_valid() const 01847 { 01848 /* that's how we check malloc() succeeded */ 01849 return m_rows_buf && m_cols.bitmap; 01850 } 01851 01852 uint m_row_count; /* The number of rows added to the event */ 01853 01854 protected: 01855 /* 01856 The constructors are protected since you're supposed to inherit 01857 this class, not create instances of this class. 01858 */ 01859 #ifndef MYSQL_CLIENT 01860 Rows_log_event(THD*, TABLE*, ulong table_id, 01861 MY_BITMAP const *cols, bool is_transactional); 01862 #endif 01863 Rows_log_event(const char *row_data, uint event_len, 01864 Log_event_type event_type, 01865 const Format_description_log_event *description_event); 01866 01867 #ifndef MYSQL_CLIENT 01868 virtual int do_add_row_data(byte *data, my_size_t length); 01869 #endif 01870 01871 #ifndef MYSQL_CLIENT 01872 TABLE *m_table; /* The table the rows belong to */ 01873 #endif 01874 ulong m_table_id; /* Table ID */ 01875 MY_BITMAP m_cols; /* Bitmap denoting columns available */ 01876 ulong m_width; /* The width of the columns bitmap */ 01877 01878 /* Bit buffer in the same memory as the class */ 01879 uint32 m_bitbuf[128/(sizeof(uint32)*8)]; 01880 01881 byte *m_rows_buf; /* The rows in packed format */ 01882 byte *m_rows_cur; /* One-after the end of the data */ 01883 byte *m_rows_end; /* One-after the end of the allocated space */ 01884 01885 flag_set m_flags; /* Flags for row-level events */ 01886 01887 private: 01888 01889 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 01890 /* 01891 Primitive to prepare for a sequence of row executions. 01892 01893 DESCRIPTION 01894 01895 Before doing a sequence of do_prepare_row() and do_exec_row() 01896 calls, this member function should be called to prepare for the 01897 entire sequence. Typically, this member function will allocate 01898 space for any buffers that are needed for the two member 01899 functions mentioned above. 01900 01901 RETURN VALUE 01902 01903 The member function will return 0 if all went OK, or a non-zero 01904 error code otherwise. 01905 */ 01906 virtual int do_before_row_operations(TABLE *table) = 0; 01907 01908 /* 01909 Primitive to clean up after a sequence of row executions. 01910 01911 DESCRIPTION 01912 01913 After doing a sequence of do_prepare_row() and do_exec_row(), 01914 this member function should be called to clean up and release 01915 any allocated buffers. 01916 */ 01917 virtual int do_after_row_operations(TABLE *table, int error) = 0; 01918 01919 /* 01920 Primitive to prepare for handling one row in a row-level event. 01921 01922 DESCRIPTION 01923 01924 The member function prepares for execution of operations needed for one 01925 row in a row-level event by reading up data from the buffer containing 01926 the row. No specific interpretation of the data is normally done here, 01927 since SQL thread specific data is not available: that data is made 01928 available for the do_exec function. 01929 01930 RETURN VALUE 01931 A pointer to the start of the next row, or NULL if the preparation 01932 failed. Currently, preparation cannot fail, but don't rely on this 01933 behavior. 01934 */ 01935 virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start) = 0; 01936 01937 /* 01938 Primitive to do the actual execution necessary for a row. 01939 01940 DESCRIPTION 01941 The member function will do the actual execution needed to handle a row. 01942 01943 RETURN VALUE 01944 0 if execution succeeded, 1 if execution failed. 01945 01946 */ 01947 virtual int do_exec_row(TABLE *table) = 0; 01948 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ 01949 }; 01950 01951 01952 /***************************************************************************** 01953 01954 Write row log event class 01955 01956 Log row insertions and updates. The event contain several 01957 insert/update rows for a table. Note that each event contains only 01958 rows for one table. 01959 01960 ****************************************************************************/ 01961 class Write_rows_log_event : public Rows_log_event 01962 { 01963 public: 01964 enum 01965 { 01966 /* Support interface to THD::binlog_prepare_pending_rows_event */ 01967 TYPE_CODE = WRITE_ROWS_EVENT 01968 }; 01969 01970 #if !defined(MYSQL_CLIENT) 01971 Write_rows_log_event(THD*, TABLE*, ulong table_id, 01972 MY_BITMAP const *cols, bool is_transactional); 01973 #endif 01974 #ifdef HAVE_REPLICATION 01975 Write_rows_log_event(const char *buf, uint event_len, 01976 const Format_description_log_event *description_event); 01977 #endif 01978 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION) 01979 static bool binlog_row_logging_function(THD *thd, TABLE *table, 01980 bool is_transactional, 01981 MY_BITMAP *cols, 01982 uint fields, 01983 const byte *before_record 01984 __attribute__((unused)), 01985 const byte *after_record) 01986 { 01987 return thd->binlog_write_row(table, is_transactional, 01988 cols, fields, after_record); 01989 } 01990 #endif 01991 01992 private: 01993 virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } 01994 01995 #ifdef MYSQL_CLIENT 01996 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 01997 #endif 01998 01999 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 02000 gptr m_memory; 02001 byte *m_after_image; 02002 02003 virtual int do_before_row_operations(TABLE *table); 02004 virtual int do_after_row_operations(TABLE *table, int error); 02005 virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); 02006 virtual int do_exec_row(TABLE *table); 02007 #endif 02008 }; 02009 02010 02011 /***************************************************************************** 02012 02013 Update rows log event class 02014 02015 Log row updates with a before image. The event contain several 02016 update rows for a table. Note that each event contains only rows for 02017 one table. 02018 02019 Also note that the row data consists of pairs of row data: one row 02020 for the old data and one row for the new data. 02021 02022 ****************************************************************************/ 02023 class Update_rows_log_event : public Rows_log_event 02024 { 02025 public: 02026 enum 02027 { 02028 /* Support interface to THD::binlog_prepare_pending_rows_event */ 02029 TYPE_CODE = UPDATE_ROWS_EVENT 02030 }; 02031 02032 #ifndef MYSQL_CLIENT 02033 Update_rows_log_event(THD*, TABLE*, ulong table_id, 02034 MY_BITMAP const *cols, bool is_transactional); 02035 #endif 02036 02037 #ifdef HAVE_REPLICATION 02038 Update_rows_log_event(const char *buf, uint event_len, 02039 const Format_description_log_event *description_event); 02040 #endif 02041 02042 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION) 02043 static bool binlog_row_logging_function(THD *thd, TABLE *table, 02044 bool is_transactional, 02045 MY_BITMAP *cols, 02046 uint fields, 02047 const byte *before_record, 02048 const byte *after_record) 02049 { 02050 return thd->binlog_update_row(table, is_transactional, 02051 cols, fields, before_record, after_record); 02052 } 02053 #endif 02054 02055 private: 02056 virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } 02057 02058 #ifdef MYSQL_CLIENT 02059 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 02060 #endif 02061 02062 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 02063 gptr m_memory; 02064 byte *m_key; 02065 byte *m_after_image; 02066 02067 virtual int do_before_row_operations(TABLE *table); 02068 virtual int do_after_row_operations(TABLE *table, int error); 02069 virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); 02070 virtual int do_exec_row(TABLE *table); 02071 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ 02072 }; 02073 02074 /***************************************************************************** 02075 02076 Delete rows log event class. 02077 02078 Log row deletions. The event contain several delete rows for a 02079 table. Note that each event contains only rows for one table. 02080 02081 RESPONSIBILITIES 02082 02083 - Act as a container for rows that has been deleted on the master 02084 and should be deleted on the slave. 02085 02086 COLLABORATION 02087 02088 Row_writer 02089 Create the event and add rows to the event. 02090 Row_reader 02091 Extract the rows from the event. 02092 02093 ****************************************************************************/ 02094 class Delete_rows_log_event : public Rows_log_event 02095 { 02096 public: 02097 enum 02098 { 02099 /* Support interface to THD::binlog_prepare_pending_rows_event */ 02100 TYPE_CODE = DELETE_ROWS_EVENT 02101 }; 02102 02103 #ifndef MYSQL_CLIENT 02104 Delete_rows_log_event(THD*, TABLE*, ulong, 02105 MY_BITMAP const *cols, bool is_transactional); 02106 #endif 02107 #ifdef HAVE_REPLICATION 02108 Delete_rows_log_event(const char *buf, uint event_len, 02109 const Format_description_log_event *description_event); 02110 #endif 02111 #if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION) 02112 static bool binlog_row_logging_function(THD *thd, TABLE *table, 02113 bool is_transactional, 02114 MY_BITMAP *cols, 02115 uint fields, 02116 const byte *before_record, 02117 const byte *after_record 02118 __attribute__((unused))) 02119 { 02120 return thd->binlog_delete_row(table, is_transactional, 02121 cols, fields, before_record); 02122 } 02123 #endif 02124 02125 private: 02126 virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; } 02127 02128 #ifdef MYSQL_CLIENT 02129 void print(FILE *file, PRINT_EVENT_INFO *print_event_info); 02130 #endif 02131 02132 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) 02133 gptr m_memory; 02134 byte *m_key; 02135 byte *m_after_image; 02136 02137 virtual int do_before_row_operations(TABLE *table); 02138 virtual int do_after_row_operations(TABLE *table, int error); 02139 virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); 02140 virtual int do_exec_row(TABLE *table); 02141 #endif 02142 }; 02143 02144 #endif /* HAVE_ROW_BASED_REPLICATION */ 02145 02146 #endif /* _log_event_h */
1.4.7

